結果
問題 | No.1775 Love Triangle 2 |
ユーザー |
|
提出日時 | 2021-12-05 05:24:30 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 61,639 bytes |
コンパイル時間 | 3,339 ms |
コンパイル使用メモリ | 239,032 KB |
最終ジャッジ日時 | 2025-01-26 03:59:42 |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 24 WA * 66 |
ソースコード
#include <bits/stdc++.h>#pragma region Headerusing i32 = int;using u32 = unsigned int;using i64 = long long;using u64 = unsigned long long;using i128 = __int128_t;using u128 = __uint128_t;using f64 = double;using f80 = long double;using f128 = __float128;constexpr i32 operator"" _i32(u64 v){return v;}constexpr i32 operator"" _u32(u64 v){return v;}constexpr i64 operator"" _i64(u64 v){return v;}constexpr u64 operator"" _u64(u64 v){return v;}constexpr f64 operator"" _f64(f80 v){return v;}constexpr f80 operator"" _f80(f80 v){return v;}using Istream = std::istream;using Ostream = std::ostream;using Str = std::string;template<typename T>using Lt = std::less<T>;template<typename T>using Gt = std::greater<T>;template<typename T>using IList = std::initializer_list<T>;template<int n>using BSet = std::bitset<n>;template<typename T1, typename T2>using Pair = std::pair<T1, T2>;template<typename... Ts>using Tup = std::tuple<Ts...>;template<typename T, int N>using Arr = std::array<T, N>;template<typename... Ts>using Deq = std::deque<Ts...>;template<typename... Ts>using Set = std::set<Ts...>;template<typename... Ts>using MSet = std::multiset<Ts...>;template<typename... Ts>using USet = std::unordered_set<Ts...>;template<typename... Ts>using UMSet = std::unordered_multiset<Ts...>;template<typename... Ts>using Map = std::map<Ts...>;template<typename... Ts>using MMap = std::multimap<Ts...>;template<typename... Ts>using UMap = std::unordered_map<Ts...>;template<typename... Ts>using UMMap = std::unordered_multimap<Ts...>;template<typename... Ts>using Vec = std::vector<Ts...>;template<typename... Ts>using Stack = std::stack<Ts...>;template<typename... Ts>using Queue = std::queue<Ts...>;template<typename T>using MaxHeap = std::priority_queue<T>;template<typename T>using MinHeap = std::priority_queue<T, Vec<T>, Gt<T>>;using NSec = std::chrono::nanoseconds;using USec = std::chrono::microseconds;using MSec = std::chrono::milliseconds;using Sec = std::chrono::seconds;template<typename T>constexpr T LIMMIN = std::numeric_limits<T>::min();template<typename T>constexpr T LIMMAX = std::numeric_limits<T>::max();template<typename T>constexpr T INF = (LIMMAX<T> - 1) / 2;template<typename T>constexpr T PI = T{3.141592653589793238462643383279502884};template<typename T = u64>constexpr T TEN(const int n){return n == 0 ? T{1} : TEN<T>(n - 1) * T{10};}Ostream& operator<<(Ostream& os, i128 v){bool minus = false;if (v < 0) { minus = true, v = -v; }Str ans;if (v == 0) { ans = "0"; }while (v) {ans.push_back('0' + v % 10), v /= 10;}std::reverse(ans.begin(), ans.end());return os << (minus ? "-" : "") << ans;}Ostream& operator<<(Ostream& os, u128 v){Str ans;if (v == 0) { ans = "0"; }while (v) {ans.push_back('0' + v % 10), v /= 10;}std::reverse(ans.begin(), ans.end());return os << ans;}template<typename T>bool chmin(T& a, const T& b){if (a > b) {a = b;return true;} else {return false;}}template<typename T>bool chmax(T& a, const T& b){if (a < b) {a = b;return true;} else {return false;}}template<typename T>constexpr T floorDiv(T x, T y){if (y < T{}) { x = -x, y = -y; }return x >= T{} ? x / y : (x - y + 1) / y;}template<typename T>constexpr T ceilDiv(T x, T y){if (y < T{}) { x = -x, y = -y; }return x >= T{} ? (x + y - 1) / y : x / y;}template<typename T, typename I>constexpr T modPower(T v, I n, T mod){T ans = 1 % mod;for (; n > 0; n >>= 1, (v *= v) %= mod) {if (n % 2 == 1) { (ans *= v) %= mod; }}return ans;}template<typename T, typename I>constexpr T power(T v, I n){T ans = 1;for (; n > 0; n >>= 1, v *= v) {if (n % 2 == 1) { ans *= v; }}return ans;}template<typename T, typename I>constexpr T power(T v, I n, const T& e){T ans = e;for (; n > 0; n >>= 1, v *= v) {if (n % 2 == 1) { ans *= v; }}return ans;}template<typename T>Vec<T> operator+=(Vec<T>& vs1, const Vec<T>& vs2){vs1.insert(vs1.end(), vs2.begin(), vs2.end());return vs1;}template<typename T>Vec<T> operator+(const Vec<T>& vs1, const Vec<T>& vs2){auto vs = vs1;vs += vs2;return vs;}template<typename Vs, typename V>void fillAll(Vs& arr, const V& v){if constexpr (std::is_convertible<V, Vs>::value) {arr = v;} else {for (auto& subarr : arr) {fillAll(subarr, v);}}}template<typename Vs>void sortAll(Vs& vs){std::sort(std::begin(vs), std::end(vs));}template<typename Vs, typename C>void sortAll(Vs& vs, C comp){std::sort(std::begin(vs), std::end(vs), comp);}template<typename Vs>void reverseAll(Vs& vs){std::reverse(std::begin(vs), std::end(vs));}template<typename V, typename Vs>V sumAll(const Vs& vs){if constexpr (std::is_convertible<Vs, V>::value) {return static_cast<V>(vs);} else {V ans = 0;for (const auto& v : vs) {ans += sumAll<V>(v);}return ans;}}template<typename Vs>int minInd(const Vs& vs){return std::min_element(std::begin(vs), std::end(vs)) - std::begin(vs);}template<typename Vs>int maxInd(const Vs& vs){return std::max_element(std::begin(vs), std::end(vs)) - std::begin(vs);}template<typename Vs, typename V>int lbInd(const Vs& vs, const V& v){return std::lower_bound(std::begin(vs), std::end(vs), v) - std::begin(vs);}template<typename Vs, typename V>int ubInd(const Vs& vs, const V& v){return std::upper_bound(std::begin(vs), std::end(vs), v) - std::begin(vs);}template<typename T, typename F>Vec<T> genVec(int n, F gen){Vec<T> ans;std::generate_n(std::back_insert_iterator(ans), n, gen);return ans;}Vec<int> iotaVec(int n, int offset = 0){Vec<int> ans(n);std::iota(ans.begin(), ans.end(), offset);return ans;}constexpr int popcount(const u64 v){return v ? __builtin_popcountll(v) : 0;}constexpr int log2p1(const u64 v){return v ? 64 - __builtin_clzll(v) : 0;}constexpr int lsbp1(const u64 v){return __builtin_ffsll(v);}constexpr int clog(const u64 v){return v ? log2p1(v - 1) : 0;}constexpr u64 ceil2(const u64 v){const int l = clog(v);return (l == 64) ? 0_u64 : (1_u64 << l);}constexpr u64 floor2(const u64 v){return v ? (1_u64 << (log2p1(v) - 1)) : 0_u64;}constexpr bool ispow2(const u64 v){return (v > 0) and ((v & (v - 1)) == 0);}constexpr bool btest(const u64 mask, const int ind){return (mask >> ind) & 1_u64;}template<typename F>struct Fix : F{Fix(F&& f) : F{std::forward<F>(f)} {}template<typename... Args>auto operator()(Args&&... args) const{return F::operator()(*this, std::forward<Args>(args)...);}};class irange{private:struct itr{itr(i64 start = 0, i64 step = 1) : m_cnt{start}, m_step{step} {}bool operator!=(const itr& it) const{return m_cnt != it.m_cnt;}int operator*(){return m_cnt;}itr& operator++(){m_cnt += m_step;return *this;}i64 m_cnt, m_step;};i64 m_start, m_end, m_step;public:irange(i64 start, i64 end, i64 step = 1){assert(step != 0);const i64 d = std::abs(step);const i64 l = (step > 0 ? start : end);const i64 r = (step > 0 ? end : start);int n = (r - l) / d + ((r - l) % d ? 1 : 0);if (l >= r) { n = 0; }m_start = start;m_end = start + step * n;m_step = step;}itr begin() const{return itr{m_start, m_step};}itr end() const{return itr{m_end, m_step};}};irange rep(int end){return irange(0, end, 1);}irange per(int rend){return irange(rend - 1, -1, -1);}#pragma COMMENT("[REFS] Xoshiro: https://prng.di.unimi.it")namespace xoshiro_impl {u64 x;u64 next(){uint64_t z = (x += 0x9e3779b97f4a7c15);z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;z = (z ^ (z >> 27)) * 0x94d049bb133111eb;return z ^ (z >> 31);}}class Xoshiro32{public:using result_type = u32;using T = result_type;Xoshiro32(T seed = 0){xoshiro_impl::x = seed;s[0] = xoshiro_impl::next();s[1] = xoshiro_impl::next();s[2] = xoshiro_impl::next();s[3] = xoshiro_impl::next();}static constexpr T min(){return LIMMIN<T>;}static constexpr T max(){return LIMMAX<T>;}T operator()(){return next();}private:static constexpr T rotl(const T x, int k){return (x << k) | (x >> (32 - k));}T next(){const T ans = rotl(s[1] * 5, 7) * 9;const T t = s[1] << 9;s[2] ^= s[0];s[3] ^= s[1];s[1] ^= s[2];s[0] ^= s[3];s[2] ^= t;s[3] = rotl(s[3], 11);return ans;}T s[4];};class Xoshiro64{public:using result_type = u64;using T = result_type;Xoshiro64(T seed = 0){xoshiro_impl::x = seed;s[0] = xoshiro_impl::next();s[1] = xoshiro_impl::next();s[2] = xoshiro_impl::next();s[3] = xoshiro_impl::next();}static constexpr T min(){return LIMMIN<T>;}static constexpr T max(){return LIMMAX<T>;}T operator()(){return next();}private:static constexpr T rotl(const T x, int k){return (x << k) | (x >> (64 - k));}T next(){const T ans = rotl(s[1] * 5, 7) * 9;const T t = s[1] << 17;s[2] ^= s[0];s[3] ^= s[1];s[1] ^= s[2];s[0] ^= s[3];s[2] ^= t;s[3] = rotl(s[3], 45);return ans;}T s[4];};template<typename Rng>class RNG{public:using result_type = typename Rng::result_type;using T = result_type;static constexpr T min(){return Rng::min();}static constexpr T max(){return Rng::max();}RNG() : RNG(std::random_device{}()) {}RNG(T seed) : m_rng(seed) {}T operator()(){return m_rng();}template<typename T>T val(T min, T max){return std::uniform_int_distribution<T>(min, max)(m_rng);}template<typename T>Pair<T, T> pair(T min, T max){return std::minmax({val<T>(min, max), val<T>(min, max)});}template<typename T>Vec<T> vec(int n, T min, T max){return genVec<T>(n, [&]() { return val<T>(min, max); });}template<typename T>Vec<Vec<T>> vvec(int n, int m, T min, T max){return genVec<Vec<T>>(n, [&]() { return vec(m, min, max); });}private:Rng m_rng;};RNG<std::mt19937> rng;RNG<std::mt19937_64> rng64;RNG<Xoshiro32> rng_xo;RNG<Xoshiro64> rng_xo64;class Scanner{public:Scanner(Istream& is = std::cin) : m_is{is}{m_is.tie(nullptr)->sync_with_stdio(false);}template<typename T>T val(){T v;return m_is >> v, v;}template<typename T>T val(T offset){return val<T>() - offset;}template<typename T>Vec<T> vec(int n){return genVec<T>(n, [&]() { return val<T>(); });}template<typename T>Vec<T> vec(int n, T offset){return genVec<T>(n, [&]() { return val<T>(offset); });}template<typename T>Vec<Vec<T>> vvec(int n, int m){return genVec<Vec<T>>(n, [&]() { return vec<T>(m); });}template<typename T>Vec<Vec<T>> vvec(int n, int m, const T offset){return genVec<Vec<T>>(n, [&]() { return vec<T>(m, offset); });}template<typename... Args>auto tup(){return Tup<Args...>{val<Args>()...};}template<typename... Args>auto tup(const Args&... offsets){return Tup<Args...>{val<Args>(offsets)...};}private:Istream& m_is;};Scanner in;class Printer{public:Printer(Ostream& os = std::cout) : m_os{os}{m_os << std::fixed << std::setprecision(15);}template<typename... Args>int operator()(const Args&... args){dump(args...);return 0;}template<typename... Args>int ln(const Args&... args){dump(args...), m_os << '\n';return 0;}template<typename... Args>int el(const Args&... args){dump(args...), m_os << std::endl;return 0;}private:template<typename T>void dump(const T& v){m_os << v;}template<typename T>void dump(const Vec<T>& vs){for (const int i : rep(vs.size())) {m_os << (i ? " " : ""), dump(vs[i]);}}template<typename T>void dump(const Vec<Vec<T>>& vss){for (const int i : rep(vss.size())) {m_os << (i ? "\n" : ""), dump(vss[i]);}}template<typename T, typename... Ts>int dump(const T& v, const Ts&... args){dump(v), m_os << ' ', dump(args...);return 0;}Ostream& m_os;};Printer out;template<typename T, int n, int i = 0>auto ndVec(int const (&szs)[n], const T x = T{}){if constexpr (i == n) {return x;} else {return std::vector(szs[i], ndVec<T, n, i + 1>(szs, x));}}template<typename T, typename F>T binSearch(T ng, T ok, F check){while (std::abs(ok - ng) > 1) {const T mid = (ok + ng) / 2;(check(mid) ? ok : ng) = mid;}return ok;}template<u32 mod_, u32 root_, u32 max2p_>class modint{template<typename U = u32&>static U modRef(){static u32 s_mod = 0;return s_mod;}template<typename U = u32&>static U rootRef(){static u32 s_root = 0;return s_root;}template<typename U = u32&>static U max2pRef(){static u32 s_max2p = 0;return s_max2p;}public:template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> mod(){return mod_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> mod(){return modRef();}template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> root(){return root_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> root(){return rootRef();}template<typename U = const u32>static constexpr std::enable_if_t<mod_ != 0, U> max2p(){return max2p_;}template<typename U = const u32>static std::enable_if_t<mod_ == 0, U> max2p(){return max2pRef();}template<typename U = u32>static void setMod(std::enable_if_t<mod_ == 0, U> m){modRef() = m;}template<typename U = u32>static void setRoot(std::enable_if_t<mod_ == 0, U> r){rootRef() = r;}template<typename U = u32>static void setMax2p(std::enable_if_t<mod_ == 0, U> m){max2pRef() = m;}constexpr modint() : m_val{0} {}constexpr modint(i64 v) : m_val{normll(v)} {}constexpr void setRaw(u32 v){m_val = v;}constexpr modint operator-() const{return modint{0} - (*this);}constexpr modint& operator+=(const modint& m){m_val = norm(m_val + m.val());return *this;}constexpr modint& operator-=(const modint& m){m_val = norm(m_val + mod() - m.val());return *this;}constexpr modint& operator*=(const modint& m){m_val = normll((i64)m_val * (i64)m.val() % (i64)mod());return *this;}constexpr modint& operator/=(const modint& m){return *this *= m.inv();}constexpr modint operator+(const modint& m) const{auto v = *this;return v += m;}constexpr modint operator-(const modint& m) const{auto v = *this;return v -= m;}constexpr modint operator*(const modint& m) const{auto v = *this;return v *= m;}constexpr modint operator/(const modint& m) const{auto v = *this;return v /= m;}constexpr bool operator==(const modint& m) const{return m_val == m.val();}constexpr bool operator!=(const modint& m) const{return not(*this == m);}friend Istream& operator>>(Istream& is, modint& m){i64 v;return is >> v, m = v, is;}friend Ostream& operator<<(Ostream& os, const modint& m){return os << m.val();}constexpr u32 val() const{return m_val;}template<typename I>constexpr modint pow(I n) const{return power(*this, n);}constexpr modint inv() const{return pow(mod() - 2);}static modint sinv(u32 n){static Vec<modint> is{1, 1};for (u32 i = (u32)is.size(); i <= n; i++) {is.push_back(-is[mod() % i] * (mod() / i));}return is[n];}static modint fact(u32 n){static Vec<modint> fs{1, 1};for (u32 i = (u32)fs.size(); i <= n; i++) {fs.push_back(fs.back() * i);}return fs[n];}static modint ifact(u32 n){static Vec<modint> ifs{1, 1};for (u32 i = (u32)ifs.size(); i <= n; i++) {ifs.push_back(ifs.back() * sinv(i));}return ifs[n];}static modint comb(int n, int k){return k > n or k < 0 ? modint{0} : fact(n) * ifact(n - k) * ifact(k);}private:static constexpr u32 norm(u32 x){return x < mod() ? x : x - mod();}static constexpr u32 normll(i64 x){return norm(u32(x % (i64)mod() + (i64)mod()));}u32 m_val;};using modint_1000000007 = modint<1000000007, 5, 1>;using modint_998244353 = modint<998244353, 3, 23>;template<int id>using modint_dynamic = modint<0, 0, id>;template<typename T = int>class Graph{struct Edge{Edge() = default;Edge(int i, int t, T c) : id{i}, to{t}, cost{c} {}int id;int to;T cost;operator int() const{return to;}};public:Graph(int n) : m_v{n}, m_edges(n) {}void addEdge(int u, int v, bool bi = false){assert(0 <= u and u < m_v);assert(0 <= v and v < m_v);m_edges[u].emplace_back(m_e, v, 1);if (bi) { m_edges[v].emplace_back(m_e, u, 1); }m_e++;}void addEdge(int u, int v, const T& c, bool bi = false){assert(0 <= u and u < m_v);assert(0 <= v and v < m_v);m_edges[u].emplace_back(m_e, v, c);if (bi) { m_edges[v].emplace_back(m_e, u, c); }m_e++;}const Vec<Edge>& operator[](const int u) const{assert(0 <= u and u < m_v);return m_edges[u];}Vec<Edge>& operator[](const int u){assert(0 <= u and u < m_v);return m_edges[u];}int v() const{return m_v;}int e() const{return m_e;}friend Ostream& operator<<(Ostream& os, const Graph& g){for (int u : rep(g.v())) {for (const auto& [id, v, c] : g[u]) {os << "[" << id << "]: ";os << u << "->" << v << "(" << c << ")\n";}}return os;}Vec<T> sizes(int root = 0) const{const int N = v();assert(0 <= root and root < N);Vec<T> ss(N, 1);Fix([&](auto dfs, int u, int p) -> void {for (const auto& [id, v, c] : m_edges[u]) {static_cast<void>(id);if (v == p) { continue; }dfs(v, u);ss[u] += ss[v];}})(root, -1);return ss;}Vec<T> depths(int root = 0) const{const int N = v();assert(0 <= root and root < N);Vec<T> ds(N, 0);Fix([&](auto dfs, int u, int p) -> void {for (const auto& [id, v, c] : m_edges[u]) {static_cast<void>(id);if (v == p) { continue; }ds[v] = ds[u] + c;dfs(v, u);}})(root, -1);return ds;}Vec<int> parents(int root = 0) const{const int N = v();assert(0 <= root and root < N);Vec<int> ps(N, -1);Fix([&](auto dfs, int u, int p) -> void {for (const auto& [id, v, c] : m_edges[u]) {static_cast<void>(id);if (v == p) { continue; }ps[v] = u;dfs(v, u);}})(root, -1);return ps;}private:int m_v;int m_e = 0;Vec<Vec<Edge>> m_edges;};#pragma endregiontemplate<class Digraph, typename V = int, typename C = V>class NetworkSimplex{public:using Node = int;using Arc = int;static const int INVALID = -1;typedef VValue;typedef C Cost;public:enum ProblemType { INFEASIBLE, OPTIMAL, UNBOUNDED };enum SupplyType {GEQ,LEQ};enum PivotRule {FIRST_ELIGIBLE,BEST_ELIGIBLE,BLOCK_SEARCH,CANDIDATE_LIST,ALTERING_LIST};private:using IntVector = std::vector<int>;using ValueVector = std::vector<Value>;using CostVector = std::vector<Cost>;using CharVector = std::vector<signed char>;enum ArcState { STATE_UPPER = -1, STATE_TREE = 0, STATE_LOWER = 1 };enum ArcDirection { DIR_DOWN = -1, DIR_UP = 1 };private:const Digraph& _graph;int _node_num;int _arc_num;int _all_arc_num;int _search_arc_num;bool _has_lower;SupplyType _stype;Value _sum_supply;IntVector _source;IntVector _target;ValueVector _lower;ValueVector _upper;ValueVector _cap;CostVector _cost;ValueVector _supply;ValueVector _flow;CostVector _pi;IntVector _parent;IntVector _pred;IntVector _thread;IntVector _rev_thread;IntVector _succ_num;IntVector _last_succ;CharVector _pred_dir;CharVector _state;IntVector _dirty_revs;int _root;int in_arc, join, u_in, v_in, u_out, v_out;Value delta;const Value MAX;public:const Value INF;private:class FirstEligiblePivotRule{private:const IntVector& _source;const IntVector& _target;const CostVector& _cost;const CharVector& _state;const CostVector& _pi;int& _in_arc;int _search_arc_num;int _next_arc;public:FirstEligiblePivotRule(NetworkSimplex& ns): _source(ns._source),_target(ns._target),_cost(ns._cost),_state(ns._state),_pi(ns._pi),_in_arc(ns.in_arc),_search_arc_num(ns._search_arc_num),_next_arc(0){}bool findEnteringArc(){Cost c;for (int e = _next_arc; e != _search_arc_num; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_in_arc = e;_next_arc = e + 1;return true;}}for (int e = 0; e != _next_arc; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_in_arc = e;_next_arc = e + 1;return true;}}return false;}};class BestEligiblePivotRule{private:const IntVector& _source;const IntVector& _target;const CostVector& _cost;const CharVector& _state;const CostVector& _pi;int& _in_arc;int _search_arc_num;public:BestEligiblePivotRule(NetworkSimplex& ns): _source(ns._source),_target(ns._target),_cost(ns._cost),_state(ns._state),_pi(ns._pi),_in_arc(ns.in_arc),_search_arc_num(ns._search_arc_num){}bool findEnteringArc(){Cost c, min = 0;for (int e = 0; e != _search_arc_num; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < min) {min = c;_in_arc = e;}}return min < 0;}};class BlockSearchPivotRule{private:const IntVector& _source;const IntVector& _target;const CostVector& _cost;const CharVector& _state;const CostVector& _pi;int& _in_arc;int _search_arc_num;int _block_size;int _next_arc;public:BlockSearchPivotRule(NetworkSimplex& ns): _source(ns._source),_target(ns._target),_cost(ns._cost),_state(ns._state),_pi(ns._pi),_in_arc(ns.in_arc),_search_arc_num(ns._search_arc_num),_next_arc(0){const double BLOCK_SIZE_FACTOR = 1.0;const int MIN_BLOCK_SIZE = 10;_block_size = std::max(int(BLOCK_SIZE_FACTOR * std::sqrt(double(_search_arc_num))),MIN_BLOCK_SIZE);}bool findEnteringArc(){Cost c, min = 0;int cnt = _block_size;int e;for (e = _next_arc; e != _search_arc_num; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < min) {min = c;_in_arc = e;}if (--cnt == 0) {if (min < 0) goto search_end;cnt = _block_size;}}for (e = 0; e != _next_arc; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < min) {min = c;_in_arc = e;}if (--cnt == 0) {if (min < 0) goto search_end;cnt = _block_size;}}if (min >= 0) return false;search_end:_next_arc = e;return true;}};class CandidateListPivotRule{private:const IntVector& _source;const IntVector& _target;const CostVector& _cost;const CharVector& _state;const CostVector& _pi;int& _in_arc;int _search_arc_num;IntVector _candidates;int _list_length, _minor_limit;int _curr_length, _minor_count;int _next_arc;public:CandidateListPivotRule(NetworkSimplex& ns): _source(ns._source),_target(ns._target),_cost(ns._cost),_state(ns._state),_pi(ns._pi),_in_arc(ns.in_arc),_search_arc_num(ns._search_arc_num),_next_arc(0){const double LIST_LENGTH_FACTOR = 0.25;const int MIN_LIST_LENGTH = 10;const double MINOR_LIMIT_FACTOR = 0.1;const int MIN_MINOR_LIMIT = 3;_list_length = std::max(int(LIST_LENGTH_FACTOR * std::sqrt(double(_search_arc_num))),MIN_LIST_LENGTH);_minor_limit = std::max(int(MINOR_LIMIT_FACTOR * _list_length),MIN_MINOR_LIMIT);_curr_length = _minor_count = 0;_candidates.resize(_list_length);}bool findEnteringArc(){Cost min, c;int e;if (_curr_length > 0 && _minor_count < _minor_limit) {++_minor_count;min = 0;for (int i = 0; i < _curr_length; ++i) {e = _candidates[i];c = _state[e]* (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < min) {min = c;_in_arc = e;} else if (c >= 0) {_candidates[i--] = _candidates[--_curr_length];}}if (min < 0) return true;}min = 0;_curr_length = 0;for (e = _next_arc; e != _search_arc_num; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_candidates[_curr_length++] = e;if (c < min) {min = c;_in_arc = e;}if (_curr_length == _list_length) goto search_end;}}for (e = 0; e != _next_arc; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_candidates[_curr_length++] = e;if (c < min) {min = c;_in_arc = e;}if (_curr_length == _list_length) goto search_end;}}if (_curr_length == 0) return false;search_end:_minor_count = 1;_next_arc = e;return true;}};class AlteringListPivotRule{private:const IntVector& _source;const IntVector& _target;const CostVector& _cost;const CharVector& _state;const CostVector& _pi;int& _in_arc;int _search_arc_num;int _block_size, _head_length, _curr_length;int _next_arc;IntVector _candidates;CostVector _cand_cost;class SortFunc{private:const CostVector& _map;public:SortFunc(const CostVector& map) : _map(map) {}bool operator()(int left, int right){return _map[left] < _map[right];}};SortFunc _sort_func;public:AlteringListPivotRule(NetworkSimplex& ns): _source(ns._source),_target(ns._target),_cost(ns._cost),_state(ns._state),_pi(ns._pi),_in_arc(ns.in_arc),_search_arc_num(ns._search_arc_num),_next_arc(0),_cand_cost(ns._search_arc_num),_sort_func(_cand_cost){const double BLOCK_SIZE_FACTOR = 1.0;const int MIN_BLOCK_SIZE = 10;const double HEAD_LENGTH_FACTOR = 0.01;const int MIN_HEAD_LENGTH = 3;_block_size = std::max(int(BLOCK_SIZE_FACTOR * std::sqrt(double(_search_arc_num))),MIN_BLOCK_SIZE);_head_length = std::max(int(HEAD_LENGTH_FACTOR * _block_size),MIN_HEAD_LENGTH);_candidates.resize(_head_length + _block_size);_curr_length = 0;}bool findEnteringArc(){int e;Cost c;for (int i = 0; i != _curr_length; ++i) {e = _candidates[i];c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_cand_cost[e] = c;} else {_candidates[i--] = _candidates[--_curr_length];}}int cnt = _block_size;int limit = _head_length;for (e = _next_arc; e != _search_arc_num; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_cand_cost[e] = c;_candidates[_curr_length++] = e;}if (--cnt == 0) {if (_curr_length > limit) goto search_end;limit = 0;cnt = _block_size;}}for (e = 0; e != _next_arc; ++e) {c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);if (c < 0) {_cand_cost[e] = c;_candidates[_curr_length++] = e;}if (--cnt == 0) {if (_curr_length > limit) goto search_end;limit = 0;cnt = _block_size;}}if (_curr_length == 0) return false;search_end:int new_length = std::min(_head_length + 1, _curr_length);std::partial_sort(_candidates.begin(),_candidates.begin() + new_length,_candidates.begin() + _curr_length,_sort_func);_in_arc = _candidates[0];_next_arc = e;_candidates[0] = _candidates[new_length - 1];_curr_length = new_length - 1;return true;}};public:NetworkSimplex(const Digraph& graph): _graph(graph),MAX(std::numeric_limits<Value>::max()),INF(std::numeric_limits<Value>::has_infinity? std::numeric_limits<Value>::infinity(): MAX){static_assert(std::numeric_limits<Value>::is_signed,"Value must be signed");static_assert(std::numeric_limits<Cost>::is_signed,"Cost must be signed");static_assert(std::numeric_limits<Value>::max() > 0,"max() must be greater than 0");reset();}template<typename LowerMap>NetworkSimplex& lowerMap(const LowerMap& map){_has_lower = true;for (Arc a = 0; a < _arc_num; a++)_lower[a] = map[a];return *this;}template<typename UpperMap>NetworkSimplex& upperMap(const UpperMap& map){for (Arc a = 0; a < _arc_num; a++)_upper[a] = map[a];return *this;}template<typename CostMap>NetworkSimplex& costMap(const CostMap& map){for (Arc a = 0; a < _arc_num; a++)_cost[a] = map[a];return *this;}template<typename SupplyMap>NetworkSimplex& supplyMap(const SupplyMap& map){for (Node n = 0; n < _node_num; n++)_supply[n] = map[n];return *this;}NetworkSimplex& stSupply(const Node& s, const Node& t, Value k){for (int i = 0; i != _node_num; ++i)_supply[i] = 0;_supply[s] = k, _supply[t] = -k;return *this;}NetworkSimplex& supplyType(SupplyType supply_type){_stype = supply_type;return *this;}ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH){if (!init()) return INFEASIBLE;return start(pivot_rule);}NetworkSimplex& resetParams(){for (int i = 0; i != _node_num; ++i) {_supply[i] = 0;}for (int i = 0; i != _arc_num; ++i) {_lower[i] = 0;_upper[i] = INF;_cost[i] = 1;}_has_lower = false;_stype = GEQ;return *this;}NetworkSimplex& reset(){_node_num = _graph.countNodes();_arc_num = _graph.countArcs();int all_node_num = _node_num + 1;int max_arc_num = _arc_num + 2 * _node_num;_source.resize(max_arc_num);_target.resize(max_arc_num);_lower.resize(_arc_num);_upper.resize(_arc_num);_cap.resize(max_arc_num);_cost.resize(max_arc_num);_supply.resize(all_node_num);_flow.resize(max_arc_num);_pi.resize(all_node_num);_parent.resize(all_node_num);_pred.resize(all_node_num);_pred_dir.resize(all_node_num);_thread.resize(all_node_num);_rev_thread.resize(all_node_num);_succ_num.resize(all_node_num);_last_succ.resize(all_node_num);_state.resize(max_arc_num);for (int a = 0; a < _arc_num; ++a) {_source[a] = _graph.source(a);_target[a] = _graph.target(a);}resetParams();return *this;}template<typename Number = Cost>Number totalCost() const{Number c = 0;for (Arc a = 0; a < _arc_num; a++)c += Number(_flow[a]) * Number(_cost[a]);return c;}Value flow(const Arc& a) const{return _flow[a];}template<typename FlowMap>void flowMap(FlowMap& map) const{for (Arc a = 0; a < _arc_num; a++) {map.set(a, _flow[a]);}}ValueVector flowMap() const{return _flow;}Cost potential(const Node& n) const{return _pi[n];}template<typename PotentialMap>void potentialMap(PotentialMap& map) const{for (int n = 0; n < _graph.V; n++) {map.set(n, _pi[n]);}}CostVector potentialMap() const{return _pi;}private:bool init(){if (_node_num == 0) return false;_sum_supply = 0;for (int i = 0; i != _node_num; ++i) {_sum_supply += _supply[i];}if (!((_stype == GEQ && _sum_supply <= 0)|| (_stype == LEQ && _sum_supply >= 0)))return false;if (_has_lower) {for (int i = 0; i != _arc_num; ++i) {Value c = _lower[i];if (c >= 0) {_cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;} else {_cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;}_supply[_source[i]] -= c;_supply[_target[i]] += c;}} else {for (int i = 0; i != _arc_num; ++i) {_cap[i] = _upper[i];}}Cost ART_COST;if (std::numeric_limits<Cost>::is_exact) {ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;} else {ART_COST = 0;for (int i = 0; i != _arc_num; ++i) {if (_cost[i] > ART_COST) ART_COST = _cost[i];}ART_COST = (ART_COST + 1) * _node_num;}for (int i = 0; i != _arc_num; ++i) {_flow[i] = 0;_state[i] = STATE_LOWER;}_root = _node_num;_parent[_root] = -1;_pred[_root] = -1;_thread[_root] = 0;_rev_thread[0] = _root;_succ_num[_root] = _node_num + 1;_last_succ[_root] = _root - 1;_supply[_root] = -_sum_supply;_pi[_root] = 0;if (_sum_supply == 0) {_search_arc_num = _arc_num;_all_arc_num = _arc_num + _node_num;for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {_parent[u] = _root;_pred[u] = e;_thread[u] = u + 1;_rev_thread[u + 1] = u;_succ_num[u] = 1;_last_succ[u] = u;_cap[e] = INF;_state[e] = STATE_TREE;if (_supply[u] >= 0) {_pred_dir[u] = DIR_UP;_pi[u] = 0;_source[e] = u;_target[e] = _root;_flow[e] = _supply[u];_cost[e] = 0;} else {_pred_dir[u] = DIR_DOWN;_pi[u] = ART_COST;_source[e] = _root;_target[e] = u;_flow[e] = -_supply[u];_cost[e] = ART_COST;}}} else if (_sum_supply > 0) {_search_arc_num = _arc_num + _node_num;int f = _arc_num + _node_num;for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {_parent[u] = _root;_thread[u] = u + 1;_rev_thread[u + 1] = u;_succ_num[u] = 1;_last_succ[u] = u;if (_supply[u] >= 0) {_pred_dir[u] = DIR_UP;_pi[u] = 0;_pred[u] = e;_source[e] = u;_target[e] = _root;_cap[e] = INF;_flow[e] = _supply[u];_cost[e] = 0;_state[e] = STATE_TREE;} else {_pred_dir[u] = DIR_DOWN;_pi[u] = ART_COST;_pred[u] = f;_source[f] = _root;_target[f] = u;_cap[f] = INF;_flow[f] = -_supply[u];_cost[f] = ART_COST;_state[f] = STATE_TREE;_source[e] = u;_target[e] = _root;_cap[e] = INF;_flow[e] = 0;_cost[e] = 0;_state[e] = STATE_LOWER;++f;}}_all_arc_num = f;} else {_search_arc_num = _arc_num + _node_num;int f = _arc_num + _node_num;for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {_parent[u] = _root;_thread[u] = u + 1;_rev_thread[u + 1] = u;_succ_num[u] = 1;_last_succ[u] = u;if (_supply[u] <= 0) {_pred_dir[u] = DIR_DOWN;_pi[u] = 0;_pred[u] = e;_source[e] = _root;_target[e] = u;_cap[e] = INF;_flow[e] = -_supply[u];_cost[e] = 0;_state[e] = STATE_TREE;} else {_pred_dir[u] = DIR_UP;_pi[u] = -ART_COST;_pred[u] = f;_source[f] = u;_target[f] = _root;_cap[f] = INF;_flow[f] = _supply[u];_state[f] = STATE_TREE;_cost[f] = ART_COST;_source[e] = _root;_target[e] = u;_cap[e] = INF;_flow[e] = 0;_cost[e] = 0;_state[e] = STATE_LOWER;++f;}}_all_arc_num = f;}return true;}bool checkBoundMaps(){for (int j = 0; j != _arc_num; ++j) {if (_upper[j] < _lower[j]) return false;}return true;}void findJoinNode(){int u = _source[in_arc];int v = _target[in_arc];while (u != v) {if (_succ_num[u] < _succ_num[v]) {u = _parent[u];} else {v = _parent[v];}}join = u;}bool findLeavingArc(){int first, second;if (_state[in_arc] == STATE_LOWER) {first = _source[in_arc];second = _target[in_arc];} else {first = _target[in_arc];second = _source[in_arc];}delta = _cap[in_arc];int result = 0;Value c, d;int e;for (int u = first; u != join; u = _parent[u]) {e = _pred[u];d = _flow[e];if (_pred_dir[u] == DIR_DOWN) {c = _cap[e];d = c >= MAX ? INF : c - d;}if (d < delta) {delta = d;u_out = u;result = 1;}}for (int u = second; u != join; u = _parent[u]) {e = _pred[u];d = _flow[e];if (_pred_dir[u] == DIR_UP) {c = _cap[e];d = c >= MAX ? INF : c - d;}if (d <= delta) {delta = d;u_out = u;result = 2;}}if (result == 1) {u_in = first;v_in = second;} else {u_in = second;v_in = first;}return result != 0;}void changeFlow(bool change){if (delta > 0) {Value val = _state[in_arc] * delta;_flow[in_arc] += val;for (int u = _source[in_arc]; u != join; u = _parent[u]) {_flow[_pred[u]] -= _pred_dir[u] * val;}for (int u = _target[in_arc]; u != join; u = _parent[u]) {_flow[_pred[u]] += _pred_dir[u] * val;}}if (change) {_state[in_arc] = STATE_TREE;_state[_pred[u_out]]= (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;} else {_state[in_arc] = -_state[in_arc];}}void updateTreeStructure(){int old_rev_thread = _rev_thread[u_out];int old_succ_num = _succ_num[u_out];int old_last_succ = _last_succ[u_out];v_out = _parent[u_out];if (u_in == u_out) {_parent[u_in] = v_in;_pred[u_in] = in_arc;_pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;if (_thread[v_in] != u_out) {int after = _thread[old_last_succ];_thread[old_rev_thread] = after;_rev_thread[after] = old_rev_thread;after = _thread[v_in];_thread[v_in] = u_out;_rev_thread[u_out] = v_in;_thread[old_last_succ] = after;_rev_thread[after] = old_last_succ;}} else {int thread_continue = old_rev_thread == v_in? _thread[old_last_succ]: _thread[v_in];int stem = u_in;int par_stem = v_in;int next_stem;int last = _last_succ[u_in];int before, after = _thread[last];_thread[v_in] = u_in;_dirty_revs.clear();_dirty_revs.push_back(v_in);while (stem != u_out) {next_stem = _parent[stem];_thread[last] = next_stem;_dirty_revs.push_back(last);before = _rev_thread[stem];_thread[before] = after;_rev_thread[after] = before;_parent[stem] = par_stem;par_stem = stem;stem = next_stem;last = _last_succ[stem] == _last_succ[par_stem]? _rev_thread[par_stem]: _last_succ[stem];after = _thread[last];}_parent[u_out] = par_stem;_thread[last] = thread_continue;_rev_thread[thread_continue] = last;_last_succ[u_out] = last;if (old_rev_thread != v_in) {_thread[old_rev_thread] = after;_rev_thread[after] = old_rev_thread;}for (int i = 0; i != int(_dirty_revs.size()); ++i) {int u = _dirty_revs[i];_rev_thread[_thread[u]] = u;}int tmp_sc = 0, tmp_ls = _last_succ[u_out];for (int u = u_out, p = _parent[u]; u != u_in;u = p, p = _parent[u]) {_pred[u] = _pred[p];_pred_dir[u] = -_pred_dir[p];tmp_sc += _succ_num[u] - _succ_num[p];_succ_num[u] = tmp_sc;_last_succ[p] = tmp_ls;}_pred[u_in] = in_arc;_pred_dir[u_in] = u_in == _source[in_arc] ? DIR_UP : DIR_DOWN;_succ_num[u_in] = old_succ_num;}int up_limit_out = _last_succ[join] == v_in ? join : -1;int last_succ_out = _last_succ[u_out];for (int u = v_in; u != -1 && _last_succ[u] == v_in; u = _parent[u]) {_last_succ[u] = last_succ_out;}if (join != old_rev_thread && v_in != old_rev_thread) {for (int u = v_out;u != up_limit_out && _last_succ[u] == old_last_succ;u = _parent[u]) {_last_succ[u] = old_rev_thread;}} else if (last_succ_out != old_last_succ) {for (int u = v_out;u != up_limit_out && _last_succ[u] == old_last_succ;u = _parent[u]) {_last_succ[u] = last_succ_out;}}for (int u = v_in; u != join; u = _parent[u]) {_succ_num[u] += old_succ_num;}for (int u = v_out; u != join; u = _parent[u]) {_succ_num[u] -= old_succ_num;}}void updatePotential(){Cost sigma = _pi[v_in] - _pi[u_in] - _pred_dir[u_in] * _cost[in_arc];int end = _thread[_last_succ[u_in]];for (int u = u_in; u != end; u = _thread[u]) {_pi[u] += sigma;}}bool initialPivots(){Value curr, total = 0;std::vector<Node> supply_nodes, demand_nodes;for (int u = 0; u < _node_num; ++u) {curr = _supply[u];if (curr > 0) {total += curr;supply_nodes.push_back(u);} else if (curr < 0) {demand_nodes.push_back(u);}}if (_sum_supply > 0) total -= _sum_supply;if (total <= 0) return true;IntVector arc_vector;if (_sum_supply >= 0) {if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {std::vector<char> reached(_node_num, false);Node s = supply_nodes[0], t = demand_nodes[0];std::vector<Node> stack;reached[t] = true;stack.push_back(t);while (!stack.empty()) {Node u, v = stack.back();stack.pop_back();if (v == s) break;for (auto a : _graph.in_eids[v]) {if (reached[u = _graph.source(a)]) continue;int j = a;if (_cap[j] >= total) {arc_vector.push_back(j);reached[u] = true;stack.push_back(u);}}}} else {for (int i = 0; i != int(demand_nodes.size()); ++i) {Node v = demand_nodes[i];Cost c, min_cost = std::numeric_limits<Cost>::max();Arc min_arc = INVALID;for (auto a : _graph.in_eids[v]) {c = _cost[a];if (c < min_cost) {min_cost = c;min_arc = a;}}if (min_arc != INVALID) { arc_vector.push_back(min_arc); }}}} else {for (Node u : supply_nodes) {Cost c, min_cost = std::numeric_limits<Cost>::max();Arc min_arc = INVALID;for (auto a : _graph.out_eids[u]) {c = _cost[a];if (c < min_cost) {min_cost = c;min_arc = a;}}if (min_arc != INVALID) { arc_vector.push_back(min_arc); }}}for (int i = 0; i != int(arc_vector.size()); ++i) {in_arc = arc_vector[i];if (_state[in_arc]* (_cost[in_arc] + _pi[_source[in_arc]]- _pi[_target[in_arc]])>= 0)continue;findJoinNode();bool change = findLeavingArc();if (delta >= MAX) return false;changeFlow(change);if (change) {updateTreeStructure();updatePotential();}}return true;}ProblemType start(PivotRule pivot_rule){switch (pivot_rule) {case FIRST_ELIGIBLE:return start<FirstEligiblePivotRule>();case BEST_ELIGIBLE:return start<BestEligiblePivotRule>();case BLOCK_SEARCH:return start<BlockSearchPivotRule>();case CANDIDATE_LIST:return start<CandidateListPivotRule>();case ALTERING_LIST:return start<AlteringListPivotRule>();}return INFEASIBLE;}template<typename PivotRuleImpl>ProblemType start(){PivotRuleImpl pivot(*this);if (!initialPivots()) return UNBOUNDED;while (pivot.findEnteringArc()) {findJoinNode();bool change = findLeavingArc();if (delta >= MAX) return UNBOUNDED;changeFlow(change);if (change) {updateTreeStructure();updatePotential();}}for (int e = _search_arc_num; e != _all_arc_num; ++e) {if (_flow[e] != 0) return INFEASIBLE;}if (_has_lower) {for (int i = 0; i != _arc_num; ++i) {Value c = _lower[i];if (c != 0) {_flow[i] += c;_supply[_source[i]] += c;_supply[_target[i]] -= c;}}}if (_sum_supply == 0) {if (_stype == GEQ) {Cost max_pot = -std::numeric_limits<Cost>::max();for (int i = 0; i != _node_num; ++i) {if (_pi[i] > max_pot) max_pot = _pi[i];}if (max_pot > 0) {for (int i = 0; i != _node_num; ++i)_pi[i] -= max_pot;}} else {Cost min_pot = std::numeric_limits<Cost>::max();for (int i = 0; i != _node_num; ++i) {if (_pi[i] < min_pot) min_pot = _pi[i];}if (min_pot < 0) {for (int i = 0; i != _node_num; ++i)_pi[i] -= min_pot;}}}return OPTIMAL;}};template<typename Capacity = long long, typename Weight = long long>struct mcf_graph_ns{struct Digraph{const int V;int E;std::vector<std::vector<int>> in_eids, out_eids;std::vector<std::pair<int, int>> arcs;Digraph(int V = 0) : V(V), E(0), in_eids(V), out_eids(V){};int add_edge(int s, int t){assert(0 <= s and s < V);assert(0 <= t and t < V);in_eids[t].push_back(E), out_eids[s].push_back(E),arcs.emplace_back(s, t), E++;return E - 1;}int countNodes() const noexcept{return V;}int countArcs() const noexcept{return E;}int source(int arcid) const{return arcs[arcid].first;}int target(int arcid) const{return arcs[arcid].second;}};struct edge{int eid;int from, to;Capacity lo, hi;Weight weight;friend Ostream& operator<<(Ostream& os, const edge& e){return (os << e.from << "->" << e.to << ":" << e.weight);}};int n;std::vector<Capacity> bs;bool infeasible;std::vector<edge> Edges;mcf_graph_ns(int V = 0) : n(V), bs(V), infeasible(false) {}int add_edge(int from,int to,Capacity lower,Capacity upper,Weight weight){assert(from >= 0 and from < n);assert(to >= 0 and to < n);int idnow = Edges.size();Edges.push_back({idnow, from, to, lower, upper, weight});return idnow;}void set_supply(int v, Capacity b){assert(v >= 0 and v < n);bs[v] = b;}std::vector<Capacity> flow;std::vector<Capacity> potential;template<typename RetVal = __int128>[[nodiscard]] RetVal solve(){std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());std::vector<int> vid(n), eid(Edges.size());std::iota(vid.begin(), vid.end(), 0);std::shuffle(vid.begin(), vid.end(), rng);std::iota(eid.begin(), eid.end(), 0);std::shuffle(eid.begin(), eid.end(), rng);flow.clear();potential.clear();Digraph graph(n + 1);std::vector<Capacity> supplies(graph.countNodes());std::vector<Capacity> lowers(Edges.size());std::vector<Capacity> uppers(Edges.size());std::vector<Weight> weights(Edges.size());for (int i = 0; i < n; i++)supplies[vid[i]] = bs[i];for (auto i : eid) {const auto& e = Edges[i];int arc = graph.add_edge(vid[e.from], vid[e.to]);lowers[arc] = e.lo;uppers[arc] = e.hi;weights[arc] = e.weight;}NetworkSimplex<Digraph, Capacity, Weight> ns(graph);auto status = ns.supplyMap(supplies).costMap(weights).lowerMap(lowers).upperMap(uppers).run(decltype(ns)::BLOCK_SEARCH);if (status == decltype(ns)::INFEASIBLE) {return infeasible = true, 0;} else {flow.resize(Edges.size());potential.resize(n);for (int i = 0; i < int(Edges.size()); i++)flow[eid[i]] = ns.flow(i);for (int i = 0; i < n; i++)potential[i] = ns.potential(vid[i]);return ns.template totalCost<RetVal>();}}};int main(){const auto [N, M] = in.tup<int, int>();const auto [X, Y, Z] = in.tup<int, int, int>(1, 1, 1);auto g = ndVec({N, N}, 1);for (int i : rep(N)) {g[i][i] = 0;}for (int i : rep(M)) {const auto [A, B] = in.tup<int, int>(1, 1);g[A][B] = g[B][A] = 0;}auto vin = [&, X = X, Y = Y, Z = Z](int i) {if (i == X) { return 2 * X; }if (i == Y) { return 2 * Y; }return 2 * i;};auto vout = [&, X = X, Y = Y, Z = Z, N = N](int i) {if (i == X) { return 2 * X; }if (i == Y) { return 2 * Y; }return 2 * i + 1;};mcf_graph_ns<int, i64> flow(4 * N);for (int i : rep(N)) {if (g[X][i]) { flow.add_edge(vout(X), vin(i), 0, 1, 0); }}for (int i : rep(N)) {if (g[i][Y]) {flow.add_edge(vout(i), vin(Y), 0, 1, 0);flow.add_edge(vout(i) + 2 * N, vin(Y) + 2 * N, 0, 1, 0);}}for (int i : rep(N)) {if (i == X or i == Y) { continue; }if (i == Z) {flow.add_edge(vin(i), vout(i) + 2 * N, 0, 1, 1);} else {flow.add_edge(vin(i), vout(i), 0, 1, 1);flow.add_edge(vin(i) + 2 * N, vout(i) + 2 * N, 0, 1, 1);}}for (int i : rep(N)) {if (i == X or i == Y) { continue; }for (int j : rep(N)) {if (j == X or j == Y) { continue; }if (g[i][j] == 0) { continue; }flow.add_edge(vout(i), vin(j), 0, 1, 0);flow.add_edge(vout(i) + 2 * N, vin(j) + 2 * N, 0, 1, 0);}}flow.set_supply(vin(X), 2);flow.set_supply(vin(Y), -1);flow.set_supply(vin(Y) + 2 * N, -1);i64 ans = flow.solve() + 2;if (flow.infeasible) {out.ln(-1);} else {void(0);void(0);void(0);for (int i : rep(flow.flow.size())) {if (flow.flow[i]) { void(0); }}out.ln(ans);}return 0;}