Problem:
B: Spent Fuel Disposal
問題文
$N$ 個の下水処理施設が $M$ 本のパイプで繋がっており、$i$ 番目のパイプは $u_i$ 番目と $v_i$ 番目の施設を繋いでいます。
パイプは全て、毎秒最大 $1$ リットルの液体を流すことができます、
今、$S$ 番目の施設から $T$ 番目の施設へ工業廃水を、 $U$ 番目の施設から $V$ 番目の施設へ純水を流したいです。$S$ 番目および $U$ 番目の施設は、それぞれ工業廃水および純水を十分な量有しており、パイプで繋がっている別の施設へこれらの液体を好きに送ることができます。 
また、各施設では、送られてきた液体をパイプで繋がっている別の処理施設へ流すことができます。
パイプはハイテクなので、$2$ 種類の液体を同時に好きな方向へ流すことができます。 
例えば、$i$ 番目のパイプは、$u_i$ から $v_i$ へ工業廃水を、$v_i$ から $u_i$ へ純水を流すことができます。
反対に $v_i$ から $u_i$ へ工業廃水を、$u_i$ から $v_i$ へ純水を流すことも可能です。
もちろん、$2$ 種類の液体を同じ方向へ流すこともできます。
ただし、どの場合においても、$1$ つのパイプに流す液体の総量は毎秒 $1$ リットルを超えることはできません。 $S$ から $T$ へ流す工業廃水の総量と $U$ から $V$ へ流す純水の総量の合計は、最大で毎秒何リットルにできますか。
答えは整数になることが証明できるため、整数で出力してください。
制約
入力は全て整数
$1 \leq N, M \leq 10^5$
$1 \leq S, T, U, V \leq N$
$S \neq T$
$U \neq V$
$1 \leq u_i, v_i \leq N$
$u_i < v_i$ ($i = 1, \ldots, M$)
$i \neq j  \rightarrow (u_i, v_i) \neq (u_j, v_j)$
全ての施設はパイプを通じて連結である
入力
入力は標準入力から以下の形式で与えられます。
$N$ $M$ $S$ $T$ $U$ $V$
$u_1$ $v_1$
$\vdots$
$u_M$ $v_M$
出力
答えを1行に出力してください。
入出力例
入力例1
5 6 1 4 2 3
1 2
2 3
3 4
4 5
3 5
1 5
出力例1
2
例えば、$1$ から $5$、$5$ から $4$ へ工業排水を毎秒 $1$ リットル、$2$ から $3$ へ純水を毎秒 $1$ リットル流せば良いです。
入力例2
3 3 1 2 1 3
1 2
1 3
2 3
出力例2
2
$T$ と $V$ が同一の施設であるケースなどに注意してください。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for(ll i=0; i <ll(n); i++)
template <class T> using V = vector<T>;
template <class A, class B>
bool chmax(A &a, B b) { return a < b && (a=b, true); }
template <class A, class B>
bool chmin(A &a, B b) { return b < a && (a=b, true); }

template<class C>
struct MaxFlow {
    C flow;
    V<char> dual; // false: S-side true: T-side
};

template<class C, class E>
struct MFExec {
    static constexpr C INF = numeric_limits<C>::max();
    C eps;
    V<V<E>>& g;
    int s, t;
    V<int> level, iter;

    C dfs(int v, C f) {
        if (v == t) return f;
        C res = 0;
        for (int& i = iter[v]; i < int(g[v].size()); i++) {
            E& e = g[v][i];
            if (e.cap <= eps || level[v] >= level[e.to]) continue;
            C d = dfs(e.to, min(f, e.cap));
            e.cap -= d;
            g[e.to][e.rev].cap += d;
            res += d;
            f -= d;
            if (f == 0) break;
        }
        return res;
    }

    MaxFlow<C> info;
    MFExec(V<V<E>>& _g, int _s, int _t, C _eps)
        : eps(_eps), g(_g), s(_s), t(_t) {
        int N = int(g.size());

        C& flow = (info.flow = 0);
        while (true) {
            queue<int> que;
            level = V<int>(N, -1);
            level[s] = 0;
            que.push(s);
            while (!que.empty()) {
                int v = que.front(); que.pop();
                for (E e: g[v]) {
                    if (e.cap <= eps || level[e.to] >= 0) continue;
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
            if (level[t] == -1) break;
            iter = V<int>(N, 0);
            while (true) {
                C f = dfs(s, INF);
                if (!f) break;
                flow += f;
            }
        }
        for (int i = 0; i < N; i++) info.dual.push_back(level[i] == -1);
    }
};

template<class C, class E>
MaxFlow<C> get_mf(V<V<E>>& g, int s, int t, C eps) {
    return MFExec<C, E>(g, s, t, eps).info;
}

struct Edge { int to, rev, cap; };

void testcase(){
    int N, M, S0, S1, T0, T1;
    cin >> N >> M >> S0 >> S1 >> T0 >> T1; S0--; S1--; T0--; T1--;
    V<V<Edge>> g(N+4);
    auto add_edge = [](auto& g, int from, int to, int cap) {
        g[from].push_back({to, int(g[to].size()), cap});
        g[to].push_back({from, int(g[from].size())-1, 0});
    };
    REP(i,M){
        int u,v; cin >> u >> v; u--; v--;
        add_edge(g, u, v, 1);
        add_edge(g, v, u, 1);
    }
    int ans = M;
    int src = N, snk = N + 1;
    REP(t,2){
        swap(T0, T1);
        auto g2 = g;
        add_edge(g2, src, S0, M);
        add_edge(g2, src, T0, M);
        add_edge(g2, S1, snk, M);
        add_edge(g2, T1, snk, M);
        chmin(ans, get_mf(g2, src, snk, 0).flow);
    }

    cout << ans << "\n";
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 19236
final_rank: 8

code_snippet: // AOJ #2979 Spent Fuel Disposal
// 2025.5.30

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct Edge{int to,cap,rev;};
struct Dinic {
    int N;
    vector<vector<Edge>> G;
    vector<int> level, it;
    Dinic(int n):N(n),G(n),level(n),it(n){}
    void add_edge(int u,int v,int c){
        G[u].push_back({v,c,(int)G[v].size()});
        G[v].push_back({u,0,(int)G[u].size()-1});
    }
    bool bfs(int s,int t){
        fill(level.begin(),level.end(),-1);
        queue<int> q; level[s]=0; q.push(s);
        while(!q.empty()){
            int u=q.front(); q.pop();
            for(auto &e:G[u]){
                if(e.cap>0 && level[e.to]<0){
                    level[e.to]=level[u]+1;
                    q.push(e.to);
                }
            }
        }
        return level[t]>=0;
    }
    int dfs(int u,int t,int f){
        if(u==t) return f;
        for(int &i=it[u]; i<(int)G[u].size(); ++i){
            auto &e = G[u][i];
            if(e.cap>0 && level[e.to]==level[u]+1){
                int r = dfs(e.to,t,min(f,e.cap));
                if(r>0){
                    e.cap -= r;
                    G[e.to][e.rev].cap += r;
                    return r;
                }
            }
        }
        return 0;
    }
    int max_flow(int s,int t){
        int flow=0, f;
        while(bfs(s,t)){
            fill(it.begin(),it.end(),0);
            while((f=dfs(s,t,INT_MAX))>0) flow += f;
        }
        return flow;
    }
};

int n, m, S, T, U, V;
vector<pair<int,int>> edges;
int INF_CAP;

// srcs→sinks の多元最大流を返す
int max_flow_vs(const vector<int> &srcs, const vector<int> &sinks){
    int Nn = n + 2;
    int SS = n, TT = n+1;
    Dinic mf(Nn);
    // 無向辺を両向き有向辺 cap=1 で追加
    for(auto &e: edges){
        int u=e.first, v=e.second;
        mf.add_edge(u,v,1);
        mf.add_edge(v,u,1);
    }
    // 重複を除いて SS→各 src, 各 sink→TT を INF_CAP で追加
    vector<int> us=srcs, vs=sinks;
    sort(us.begin(), us.end());
    us.erase(unique(us.begin(), us.end()), us.end());
    sort(vs.begin(), vs.end());
    vs.erase(unique(vs.begin(), vs.end()), vs.end());
    for(int u: us) mf.add_edge(SS, u, INF_CAP);
    for(int v: vs) mf.add_edge(v, TT, INF_CAP);
    return mf.max_flow(SS, TT);
}

int main(){
    n = Cin(), m = Cin();
    S = Cin()-1, T = Cin()-1, U = Cin()-1, V = Cin()-1;
    edges.resize(m);
    for(int i=0;i<m;i++){
        int u = Cin()-1, v = Cin()-1;
        edges[i] = {u, v};
    }

    INF_CAP = m;
    int fST = max_flow_vs({S}, {T});
    int fUV = max_flow_vs({U}, {V});
    int c1  = fST + fUV;
    int c2 = max_flow_vs({S, U}, {T, V});
    int c3 = max_flow_vs({S, V}, {T, U});
    Cout(min(c1, min(c2, c3)));;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 15200
final_rank: 5

code_snippet: // AOJ #2979 Spent Fuel Disposal
// 2025.5.30

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct Edge { int to, cap, rev; };
struct Dinic {
    int N;
    vector<vector<Edge>> G;
    vector<int> level, it;
    Dinic(int n): N(n), G(n), level(n), it(n) {}
    void add_edge(int u, int v, int c) {
        G[u].push_back({v,c,(int)G[v].size()});
        G[v].push_back({u,0,(int)G[u].size()-1});
    }
    bool bfs(int s, int t) {
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s]=0; q.push(s);
        while(!q.empty()) {
            int u=q.front(); q.pop();
            for(auto &e: G[u]) if(e.cap>0 && level[e.to]<0) {
                level[e.to]=level[u]+1;
                q.push(e.to);
            }
        }
        return level[t]>=0;
    }
    int dfs(int u, int t, int f) {
        if(u==t) return f;
        for(int &i=it[u]; i<(int)G[u].size(); ++i) {
            auto &e = G[u][i];
            if(e.cap>0 && level[e.to]==level[u]+1) {
                int r = dfs(e.to,t,min(f,e.cap));
                if(r>0) {
                    e.cap -= r;
                    G[e.to][e.rev].cap += r;
                    return r;
                }
            }
        }
        return 0;
    }
    int max_flow(int s, int t) {
        int flow=0, f;
        while(bfs(s,t)) {
            fill(it.begin(), it.end(), 0);
            while((f=dfs(s,t,1))>0) flow += f;
        }
        return flow;
    }
};

int main(){
    int n = Cin(), m = Cin();
    int S = Cin()-1, T = Cin()-1, U = Cin()-1, V = Cin()-1;
    vector<pair<int,int>> p(m);
    for(int i=0;i<m;i++){
        int u = Cin()-1, v = Cin()-1;
        p[i] = {u, v};
    }

    int Nn = n + (m << 1);

    auto build = [&](){
        Dinic mf(Nn);
        for(int i=0;i<m;i++){
            int u=p[i].first, v=p[i].second;
            int in = n + i, out = n + m + i;
            mf.add_edge(u, in, 1);
            mf.add_edge(v, in, 1);
            mf.add_edge(in, out, 1);
            mf.add_edge(out, u, 1);
            mf.add_edge(out, v, 1);
        }
        return mf;
    };

    auto mf1 = build();
    int f1 = mf1.max_flow(S, T);
    int f2 = mf1.max_flow(U, V);
    int ans1 = f1 + f2;

    auto mf2 = build();
    int g1 = mf2.max_flow(U, V);
    int g2 = mf2.max_flow(S, T);
    int ans2 = g1 + g2;

    Cout(max(ans1, ans2));
    return 0;
}
accuracy: 0.19148936170212766
time_ms: 320
memory_kb: 52416
final_rank: 18

code_snippet: /**
 *    author:  otera
 *    created: 07.06.2022 16:39:53 
**/
#include<bits/stdc++.h>

#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>


#include <vector>

namespace atcoder {

namespace internal {

template <class T> struct simple_queue {
    std::vector<T> payload;
    int pos = 0;
    void reserve(int n) { payload.reserve(n); }
    int size() const { return int(payload.size()) - pos; }
    bool empty() const { return pos == int(payload.size()); }
    void push(const T& t) { payload.push_back(t); }
    T& front() { return payload[pos]; }
    void clear() {
        payload.clear();
        pos = 0;
    }
    void pop() { pos++; }
};

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

template <class Cap> struct mf_graph {
  public:
    mf_graph() : _n(0) {}
    explicit mf_graph(int n) : _n(n), g(n) {}

    int add_edge(int from, int to, Cap cap) {
        assert(0 <= from && from < _n);
        assert(0 <= to && to < _n);
        assert(0 <= cap);
        int m = int(pos.size());
        pos.push_back({from, int(g[from].size())});
        int from_id = int(g[from].size());
        int to_id = int(g[to].size());
        if (from == to) to_id++;
        g[from].push_back(_edge{to, to_id, cap});
        g[to].push_back(_edge{from, from_id, 0});
        return m;
    }

    struct edge {
        int from, to;
        Cap cap, flow;
    };

    edge get_edge(int i) {
        int m = int(pos.size());
        assert(0 <= i && i < m);
        auto _e = g[pos[i].first][pos[i].second];
        auto _re = g[_e.to][_e.rev];
        return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
    }
    std::vector<edge> edges() {
        int m = int(pos.size());
        std::vector<edge> result;
        for (int i = 0; i < m; i++) {
            result.push_back(get_edge(i));
        }
        return result;
    }
    void change_edge(int i, Cap new_cap, Cap new_flow) {
        int m = int(pos.size());
        assert(0 <= i && i < m);
        assert(0 <= new_flow && new_flow <= new_cap);
        auto& _e = g[pos[i].first][pos[i].second];
        auto& _re = g[_e.to][_e.rev];
        _e.cap = new_cap - new_flow;
        _re.cap = new_flow;
    }

    Cap flow(int s, int t) {
        return flow(s, t, std::numeric_limits<Cap>::max());
    }
    Cap flow(int s, int t, Cap flow_limit) {
        assert(0 <= s && s < _n);
        assert(0 <= t && t < _n);
        assert(s != t);

        std::vector<int> level(_n), iter(_n);
        internal::simple_queue<int> que;

        auto bfs = [&]() {
            std::fill(level.begin(), level.end(), -1);
            level[s] = 0;
            que.clear();
            que.push(s);
            while (!que.empty()) {
                int v = que.front();
                que.pop();
                for (auto e : g[v]) {
                    if (e.cap == 0 || level[e.to] >= 0) continue;
                    level[e.to] = level[v] + 1;
                    if (e.to == t) return;
                    que.push(e.to);
                }
            }
        };
        auto dfs = [&](auto self, int v, Cap up) {
            if (v == s) return up;
            Cap res = 0;
            int level_v = level[v];
            for (int& i = iter[v]; i < int(g[v].size()); i++) {
                _edge& e = g[v][i];
                if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
                Cap d =
                    self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
                if (d <= 0) continue;
                g[v][i].cap += d;
                g[e.to][e.rev].cap -= d;
                res += d;
                if (res == up) return res;
            }
            level[v] = _n;
            return res;
        };

        Cap flow = 0;
        while (flow < flow_limit) {
            bfs();
            if (level[t] == -1) break;
            std::fill(iter.begin(), iter.end(), 0);
            Cap f = dfs(dfs, t, flow_limit - flow);
            if (!f) break;
            flow += f;
        }
        return flow;
    }

    std::vector<bool> min_cut(int s) {
        std::vector<bool> visited(_n);
        internal::simple_queue<int> que;
        que.push(s);
        while (!que.empty()) {
            int p = que.front();
            que.pop();
            visited[p] = true;
            for (auto e : g[p]) {
                if (e.cap && !visited[e.to]) {
                    visited[e.to] = true;
                    que.push(e.to);
                }
            }
        }
        return visited;
    }

  private:
    int _n;
    struct _edge {
        int to, rev;
        Cap cap;
    };
    std::vector<std::pair<int, int>> pos;
    std::vector<std::vector<_edge>> g;
};

}  // namespace atcoder

using namespace std;

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using uint = unsigned;
const int inf=1e9+7;
const ll INF=1LL<<60;
#define repa(i, n) for(int i = 0; i < n; ++ i)
#define repb(i, a, b) for(int i = a; i < b; ++ i)
#define repc(i, a, b, c) for(int i = a; i < b; i += c)
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, repc, repb, repa)(__VA_ARGS__)
#define rep1a(i, n) for(int i = 0; i <= n; ++ i)
#define rep1b(i, a, b) for(int i = a; i <= b; ++ i)
#define rep1c(i, a, b, c) for(int i = a; i <= b; i += c)
#define rep1(...) overload4(__VA_ARGS__, rep1c, rep1b, rep1a)(__VA_ARGS__)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define per1(i,n) for(int i=n;i>=1;i--)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define pb push_back
#define eb emplace_back
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define si(c) (int)(c).size()
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
#define tpow(n) (1LL<<(n))
#define unless(A) if(!(A))
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll intpow(ll a, ll b, ll m) {ll ans = 1; while(b){ if(b & 1) (ans *= a) %= m; (a *= a) %= m; b /= 2; } return ans; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template<class T> void scan(T& a){ cin >> a; }
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ cout << ' '; }
template<class T> void print(const T& a){ cout << a; }
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout << ' '; print(*i); } }
int out(){ cout << '\n'; return 0; }
template<class T> int out(const T& t){ print(t); cout << '\n'; return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); cout << ' '; out(tail...); return 0; }
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0,a1,a2,a3,a4,x,...) x
#define debug_1(x1) cout<<#x1<<": "<<x1<<endl
#define debug_2(x1,x2) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<endl
#define debug_3(x1,x2,x3) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<endl
#define debug_4(x1,x2,x3,x4) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<endl
#define debug_5(x1,x2,x3,x4,x5) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<", "#x5<<": "<<x5<<endl
#ifdef DEBUG
#define debug(...) CHOOSE((__VA_ARGS__,debug_5,debug_4,debug_3,debug_2,debug_1,~))(__VA_ARGS__)
#define dump(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...)
#define dump(...)
#endif

#define int long long

void solve() {
    INT(n, m, s, t, u, v);
    -- s, -- t;
    -- u, -- v;
    atcoder::mf_graph<int> g(n + 2), h(n + 2);
    int a = n, b = n + 1;
    rep(i, m) {
        INT(x, y); -- x, -- y;
        g.add_edge(x, y, 1); g.add_edge(y, x, 1);
        h.add_edge(x, y, 1); h.add_edge(y, x, 1);
    }
    g.add_edge(a, s, inf); g.add_edge(a, u, inf);
    g.add_edge(t, b, inf); g.add_edge(v, b, inf);
    h.add_edge(a, s, inf); h.add_edge(a, v, inf);
    h.add_edge(t, b, inf); h.add_edge(u, b, inf);
    int ans = min(g.flow(a, b), h.flow(a, b));
    out(ans);
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    // cout << fixed << setprecision(20);
    // INT(t); rep(i, t)solve();
    solve();
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 29468
final_rank: 10

code_snippet: #include "bits/stdc++.h"

template <class flow_t>
class dinic {
 public:
  dinic() : _n(0) {}
  dinic(int n) : _n(n), g(n), level(_n), iter(_n) {}

  struct edge {
    int from, to;
    flow_t cap, flow;
  };

  int add_edge(int from, int to, flow_t cap) {
    assert(0 <= from && from < _n);
    assert(0 <= to && to < _n);
    assert(0 <= cap);
    int from_id = int(g[from].size()), to_id = int(g[to].size()) + (from == to);
    int m = int(pos.size());
    pos.push_back({from, from_id});
    g[from].push_back(_edge{to, to_id, cap});
    g[to].push_back(_edge{from, from_id, cap});
    return m;
  }

  edge get_edge(int i) {
    int m = int(pos.size());
    assert(0 <= i && i < m);
    auto _e = g[pos[i].first][pos[i].second];
    auto _re = g[_e.to][_e.rev];
    return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
  }

  std::vector<edge> get_edges() {
    std::vector<edge> edges;
    for (int i = 0; i < int(pos.size()); i++) {
      edges.emplace_back(get_edge(i));
    }
    return edges;
  }

  flow_t flow(int s, int t, flow_t flow_limit) {
    assert(0 <= s && s < _n);
    assert(0 <= t && t < _n);
    assert(s != t);

    flow_t flow = 0;
    while (flow < flow_limit) {
      bfs(s);
      if (level[t] == -1) break;
      std::fill(iter.begin(), iter.end(), 0);
      flow_t f = dfs(s, t, flow_limit - flow);
      if (!f) break;
      flow += f;
    }
    return flow;
  }

  flow_t flow(int s, int t) {
    return flow(s, t, std::numeric_limits<flow_t>::max());
  }

  void output_edges() const {
    for (const auto& e : get_edges()) {
      std::cerr << e.from << "->" << e.to << " : " << e.flow << "/" << e.cap
                << std::endl;
    }
  }

 private:
  int _n;
  struct _edge {
    int to, rev;
    flow_t cap;
  };
  std::vector<std::pair<int, int>> pos;
  std::vector<std::vector<_edge>> g;
  std::vector<int> level, iter;

  void bfs(int s) {
    std::fill(level.begin(), level.end(), -1);
    std::queue<int> que;
    level[s] = 0;
    que.push(s);
    while (!que.empty()) {
      int v = que.front();
      que.pop();
      for (const auto& e : g[v]) {
        if (e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          que.push(e.to);
        }
      }
    }
  }

  flow_t dfs(int v, int t, flow_t f) {
    if (v == t) return f;
    for (int &i = iter[v]; i < (int)g[v].size(); i++) {
      auto& e = g[v][i];
      if (e.cap > 0 && level[v] < level[e.to]) {
        flow_t d = dfs(e.to, t, std::min(f, e.cap));
        if (d > 0) {
          e.cap -= d;
          g[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }
};

using namespace std;
const int inf = 1e8;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int n, m, s, t, u, v;
  cin >> n >> m >> s >> t >> u >> v;
  s--;
  t--;
  u--;
  v--;
  dinic<int> G(n + 2), H(n + 2);
  const int SRC = n, SNK = n + 1;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    G.add_edge(a, b, 1);
    H.add_edge(a, b, 1);
  }
  {
    G.add_edge(SRC, s, inf);
    G.add_edge(SRC, u, inf);
    G.add_edge(t, SNK, inf);
    G.add_edge(v, SNK, inf);
  }
  {
    H.add_edge(SRC, s, inf);
    H.add_edge(SRC, v, inf);
    H.add_edge(t, SNK, inf);
    H.add_edge(u, SNK, inf);
  }
  cout << min(G.flow(SRC, SNK), H.flow(SRC, SNK)) << endl;
}
accuracy: 1
time_ms: 350
memory_kb: 18028
final_rank: 11

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2979

#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename Flow,bool directed>
struct Dinic{
  struct Edge {
    int dst;
    Flow cap;
    int rev;
    Edge(){}
    Edge(int dst,Flow cap,int rev):dst(dst),cap(cap),rev(rev){}
  };

  vector< vector<Edge> > G;
  vector<int> level,iter;

  Dinic(){}
  Dinic(int n):G(n),level(n),iter(n){}

  int add_edge(int src,int dst,Flow cap){
    int e=G[src].size();
    int r=(src==dst?e+1:G[dst].size());
    G[src].emplace_back(dst,cap,r);
    G[dst].emplace_back(src,directed?0:cap,e);
    return e;
  }

  void bfs(int s){
    fill(level.begin(),level.end(),-1);
    queue<int> que;
    level[s]=0;
    que.emplace(s);
    while(!que.empty()){
      int v=que.front();que.pop();
      for(int i=0;i<(int)G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0&&level[e.dst]<0){
          level[e.dst]=level[v]+1;
          que.emplace(e.dst);
        }
      }
    }
  }

  Flow dfs(int v,int t,Flow f){
    if(v==t) return f;
    for(int &i=iter[v];i<(int)G[v].size();i++){
      Edge &e=G[v][i];
      if(e.cap>0&&level[v]<level[e.dst]){
        Flow d=dfs(e.dst,t,min(f,e.cap));
        if(d==0) continue;
        e.cap-=d;
        G[e.dst][e.rev].cap+=d;
        return d;
      }
    }
    return 0;
  }

  Flow flow(int s,int t,Flow lim){
    Flow fl=0;
    while(1){
      bfs(s);
      if(level[t]<0||lim==0) break;
      fill(iter.begin(),iter.end(),0);

      while(1){
        Flow f=dfs(s,t,lim);
        if(f==0) break;
        fl+=f;
        lim-=f;
      }
    }
    return fl;
  }

  Flow flow(int s,int t){
    return flow(s,t,numeric_limits<Flow>::max()/2);
  }

  Flow cut(int s,int t,int x,int a){
    static_assert(directed, "must be directed");
    auto &e=G[x][a];
    int y=e.dst;
    Flow cr=G[y][e.rev].cap;
    if(cr==0) return e.cap=0;
    e.cap=G[y][e.rev].cap=0;
    Flow cap=cr-flow(x,y,cr);
    if(x!=s&&cap!=0) flow(x,s,cap);
    if(t!=y&&cap!=0) flow(t,y,cap);
    return cap;
  }

  Flow link(int s,int t,int x,int a,Flow f){
    auto &e=G[x][a];
    e.cap+=f;
    return flow(s,t,f);
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#include "./dinic.cpp"
#undef call_from_test

#endif
//BEGIN CUT HERE
template<typename Flow, bool directed>
struct TwoCommodity{
  Dinic<Flow, directed> G,H;
  int S,T;
  TwoCommodity(int n):G(n+2),H(n+2),S(n),T(n+1){}

  void add_edge(int src,int dst,Flow cap){
    G.add_edge(src,dst,cap);
    H.add_edge(src,dst,cap);
  }

  // maximize sum of two flows (s -> t) and (u -> v)
  Flow build(int s,int t,int u,int v){
    const Flow INF = numeric_limits<Flow>::max()/4;

    G.add_edge(S,s,INF);
    G.add_edge(S,u,INF);
    G.add_edge(t,T,INF);
    G.add_edge(v,T,INF);

    H.add_edge(S,s,INF);
    H.add_edge(S,v,INF);
    H.add_edge(t,T,INF);
    H.add_edge(u,T,INF);

    return min(G.flow(S,T),H.flow(S,T));
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,s,t,u,v;
  cin>>n>>m>>s>>t>>u>>v;
  s--;t--;u--;v--;

  TwoCommodity<int, false> G(n);
  for(int i=0;i<m;i++){
    int x,y;
    cin>>x>>y;
    x--;y--;
    G.add_edge(x,y,1);
  }

  cout<<G.build(s,t,u,v)<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 16608
final_rank: 7

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2979

#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename Flow,bool directed>
struct Dinic{
  struct Edge {
    int dst;
    Flow cap;
    int rev;
    Edge(){}
    Edge(int dst,Flow cap,int rev):dst(dst),cap(cap),rev(rev){}
  };

  vector< vector<Edge> > G;
  vector<int> level,iter;

  Dinic(){}
  Dinic(int n):G(n),level(n),iter(n){}

  int add_edge(int src,int dst,Flow cap){
    int e=G[src].size();
    int r=(src==dst?e+1:G[dst].size());
    G[src].emplace_back(dst,cap,r);
    G[dst].emplace_back(src,directed?0:cap,e);
    return e;
  }

  void bfs(int s){
    fill(level.begin(),level.end(),-1);
    queue<int> que;
    level[s]=0;
    que.emplace(s);
    while(!que.empty()){
      int v=que.front();que.pop();
      for(int i=0;i<(int)G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0&&level[e.dst]<0){
          level[e.dst]=level[v]+1;
          que.emplace(e.dst);
        }
      }
    }
  }

  Flow dfs(int v,int t,Flow f){
    if(v==t) return f;
    for(int &i=iter[v];i<(int)G[v].size();i++){
      Edge &e=G[v][i];
      if(e.cap>0&&level[v]<level[e.dst]){
        Flow d=dfs(e.dst,t,min(f,e.cap));
        if(d==0) continue;
        e.cap-=d;
        G[e.dst][e.rev].cap+=d;
        return d;
      }
    }
    return 0;
  }

  Flow flow(int s,int t,Flow lim){
    Flow fl=0;
    while(1){
      bfs(s);
      if(level[t]<0||lim==0) break;
      fill(iter.begin(),iter.end(),0);

      while(1){
        Flow f=dfs(s,t,lim);
        if(f==0) break;
        fl+=f;
        lim-=f;
      }
    }
    return fl;
  }

  Flow flow(int s,int t){
    return flow(s,t,numeric_limits<Flow>::max()/2);
  }

  Flow cut(int s,int t,int x,int a){
    static_assert(directed, "must be directed");
    auto &e=G[x][a];
    int y=e.dst;
    Flow cr=G[y][e.rev].cap;
    if(cr==0) return e.cap=0;
    e.cap=G[y][e.rev].cap=0;
    Flow cap=cr-flow(x,y,cr);
    if(x!=s&&cap!=0) flow(x,s,cap);
    if(t!=y&&cap!=0) flow(t,y,cap);
    return cap;
  }

  Flow link(int s,int t,int x,int a,Flow f){
    auto &e=G[x][a];
    e.cap+=f;
    return flow(s,t,f);
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#include "./dinic.cpp"
#undef call_from_test

#endif
//BEGIN CUT HERE
template<typename Flow, bool directed>
struct TwoCommodity{
  Dinic<Flow, directed> G,H;
  int S,T;
  TwoCommodity(int n):G(n+2),H(n+2),S(n),T(n+1){}

  void add_edge(int src,int dst,Flow cap){
    G.add_edge(src,dst,cap);
    H.add_edge(src,dst,cap);
  }

  // maximize sum of two flows (s -> t) and (u -> v)
  Flow build(int s,int t,int u,int v){
    const Flow INF = numeric_limits<Flow>::max()/4;

    G.add_edge(S,s,INF);
    G.add_edge(S,u,INF);
    G.add_edge(t,T,INF);
    G.add_edge(v,T,INF);

    H.add_edge(S,s,INF);
    H.add_edge(S,v,INF);
    H.add_edge(t,T,INF);
    H.add_edge(u,T,INF);

    return min(G.flow(S,T),H.flow(S,T));
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,s,t,u,v;
  cin>>n>>m>>s>>t>>u>>v;
  s--;t--;u--;v--;

  TwoCommodity<int, false> G(n);
  for(int i=0;i<m;i++){
    int x,y;
    cin>>x>>y;
    x--;y--;
    G.add_edge(x,y,1);
  }

  cout<<G.build(s,t,u,v)<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 16452
final_rank: 2

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2979

#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename Flow,bool directed>
struct Dinic{
  struct Edge {
    int dst;
    Flow cap;
    int rev;
    Edge(){}
    Edge(int dst,Flow cap,int rev):dst(dst),cap(cap),rev(rev){}
  };

  vector< vector<Edge> > G;
  vector<int> level,iter;

  Dinic(){}
  Dinic(int n):G(n),level(n),iter(n){}

  int add_edge(int src,int dst,Flow cap){
    int e=G[src].size();
    int r=(src==dst?e+1:G[dst].size());
    G[src].emplace_back(dst,cap,r);
    G[dst].emplace_back(src,directed?0:cap,e);
    return e;
  }

  void bfs(int s){
    fill(level.begin(),level.end(),-1);
    queue<int> que;
    level[s]=0;
    que.emplace(s);
    while(!que.empty()){
      int v=que.front();que.pop();
      for(int i=0;i<(int)G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0&&level[e.dst]<0){
          level[e.dst]=level[v]+1;
          que.emplace(e.dst);
        }
      }
    }
  }

  Flow dfs(int v,int t,Flow f){
    if(v==t) return f;
    for(int &i=iter[v];i<(int)G[v].size();i++){
      Edge &e=G[v][i];
      if(e.cap>0&&level[v]<level[e.dst]){
        Flow d=dfs(e.dst,t,min(f,e.cap));
        if(d==0) continue;
        e.cap-=d;
        G[e.dst][e.rev].cap+=d;
        return d;
      }
    }
    return 0;
  }

  Flow flow(int s,int t,Flow lim){
    Flow fl=0;
    while(1){
      bfs(s);
      if(level[t]<0||lim==0) break;
      fill(iter.begin(),iter.end(),0);

      while(1){
        Flow f=dfs(s,t,lim);
        if(f==0) break;
        fl+=f;
        lim-=f;
      }
    }
    return fl;
  }

  Flow flow(int s,int t){
    return flow(s,t,numeric_limits<Flow>::max()/2);
  }

  Flow cut(int s,int t,int x,int a){
    static_assert(directed, "must be directed");
    auto &e=G[x][a];
    int y=e.dst;
    Flow cr=G[y][e.rev].cap;
    if(cr==0) return e.cap=0;
    e.cap=G[y][e.rev].cap=0;
    Flow cap=cr-flow(x,y,cr);
    if(x!=s&&cap!=0) flow(x,s,cap);
    if(t!=y&&cap!=0) flow(t,y,cap);
    return cap;
  }

  Flow link(int s,int t,int x,int a,Flow f){
    auto &e=G[x][a];
    e.cap+=f;
    return flow(s,t,f);
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

template<typename Flow, bool directed>
struct TwoCommodity{
  Dinic<Flow, directed> G,H;
  int S,T;
  TwoCommodity(int n):G(n+2),H(n+2),S(n),T(n+1){}

  void add_edge(int src,int dst,Flow cap){
    G.add_edge(src,dst,cap);
    H.add_edge(src,dst,cap);
  }

  // maximize sum of two flows (s -> t) and (u -> v)
  Flow build(int s,int t,int u,int v){
    const Flow INF = numeric_limits<Flow>::max()/4;

    G.add_edge(S,s,INF);
    G.add_edge(S,u,INF);
    G.add_edge(t,T,INF);
    G.add_edge(v,T,INF);

    H.add_edge(S,s,INF);
    H.add_edge(S,v,INF);
    H.add_edge(t,T,INF);
    H.add_edge(u,T,INF);

    return min(G.flow(S,T),H.flow(S,T));
  }
};

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,s,t,u,v;
  cin>>n>>m>>s>>t>>u>>v;
  s--;t--;u--;v--;

  TwoCommodity<int, false> G(n);
  for(int i=0;i<m;i++){
    int x,y;
    cin>>x>>y;
    x--;y--;
    G.add_edge(x,y,1);
  }

  cout<<G.build(s,t,u,v)<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 16480
final_rank: 3

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2979

#include <bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
template<typename T,bool directed>
struct Dinic{
  struct edge {
    int to;
    T cap;
    int rev;
    edge(){}
    edge(int to,T cap,int rev):to(to),cap(cap),rev(rev){}
  };

  vector< vector<edge> > G;
  vector<int> level,iter;

  Dinic(){}
  Dinic(int n):G(n),level(n),iter(n){}

  int add_edge(int from,int to,T cap){
    G[from].emplace_back(to,cap,G[to].size());
    G[to].emplace_back(from,directed?0:cap,G[from].size()-1);
    return G[to].back().rev;
  }

  void bfs(int s){
    fill(level.begin(),level.end(),-1);
    queue<int> que;
    level[s]=0;
    que.emplace(s);
    while(!que.empty()){
      int v=que.front();que.pop();
      for(int i=0;i<(int)G[v].size();i++){
        edge &e=G[v][i];
        if(e.cap>0&&level[e.to]<0){
          level[e.to]=level[v]+1;
          que.emplace(e.to);
        }
      }
    }
  }

  T dfs(int v,int t,T f){
    if(v==t) return f;
    for(int &i=iter[v];i<(int)G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[v]<level[e.to]){
        T d=dfs(e.to,t,min(f,e.cap));
        if(d==0) continue;
        e.cap-=d;
        G[e.to][e.rev].cap+=d;
        return d;
      }
    }
    return 0;
  }

  T flow(int s,int t,T lim){
    T fl=0;
    while(1){
      bfs(s);
      if(level[t]<0||lim==0) break;
      fill(iter.begin(),iter.end(),0);

      while(1){
        T f=dfs(s,t,lim);
        if(f==0) break;
        fl+=f;
        lim-=f;
      }
    }
    return fl;
  }

  T flow(int s,int t){
    return flow(s,t,numeric_limits<T>::max()/2);
  }

  T cut(int s,int t,int x,int a){
    static_assert(directed, "must be directed");
    auto &e=G[x][a];
    int y=e.to;
    T cr=G[y][e.rev].cap;
    if(cr==0) return e.cap=0;
    e.cap=G[y][e.rev].cap=0;
    T cap=cr-flow(x,y,cr);
    if(x!=s&&cap!=0) flow(x,s,cap);
    if(t!=y&&cap!=0) flow(t,y,cap);
    return cap;
  }

  T link(int s,int t,int x,int a,T f){
    auto &e=G[x][a];
    e.cap+=f;
    return flow(s,t,f);
  }
};
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed main(){
  return 0;
}
#endif

#undef call_from_test

signed main(){cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,s,t,u,v;
  cin>>n>>m>>s>>t>>u>>v;
  s--;t--;u--;v--;

  Dinic<int, false> G(n+2),H(n+2);
  int S=n,T=n+1;
  for(int i=0;i<m;i++){
    int x,y;
    cin>>x>>y;
    x--;y--;
    G.add_edge(x,y,1);
    H.add_edge(x,y,1);
  }
  const int INF = 1e8;
  G.add_edge(S,s,INF);
  G.add_edge(S,u,INF);
  G.add_edge(t,T,INF);
  G.add_edge(v,T,INF);

  H.add_edge(S,s,INF);
  H.add_edge(S,v,INF);
  H.add_edge(t,T,INF);
  H.add_edge(u,T,INF);

  cout<<min(G.flow(S,T),H.flow(S,T))<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 16500
final_rank: 4

code_snippet: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<queue>
#include<stack>
using namespace std;
#define MOD 1000000007
#define INF (1<<29)
#define LINF (1LL<<60)
#define EPS (1e-10)
typedef long long Int;
typedef pair<Int, Int> P;

class Edge{
public:
    int from, to, rev;
    Int cost, lim;
    Edge(int from, int to, Int cost, int lim = -1, Int rev = -1):
        from(from),to(to),cost(cost),lim(lim),rev(rev){}
};


class Graph{
public:
    int n;
    int m;
    vector<vector<Edge>> edge;
    Graph(int n = 0):n(n),m(0){
        edge = vector<vector<Edge>>(n);
    }
    void add_edge(int from, int to, int cost = 1, int lim = -1)
        {
            if(lim == -1){
                edge[from].push_back(Edge(from, to, cost));
                return;
            }
            edge[from].push_back(Edge(from, to, cost, lim, edge[to].size()));
            edge[to].push_back(Edge(to, from, -cost, 0, edge[from].size() - 1));
        }
};



class Dinic{
public:
    Graph *g;
    vector<int> iter, level, come;

    Dinic(){};
    void bfs(int s){
        queue<int> q;
        fill(level.begin(), level.end(), INF);
        level[s] = 0;
        q.push(s);
        while(!q.empty()){
            int x = q.front();q.pop();
            for(auto e:g->edge[x]){
                if(level[e.to] != INF)continue;
                if(e.lim <= 0)continue;
                level[e.to] = level[x] + 1;
                q.push(e.to);
            }
        }
    }

    Int dfs(int s, int t, Int f){
        if(s == t)return f;
        if(come[s])return 0;
        come[s] = true;
        for(int &i = iter[s];i < g->edge[s].size();i++){
            Edge &e = g->edge[s][i];
            if(e.lim <= 0)continue;
            Int tmp = dfs(e.to, t, min(f, e.lim));
            if(tmp == 0)continue;
            e.lim -= tmp;
            g->edge[e.to][e.rev].lim += tmp;
            return tmp;
        }
        return 0;
    }
    Int max_flow(Graph &_g, int s, int t){
        g = &_g;
        iter = vector<int>(g->n);
        level = vector<int>(g->n);
        come = vector<int>(g->n, 0);
        Int res = 0;
        while(true){
            bfs(s);
            if(level[t] == INF)break;
            fill(iter.begin(), iter.end(), 0);
            while(true){
                fill(come.begin(), come.end(), false);
                Int tmp = dfs(s, t, INF);
                if(tmp == 0)break;
                else res += tmp;
            }
        }
        return res;   
    }  
};

Int n, m,u, v;
Int S, T, U, V;
int main(){
    cin >> n >> m;
    cin >> S >> T >> U >> V;
    Graph g1(n + 3), g2(n+3);
    int X = n+1, Y = n + 2;
    for(int i = 0;i < m;i++){
        cin >> u >> v;
        g1.add_edge(u, v, 1, 1);
        g1.add_edge(v, u, 1, 1);
        g2.add_edge(u, v, 1, 1);
        g2.add_edge(v, u, 1, 1);
    }
    g1.add_edge(X, S, 1, 1100000);
    g1.add_edge(X, U, 1, 1100000);
    g1.add_edge(T, Y, 1, 1100000);
    g1.add_edge(V, Y, 1, 1100000);
    g2.add_edge(X, S, 1, 1100000);
    g2.add_edge(X, V, 1, 1100000);
    g2.add_edge(T, Y, 1, 1100000);
    g2.add_edge(U, Y, 1, 1100000);
    Dinic d;
    Int ans = LINF;
    if(S != V && T != U)ans = min(ans, d.max_flow(g1, X, Y));
    if(S != U && T != V)ans = min(ans, d.max_flow(g2, X, Y));
    cout << ans << endl;
    
    
    return 0;
}
accuracy: 1
time_ms: 1050
memory_kb: 43568
final_rank: 14

code_snippet: #include "bits/stdc++.h"

using namespace std;
#define REP(i, n) for (ll i = 0; i < n; ++i)
using ll = long long;

struct Edge {
	int to, cap, rev, cost;
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

struct maxflow {
	Graph g;
	vector<int> level, iter;
	maxflow(int n) {
		level.resize(n);
		iter.resize(n);
		g.resize(n);
	}

	void add_edge(int from, int to, int cap, int cost = 0) {
		g[from].push_back(Edge{to, cap, (int)g[to].size(), cost});
		g[to].push_back(Edge{from, 0, (int)g[from].size() - 1, -cost});
	}

	void bfs(int s) {
		fill(level.begin(), level.end(), -1);
		queue<int> q;
		level[s] = 0;
		q.push(s);
		while (!q.empty()) {
			int v = q.front();
			q.pop();
			for (auto &&e : g[v]) {
				if (e.cap > 0 && level[e.to] < 0) {
					level[e.to] = level[v] + 1;
					q.push(e.to);
				}
			}
		}
	}
	int dfs(int v, int t, int f) {
		if (v == t) return f;
		for (int &i = iter[v]; i < g[v].size(); i++) {
			Edge &e = g[v][i];
			if (e.cap > 0 && level[v] < level[e.to]) {
				int d = dfs(e.to, t, min(f, e.cap));
				if (d > 0) {
					e.cap -= d;
					g[e.to][e.rev].cap += d;
					return d;
				}
			}
		}
		return 0;
	}
	int max_flow(int s, int t) {
		int flow = 0;
		while (true) {
			bfs(s);
			if (level[t] < 0) return flow;
			fill(iter.begin(), iter.end(), 0);
			int f;
			while ((f = dfs(s, t, 1e9)) > 0) {
				flow += f;
			}
		}
	}
};

int main() {
	int n, m, s, t, u, v;
	cin >> n >> m >> s >> t >> u >> v;
	s--;
	t--;
	u--;
	v--;
	maxflow mf(n);
	vector<int> a(m), b(m);
	REP(i, m) {
		cin >> a[i] >> b[i];
		a[i]--;
		b[i]--;
		mf.add_edge(a[i], b[i], 1, 1);
		mf.add_edge(b[i], a[i], 1, 1);
	}
	int k = mf.max_flow(s, t);

	set<pair<int, int>> used;
	REP(i, n) REP(j, mf.g[i].size()) {
		if (mf.g[i][j].cost == 1 && mf.g[i][j].cap == 0) {
			int c = i, d = mf.g[i][j].to;
			if (c > d) swap(c, d);
			used.emplace(c, d);
		}
	}
	maxflow mf2(n);
	REP(i, m) {
		if (!used.count({a[i], b[i]})) {
			mf2.add_edge(a[i], b[i], 1);
			mf2.add_edge(b[i], a[i], 1);
		}
	}
	int l = mf2.max_flow(u, v);
	cout << k + l << endl;
}
accuracy: 0.06382978723404255
time_ms: 40
memory_kb: 20468
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF=1e9;

template<typename T,bool directed>//directedは有向のこと
struct Fordfulkerson{
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  vector<vector<edge> > G;
  vector<int> used;

  Fordfulkerson(){}
  Fordfulkerson(int n):G(n),used(n){}//n個の頂点

  void add_edge(int from,int to,T cap){
    G[from].emplace_back(to,cap,G[to].size());//edgeのrevには逆辺の番号が入る
    G[to].emplace_back(from,directed?0:cap,G[from].size()-1);//有向グラフならcapは0
  }

  T dfs(int v,int t,T f){//v->tにfの流量を道が見つかり次第通していく感じ　通った量が返り値
    if(v==t) return f;//ゴール
    used[v]=true;//通った確認
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to]&&e.cap>0){//まだ通ってなくてcap的にいける場所があるなら
        T d=dfs(e.to,t,min(f,e.cap));//そこからtまで通せるだけ通そうとして見る
        if(d>0){//dだけ通った
          e.cap-=d;//流量を減らす
          G[e.to][e.rev].cap+=d;//逆辺の流量を増やす
          return d;//d通せた
        }
      }
    }
    return 0;
  }

  int flow(int s,int t,T lim){
    T fl=0;
    while(1){
      fill(used.begin(),used.end(),0);//usedの初期化
      T f=dfs(s,t,lim);//sからtまで逆辺を考慮しつつ通す
      if(f==0) break;//全く通らないなら終了
      fl+=f;//通ってるなら流量を増やす
      lim-=f;//初期流量を減らす
    }
    return fl;
  }

  int flow(int s,int t){//全力で流す
    return flow(s,t,numeric_limits<T>::max()/2);
  }

};

signed main(){
  int N,M,S,T,U,V;cin>>N>>M>>S>>T>>U>>V;
  Fordfulkerson<int,0> fl(123456),fl2(123456);
  while(M--){
    int u,v;cin>>u>>v;
    fl.add_edge(u,v,1);
    fl2.add_edge(u,v,1);
  }
  fl.add_edge(123400,S,INF);
  fl.add_edge(123400,U,INF);
  fl.add_edge(T,123401,INF);
  fl.add_edge(V,123401,INF);
  fl2.add_edge(123400,S,INF);
  fl2.add_edge(123400,V,INF);
  fl2.add_edge(T,123401,INF);
  fl2.add_edge(U,123401,INF);
  cout<<min(fl.flow(123400,123401),fl2.flow(123400,123401))<<endl;
}
accuracy: 1
time_ms: 560
memory_kb: 26240
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;

using Int = long long;
using ll = long long;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};

template<typename T> void drop(T x){cout<<x<<endl;exit(0);};

template<typename T, bool directed>
struct Dinic{
  struct edge{
    int to;
    T cap;
    int rev;
    edge(){}
    edge(int to, T cap, int rev):to(to), cap(cap), rev(rev){}
  };

  vector<vector<edge> > G;
  vector<int> level, iter;

  Dinic(){}
  Dinic(int n):G(n), level(n), iter(n){}

  int add_edge(int from, int to, T cap){
    G[from].emplace_back(to, cap, G[to].size());
    G[to].emplace_back(from, directed?0:cap, G[from].size() - 1);
    return G[to].back().rev;
  }

  void bfs(int s){
    fill(level.begin(), level.end(), -1);
    queue<int> que;

    level[s] = 0;
    que.emplace(s);

    while(!que.empty()){
      int v = que.front(); que.pop();
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap > 0 && level[e.to] < 0){
          level[e.to] = level[v] + 1;
          que.emplace(e.to);
        }
      }

    }
  }

  T dfs(int v, int t, T f){
    if(v == t) return f;
    for(int &i=iter[v];i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(e.cap > 0 && level[v] < level[e.to]){
        T d = dfs(e.to, t, min(f, e.cap));
        if(d == 0) continue;
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
    return 0;
  }

  T flow(int s, int t, T lim){
    T fl = 0;
    while(1){
      bfs(s);
      if(level[t] < 0 || lim == 0) break;
      fill(iter.begin(), iter.end(), 0);

      while(1){
        T f = dfs(s, t, lim);
        if(f == 0) break;
        fl += f;
        lim -= f;
      }
    }
    return fl;
  }

  T flow(int s, int t){
    return flow(s, t, numeric_limits<T>::max()/2);
  }
};

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m,s,t,u,v;
  cin>>n>>m>>s>>t>>u>>v;
  s--;t--;u--;v--;

  Dinic<int, false> G(n+2),H(n+2);
  int S=n,T=n+1;
  for(int i=0;i<m;i++){
    int x,y;
    cin>>x>>y;
    x--;y--;
    G.add_edge(x,y,1);
    H.add_edge(x,y,1);
  }
  const int INF = 1e8;
  G.add_edge(S,s,INF);
  G.add_edge(S,u,INF);
  G.add_edge(t,T,INF);
  G.add_edge(v,T,INF);

  H.add_edge(S,s,INF);
  H.add_edge(S,v,INF);
  H.add_edge(t,T,INF);
  H.add_edge(u,T,INF);

  cout<<min(G.flow(S,T),H.flow(S,T))<<endl;
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 16160
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF INT_MAX/2
#define mod 1000000007

#define MAX_V 100010

struct edge{ int to,cap,rev; };
vector<edge> G[MAX_V];
int level[MAX_V];
int iter[MAX_V];

void add_edge(int from,int to,int cap,bool dir){
  G[from].push_back((edge){to,cap,(int)G[to].size()});
  G[to].push_back((edge){from,(dir?cap:0),(int)G[from].size()-1});
}

void bfs(int s){
  memset(level,-1,sizeof(level));
  queue<int> que;
  level[s]=0;
  que.push(s);
  while(!que.empty()){
    int v=que.front(); que.pop();
    for(int i=0;i<(int)G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[e.to]<0){
        level[e.to]=level[v]+1;
        que.push(e.to);
      }
    }
  }
}

int dfs(int v,int t,int f){
  if(v==t)return f;
  for(int &i=iter[v];i<(int)G[v].size();i++){
    edge &e=G[v][i];
    if(e.cap>0&&level[v]<level[e.to]){
      int d=dfs(e.to,t,min(f,e.cap));
      if(d>0){
        e.cap-=d;
        G[e.to][e.rev].cap+=d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s,int t){
  int flow=0;
  while(1){
    bfs(s);
    if(level[t]<0)return flow;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs(s,t,INF))>0){
      flow+=f;
    }
  }
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N,M,S1,T1,S2,T2;
  cin>>N>>M>>S1>>T1>>S2>>T2;
  S1--;T1--;S2--;T2--;
  vector<P> es;

  int source1=N,sink1=N+1,source2=N+2,sink2=N+3;
  rep(i,M){
    int a,b;
    cin>>a>>b;
    a--;b--;
    es.push_back(P(a,b));
  }

  rep(i,M){
    add_edge(es[i].fi,es[i].se,true,1);
  }
  add_edge(source1,S1,M,false); add_edge(source1,S2,M,false); add_edge(T1,sink1,M,false); add_edge(T2,sink1,M,false);
  int f1=max_flow(source1,sink1);

  rep(i,N){
    G[i].clear();
  }
  rep(i,M){
    add_edge(es[i].fi,es[i].se,true,1);
  }
  add_edge(source2,S1,M,false); add_edge(source2,T2,M,false); add_edge(T1,sink2,M,false); add_edge(S2,sink2,M,false);
  int f2=max_flow(source2,sink2);

  cout<<min(f1,f2)<<endl;

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 11824
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF INT_MAX/2
#define mod 1000000007

#define MAX_V 100010

struct edge{ int to,cap,rev; };
vector<edge> G[MAX_V];
int level[MAX_V];
int iter[MAX_V];

void add_edge(int from,int to,int cap,bool dir){
  G[from].push_back((edge){to,cap,(int)G[to].size()});
  G[to].push_back((edge){from,(dir?cap:0),(int)G[from].size()-1});
}

void bfs(int s){
  memset(level,-1,sizeof(level));
  queue<int> que;
  level[s]=0;
  que.push(s);
  while(!que.empty()){
    int v=que.front(); que.pop();
    for(int i=0;i<(int)G[v].size();i++){
      edge &e=G[v][i];
      if(e.cap>0&&level[e.to]<0){
        level[e.to]=level[v]+1;
        que.push(e.to);
      }
    }
  }
}

int dfs(int v,int t,int f){
  if(v==t)return f;
  for(int &i=iter[v];i<(int)G[v].size();i++){
    edge &e=G[v][i];
    if(e.cap>0&&level[v]<level[e.to]){
      int d=dfs(e.to,t,min(f,e.cap));
      if(d>0){
        e.cap-=d;
        G[e.to][e.rev].cap+=d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s,int t){
  int flow=0;
  while(1){
    bfs(s);
    if(level[t]<0)return flow;
    memset(iter,0,sizeof(iter));
    int f;
    while((f=dfs(s,t,INF))>0){
      flow+=f;
    }
  }
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N,M,S1,T1,S2,T2;
  cin>>N>>M>>S1>>T1>>S2>>T2;
  S1--;T1--;S2--;T2--;

  int source1=N,sink1=N+1,source2=N+2,sink2=N+3;
  rep(i,M){
    int a,b;
    cin>>a>>b;
    a--;b--;
    add_edge(a,b,1,true);
  }

  add_edge(source1,S1,M,false); add_edge(source1,S2,M,false); add_edge(T1,sink1,M,false); add_edge(T2,sink1,M,false);
  add_edge(source2,S1,M,false); add_edge(source2,T2,M,false); add_edge(T1,sink2,M,false); add_edge(S2,sink2,M,false);

  cout<<min(max_flow(source1,sink1),max_flow(source2,sink2))<<endl;

  return 0;
}
accuracy: 0.02127659574468085
time_ms: 10
memory_kb: 9552
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for (long long i=0;i<(n);i++)
#define FOR(i,a,b) for (long long i=(a);i<(b);i++)
#define dump(x)  cerr << #x << " => " << (x) << endl
#define MIN(vec) *min_element(vec.begin(), vec.end())
#define MAX(vec) *max_element(vec.begin(), vec.end())
#define UNIQ(vec) vec.erase(unique(vec.begin(), vec.end()),vec.end()) //ソートの必要あり
#define IN(n,m)  (!(m.find(n) == m.end()))
#define FINDL(vec,x) (lower_bound(vec.begin(),vec.end(),x) - vec.begin())
#define FINDU(vec,x) (upper_bound(vec.begin(),vec.end(),x) - vec.begin())
#define EQ(a,b) (abs(a - b) < 1e-10)
using namespace std;
typedef long long LL;
constexpr int dx[4] = {0,1,0,-1};
constexpr int dy[4] = {1,0,-1,0};
constexpr long double pi = M_PI;
constexpr double eps = 1e-10;
constexpr long mod = 1000000007;
// LONG_MAX,LLONG_MAX
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class Key,class Value> ostream& operator << (ostream &s, map<Key,Value> M)
{ for ( auto itr = begin(M); itr != end(M); ++itr) { s << itr->first << ":" << itr->second; } return s;}

using Long = long long;

template<typename W>
struct Edge { 
    int to,rev;
    W cap;
    Edge(int to, int rev, W cap) : to(to), rev(rev), cap(cap) {}
};

template<typename W>
using Graph = vector<vector<Edge<W>>>;

template<typename W>
struct NetWork {
    Graph<W> G;
    NetWork(int V) : G(V) { }
    void add_edge(int from, int to, W cap) {
        G[from].emplace_back(to, (int)G[to].size(), cap);
        G[to].emplace_back(from, (int)G[from].size()-1, 0);
    }
};

// private
template<typename W>
void bfs(int s, Graph<W> &g, vector<int> &level) {
    fill(level.begin(),level.end(), -1);
    queue<int> que;
    level[s] = 0;
    que.push(s);
    while(!que.empty()) {
        int v=que.front();que.pop();
        for(auto &&e : g[v]) {
            if( e.cap > 0 && level[e.to] < 0) {
                level[e.to] = level[v]+1;
                que.push(e.to);
            }
        }
    }
}

// private
template<typename W>
W dfs(int v,int t,W f, Graph<W> &g, vector<int> &iter, vector<int> &level) {
    if(v==t) return f;
    for(int &i = iter[v] ; i < g[v].size();i++ ) {
        Edge<W> &e = g[v][i];
        if( e.cap > 0 && level[v]<level[e.to] ) {
            int d = dfs(e.to, t , min(f , e.cap), g, iter, level);
            if( d > 0 ) {
                e.cap-=d;
                g[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

// Dinic法
template<typename W>
W max_flow(NetWork<W> &network, int s, int t) {
    W flow = 0;
    // networkのグラフ
    Graph<W> &g = network.G;
    // level[i] : 頂点sから頂点iまでの最短距離
    vector<int> level(g.size(), -1);
    vector<int> iter(g.size(), 0);
    for( ; ; ) {
        bfs(s, g, level);
        // フローを流せるエッジが存在しない.
        if( level[t] < 0 ) return flow;
        fill(iter.begin(),iter.end(),0);
        int f;
        while( (f=dfs(s , t, numeric_limits<W>::max(), g, iter, level)) > 0){
            flow += f;
        }
    }
    return flow;
}

int main(void) {
	cin.tie(0);
	ios::sync_with_stdio(false);

    int N, M, S, T, U, V;
    cin >> N >> M >> S >> T >> U >> V;
    S--;T--;U--;V--;
    NetWork<int> network1(N+2);
    NetWork<int> network2(N+2);
    REP(i, M) {
        int u,v;
        cin >> u >> v;
        u--;v--;
        network1.add_edge(u, v, 1);
        network1.add_edge(v, u, 1);
        network2.add_edge(u, v, 1);
        network2.add_edge(v, u, 1);
    }
    int SS = N;
    int GG = N+1;
    network1.add_edge(SS, S, INT_MAX / 2);
    network1.add_edge(T, GG, INT_MAX / 2);
    network1.add_edge(SS, U, INT_MAX / 2);
    network1.add_edge(V, GG, INT_MAX / 2);

    network2.add_edge(SS, S, INT_MAX / 2);
    network2.add_edge(T, GG, INT_MAX / 2);
    network2.add_edge(SS, V, INT_MAX / 2);
    network2.add_edge(U, GG, INT_MAX / 2);

    cout << min( max_flow(network1, SS, GG), max_flow(network2, SS, GG)) << endl;
    

}
accuracy: 1
time_ms: 70
memory_kb: 19240
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;
typedef pair<ll, P> P3;
typedef pair<P ,P> PP;
constexpr ll MOD = ll(1e9) + 7;
constexpr int IINF = INT_MAX;
constexpr ll LLINF = LLONG_MAX;
constexpr int MAX_N = int(2e5) + 5;
constexpr double EPS = 1e-8;
constexpr int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define SORTR(v) sort((v).rbegin(), (v).rend())
#define ALL(v) (v).begin(), (v).end()

struct edge{
    int to, cap, rev;
};

struct Flow{
    Flow(int n){
        G.resize(n);
    }
    vector<vector<edge> > G;
    vector<bool> used;
    
    void add_edge(int from, int to, int cap){
        G[from].emplace_back((edge){to, cap, int(G[to].size())});
        G[to].emplace_back((edge){from, 0, int(G[from].size())-1});
    }
    
    // 増加路の探索
    int dfs(int v, int t, int f){
        if(v == t) return f;
        used[v] = true;
        for(auto &e : G[v]){
            if(!used[e.to] && e.cap > 0){
                int d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    int max_flow(int s, int t){
        used.resize(G.size());
        int flow = 0;
        while(1){
            fill(used.begin(), used.end(), false);
            int f = dfs(s, t, IINF);
            if(f==0) break;
            flow += f;
        }
        return flow;
    }
};

int main() {
    int n, m, S, T, U, V;
    cin >> n >> m >> S >> T >> U >> V;
    S--; T--;
    U--; V--;
    Flow flow1(n+2);
    for(int i=0;i<m;i++){
        int u, v;
        cin >> u >> v;
        u--; v--;
        flow1.add_edge(u,v,1);
        flow1.add_edge(v,u,1);
    }
    int SS = n, TT = n+1;
    flow1.add_edge(SS, S, INT_MAX/2);
    flow1.add_edge(T, TT, INT_MAX/2);
    Flow flow2 = flow1;
    flow1.add_edge(SS, U, INT_MAX/2);
    flow1.add_edge(V, TT, INT_MAX/2);
    flow2.add_edge(SS, V, INT_MAX/2);
    flow2.add_edge(U, TT, INT_MAX/2);
    cout << min(flow1.max_flow(SS,TT), flow2.max_flow(SS,TT)) << endl;
    return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 17664
final_rank: 13

code_snippet: #pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

template<typename T,bool directed>
struct Fordfulkerson{
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  vector<vector<edge> > G;
  vector<int> used; 

  Fordfulkerson(){}
  Fordfulkerson(int n):G(n),used(n){}

  void add_edge(int from,int to,T cap){
    G[from].emplace_back(to,cap,G[to].size());
    G[to].emplace_back(from,directed?0:cap,G[from].size()-1);
  }

  T dfs(int v,int t,T f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to]&&e.cap>0){
        T d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      }
    }
    return 0;
  }

  int flow(int s,int t,T lim){
    T fl=0;
    while(1){
      fill(used.begin(),used.end(),0);
      T f=dfs(s,t,lim);
      if(f==0) break;
      fl+=f;
      lim-=f;
    }
    return fl;
  }
};


signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int V,E,A,B,C,D;
  int a=0,b=0,c=0,d=0;
  cin>>V>>E>>A>>B>>C>>D; A--;B--;C--;D--;
  Fordfulkerson<int, false> G(V+2);
  for(int i=0;i<E;i++){
    int u,v;
    cin>>u>>v; u--; v--;

    if(A==u)a++;
    if(A==v)a++;
    if(B==u)b++;
    if(B==v)b++;
    if(C==u)c++;
    if(C==v)c++;
    if(D==u)d++;
    if(D==v)d++;

    G.add_edge(u,v,1);
  }

  int AA=min(a,b);
  int BB=min(c,d);

  

  int ANS=G.flow(C,D,BB);
  ANS+=G.flow(A,B,AA);
  cout<<ANS<<endl;

  return 0;
}
accuracy: 0.19148936170212766
time_ms: 180
memory_kb: 6668
final_rank: 15

code_snippet: #pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

template<typename T,bool directed>
struct Fordfulkerson{
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  vector<vector<edge> > G;
  vector<int> used; 

  Fordfulkerson(){}
  Fordfulkerson(int n):G(n),used(n){}

  void add_edge(int from,int to,T cap){
    G[from].emplace_back(to,cap,G[to].size());
    G[to].emplace_back(from,directed?0:cap,G[from].size()-1);
  }

  T dfs(int v,int t,T f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to]&&e.cap>0){
        T d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      }
    }
    return 0;
  }

  int flow(int s,int t,T lim){
    T fl=0;
    while(1){
      fill(used.begin(),used.end(),0);
      T f=dfs(s,t,lim);
      if(f==0) break;
      fl+=f;
      lim-=f;
    }
    return fl;
  }
};


signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int V,E,A,B,C,D;
  int a=0,b=0,c=0,d=0;
  cin>>V>>E>>A>>B>>C>>D; A--;B--;C--;D--;
  Fordfulkerson<int, false> G(V+2);
  for(int i=0;i<E;i++){
    int u,v;
    cin>>u>>v; u--; v--;

    if(A==u)a++;
    if(A==v)a++;
    if(B==u)b++;
    if(B==v)b++;
    if(C==u)c++;
    if(C==v)c++;
    if(D==u)d++;
    if(D==v)d++;

    G.add_edge(u,v,1);
  }

  int AA=min(a,b);
  int BB=min(c,d);

  G.add_edge(V,A,a);
  G.add_edge(V,C,c);
  G.add_edge(B,V+1,b);
  G.add_edge(D,V+1,d);
  

  int ANS=G.flow(C,D,BB);
  ANS+=G.flow(A,B,AA);
  cout<<ANS<<endl;

  return 0;
}
accuracy: 0.19148936170212766
time_ms: 190
memory_kb: 6520
final_rank: 16

code_snippet: #pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

template<typename T,bool directed>
struct Fordfulkerson{
  struct edge{
    int to,cap,rev;
    edge(){}
    edge(int to,int cap,int rev):to(to),cap(cap),rev(rev){}
  };

  vector<vector<edge> > G;
  vector<int> used; 

  Fordfulkerson(){}
  Fordfulkerson(int n):G(n),used(n){}

  void add_edge(int from,int to,T cap){
    G[from].emplace_back(to,cap,G[to].size());
    G[to].emplace_back(from,directed?0:cap,G[from].size()-1);
  }

  T dfs(int v,int t,T f){
    if(v==t) return f;
    used[v]=true;
    for(int i=0;i<(int)G[v].size();i++){
      edge &e = G[v][i];
      if(!used[e.to]&&e.cap>0){
        T d=dfs(e.to,t,min(f,e.cap));
        if(d>0){
          e.cap-=d;
          G[e.to][e.rev].cap+=d;
          return d;
        }
      }
    }
    return 0;
  }

  int flow(int s,int t,T lim){
    T fl=0;
    while(1){
      fill(used.begin(),used.end(),0);
      T f=dfs(s,t,lim);
      if(f==0) break;
      fl+=f;
      lim-=f;
    }
    return fl;
  }
};


signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int V,E,A,B,C,D;
  int a=0,b=0,c=0,d=0;
  cin>>V>>E>>A>>B>>C>>D; A--;B--;C--;D--;
  Fordfulkerson<int, false> G(V+2);
  for(int i=0;i<E;i++){
    int u,v;
    cin>>u>>v; u--; v--;

    if(A==u)a++;
    if(A==v)a++;
    if(B==u)b++;
    if(B==v)b++;
    if(C==u)c++;
    if(C==v)c++;
    if(D==u)d++;
    if(D==v)d++;

    G.add_edge(u,v,1);
  }

  int AA=min(a,b);
  int BB=min(c,d);

  G.add_edge(V,A,a);
  G.add_edge(V,C,c);
  G.add_edge(B,V+1,b);
  G.add_edge(D,V+1,d);
  

  int ANS=G.flow(A,B,AA)+G.flow(C,D,BB);
  cout<<ANS<<endl;

  return 0;
}
accuracy: 0.19148936170212766
time_ms: 200
memory_kb: 6608
final_rank: 17