Problem:
問題文
ハコの魔女 H.N.ELLY はとある動画サイトの熱狂的なファンである．ハコの魔女の強さはその時々のその動画サイトからの転送速度に応じて変化するのではないかと
美樹さやか
は考えた．そこで動画サイトからハコの魔女の持つコンピュータまでの過去の転送速度 (=単位時間あたりのデータの転送量) を調べたい．
初期のインターネットのネットワークの構造とそれ以降のネットワークの構造の変化を表すクエリが与えられるので，各変化について変化した直後の動画サイトからハコの魔女の持つコンピュータまでの転送速度を求めよ．
インターネットは複数の転送装置からなるものと見なし，各々をつなぐ回線は双方向に情報を送ることができ，その転送速度の最大は
1
であるとする．また，ネットワークは常に動画サイトからハコの魔女へ送られるデータの転送速度を最大化するように運ぶものとする．
入力形式
入力は以下の形式で与えられる．
N\ E\ Q\\
F_1\ T_1\\
F_2\ T_2\\
…\\
F_E\ T_E\\
M_1\ A_1\ B_1\\
M_2\ A_2\ B_2\\
...\\
M_Q\ A_Q\ B_Q\\
N
は動画サイトとハコの魔女の持つコンピュータを含めた転送装置の数である．番号が
1
である転送装置は動画サイトであり，番号が
N
である転送装置はハコの魔女の持つコンピュータである．
E
は初期状態で接続されている転送装置の組み合わせの数であり，
Q
はインターネットが変化した回数である．初期のインターネットは
F_i
と
T_i
が転送速度
1
で双方向に接続されていることを表す．
ネットワークの変化は時系列順に与えられ，
j
番目の変化は
M_j
が
1
であれば
A_j,\ B_j
間がつながれたことを表し，
M_j
が
2
であれば
A_j,\ B_j
間の接続が切れたことを表す．
出力形式
各変化の直後における，動画サイトからハコの魔女の持つコンピュータまでの転送速度を出力せよ．
制約
2 \leq N \leq 500
0 \leq E \leq 20,000
1 \leq Q \leq 1,000
1 \leq F_i \leq N,\ 1 \leq T_i \leq N,\ F_i \neq T_i \ (1 \leq i \leq E)
すべての
\{F_i, T_i\}
のペアは異なる．
1 \leq M_j \leq 2,\ 1 \leq A_j \leq N\ ,\ 1 \leq B_j \leq N\ ,\ A_j \neq B_j (1 \leq j \leq Q)
ネットワークのどの段階においても次のことが成り立つ : どの
2
つの転送装置の間も高々
1
つの回線でしか繋がれていない．
2
つの転送装置の間が既に繋がれている状態でそれらの間を接続するようなクエリが来たり，
2
つの転送装置の間が回線で繋がれていない状態でそれらの間の接続を切るようなクエリが来ることはない．
入出力例
入力例 1
2 1 2
1 2
2 1 2
1 2 1
出力例1
0
1
最初の変化の後，ハコの魔女のコンピュータと動画サイトは繋がらなくなっているので転送速度は
0
である．
2
度目の変化の後は両者は直接繋がっており，転送速度は
1
になる．
入力例 2
3 0 4
1 2 3
1 2 1
1 3 1
2 2 3
出力例 2
0
1
2
1
入力例 3
6 4 8
1 2
1 3
4 6
5 6
1 2 4
1 3 5
1 2 5
1 3 4
2 2 4
2 3 5
1 2 4
2 2 1
出力例 3
1
2
2
2
2
2
2
1
入力例 4
12 38 6
1 2
1 3
1 4
1 5
2 3
2 4
2 5
2 6
2 7
2 8
2 12
3 4
3 5
3 6
3 7
3 8
4 5
4 6
4 7
4 8
5 6
5 7
5 8
6 7
6 8
6 9
6 10
6 12
7 8
7 9
7 10
8 9
8 10
9 10
9 11
9 12
10 11
11 12
2 6 12
2 9 12
1 9 12
1 6 12
2 6 12
1 6 12
出力例 4
3
2
3
4
3
4
Problem Setter: Flat35

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct MaxFlow {
    struct Edge {
        int to, rev;
        ll cap;
    };
    int V;
    vector<vector<Edge>> G;
    vector<int> itr, level;
    using P = pair<int, int>;
    vector<P> es;

  public:
    MaxFlow() {}
    MaxFlow(int V) : V(V) {
        G.assign(V, vector<Edge>());
    }
    int add_vertex() {
        G.push_back(vector<Edge>());
        return V++;
    }
    int add_edge(int from, int to, ll cap) {
        int fid = SZ(G[from]), tid = SZ(G[to]);
        if (from == to)
            tid++;
        es.push_back({from, fid});
        G[from].push_back({to, tid, cap});
        G[to].push_back({from, fid, 0});
        return es.size()-1;
    }
    struct Type {
        int from, to;
        ll cap, recap;
    };
    Type get_edge(int i) {
        auto [from, pos] = es[i];
        auto e = G[from][pos];
        auto re = G[e.to][e.rev];
        return Type{from, e.to, e.cap, re.cap};
    }
    void bfs(int s) {
        level.assign(V, -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);
                }
            }
        }
    }
    ll dfs(int v, int t, ll f) {
        if (v == t)
            return f;
        for (int &i = itr[v]; i < (int)G[v].size(); i++) {
            Edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                ll 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;
    }
    ll run(int s, int t, ll flow_limit = INF) {
        ll ret = 0, f;
        while (ret < flow_limit && (bfs(s), level[t] >= 0)) {
            itr.assign(V, 0);
            while ((f = dfs(s, t, flow_limit - ret)) > 0)
                ret += f;
        }
        return ret;
    }
    vector<int> cut() {
        vector<int> ret(V);
        rep(v, 0, V) if (level[v] < 0) ret[v] = 1;
        return ret;
    }
    void erase_edge(int i) {
        auto& e = G[es[i].first][es[i].second];
        auto& re = G[e.to][e.rev];
        e.cap = re.cap = 0;
    }
};

/**
 * @brief Maximum Flow
 */

int main() {
    int N, M, Q;
    cin >> N >> M >> Q;
    MaxFlow G(N);
    map<pair<int,int>,int> mp;
    rep(i,0,M) {
        int A, B;
        cin >> A >> B;
        A--, B--;
        mp[{A,B}] = G.add_edge(A,B,1);
        mp[{B,A}] = G.add_edge(B,A,1);
    }
    int ANS = G.run(0,N-1);
    rep(i,0,Q) {
        int T, A, B;
        cin >> T >> A >> B;
        A--, B--;
        if (T == 1) {
            mp[{A,B}] = G.add_edge(A,B,1);
            mp[{B,A}] = G.add_edge(B,A,1);
            ANS += G.run(0,N-1);
        }
        else {
            int id1 = mp[{A,B}], id2 = mp[{B,A}];
            if (G.get_edge(id1).cap == 0 && G.get_edge(id2).cap == 1) {
                G.erase_edge(id1);
                G.erase_edge(id2);
                if (G.run(A,B,1) == 0) {
                    ANS--;
                    G.run(A,0,1);
                    G.run(N-1,B,1);
                }
            }
            else if (G.get_edge(id2).cap == 0 && G.get_edge(id1).cap == 1) {
                G.erase_edge(id1);
                G.erase_edge(id2);
                if (G.run(B,A,1) == 0) {
                    ANS--;
                    G.run(B,0,1);
                    G.run(N-1,A,1);
                }
            }
            else {
                G.erase_edge(id1);
                G.erase_edge(id2);
            }
        }
        cout << ANS << endl;
    }
}
accuracy: 1
time_ms: 700
memory_kb: 7500
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct MaxFlow {
    struct Edge {
        int to, rev;
        ll cap;
    };
    int V;
    vector<vector<Edge>> G;
    vector<int> itr, level;
    using P = pair<int, int>;
    vector<P> es;

  public:
    MaxFlow() {}
    MaxFlow(int V) : V(V) {
        G.assign(V, vector<Edge>());
    }
    int add_vertex() {
        G.push_back(vector<Edge>());
        return V++;
    }
    int add_edge(int from, int to, ll cap) {
        int fid = SZ(G[from]), tid = SZ(G[to]);
        if (from == to)
            tid++;
        es.push_back({from, fid});
        G[from].push_back({to, tid, cap});
        G[to].push_back({from, fid, 0});
        return es.size()-1;
    }
    struct Type {
        int from, to;
        ll cap, recap;
    };
    Type get_edge(int i) {
        auto [from, pos] = es[i];
        auto e = G[from][pos];
        auto re = G[e.to][e.rev];
        return Type{from, e.to, e.cap, re.cap};
    }
    void bfs(int s) {
        level.assign(V, -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);
                }
            }
        }
    }
    ll dfs(int v, int t, ll f) {
        if (v == t)
            return f;
        for (int &i = itr[v]; i < (int)G[v].size(); i++) {
            Edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                ll 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;
    }
    ll run(int s, int t, ll flow_limit = INF) {
        ll ret = 0, f;
        while (ret < flow_limit && (bfs(s), level[t] >= 0)) {
            itr.assign(V, 0);
            while ((f = dfs(s, t, flow_limit - ret)) > 0)
                ret += f;
        }
        return ret;
    }
    vector<int> cut() {
        vector<int> ret(V);
        rep(v, 0, V) if (level[v] < 0) ret[v] = 1;
        return ret;
    }
    void erase_edge(int i) {
        auto& e = G[es[i].first][es[i].second];
        auto& re = G[e.to][e.rev];
        e.cap = re.cap = 0;
    }
};

/**
 * @brief Maximum Flow
 */

int main() {
    int N, M, Q;
    cin >> N >> M >> Q;
    MaxFlow G(N);
    map<pair<int,int>,int> mp;
    rep(i,0,M) {
        int A, B;
        cin >> A >> B;
        A--, B--;
        mp[{A,B}] = G.add_edge(A,B,1);
        mp[{B,A}] = G.add_edge(B,A,1);
    }
    int ANS = G.run(0,N-1);
    rep(i,0,Q) {
        int T, A, B;
        cin >> T >> A >> B;
        A--, B--;
        if (T == 1) {
            mp[{A,B}] = G.add_edge(A,B,1);
            mp[{B,A}] = G.add_edge(B,A,1);
            ANS += G.run(0,N-1);
        }
        else {
            int id1 = mp[{A,B}], id2 = mp[{B,A}];
            if (G.get_edge(id1).cap == 0 && G.get_edge(id2).cap == 1) {
                G.erase_edge(id1);
                G.erase_edge(id2);
                if (G.run(A,B) == 0) {
                    ANS--;
                    G.run(A,0,1);
                    G.run(N-1,B,1);
                }
            }
            else if (G.get_edge(id2).cap == 0 && G.get_edge(id1).cap == 1) {
                G.erase_edge(id1);
                G.erase_edge(id2);
                if (G.run(B,A) == 0) {
                    ANS--;
                    G.run(B,0,1);
                    G.run(N-1,A,1);
                }
            }
            else {
                G.erase_edge(id1);
                G.erase_edge(id2);
            }
        }
        cout << ANS << endl;
    }
}
accuracy: 0.2413793103448276
time_ms: 10
memory_kb: 3628
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;


struct Dinic {
public:
    const long long inf = 1e18;
    vector<int> dist; //sからの距離
    vector<int> iter; //どこまで調べたか

    struct edge {
        int to, rev; long long cap;
        edge(int t = 0, int r = 0, long long c = 0LL) : to(t), rev(r), cap(c) {}
    };

    int n;
    vector<vector<edge>> to;

    Dinic(int n_ = 1) : n(n_), to(n_), dist(n_), iter(n_) {}

    void addedge(int u, int v, long long cap) {//u->vにcapの容量
        int su = (int)to[u].size(), sv = (int)to[v].size();
        to[u].push_back({ v, sv, cap });
        to[v].push_back({ u, su, cap });
    }

    long long dfs(int v, int t, long long f) { //t: 終点, f: flow
        if (v == t) return f;
        int sv = (int)to[v].size();
        for (int& i = iter[v]; i < sv; i++) {
            edge& nv = to[v][i];
            if (dist[nv.to] <= dist[v] || nv.cap == 0) continue; //here
            long long nf = dfs(nv.to, t, min(f, nv.cap));
            if (nf > 0) {
                nv.cap -= nf;
                to[nv.to][nv.rev].cap += nf;
                return nf;
            }
        }
        return 0;
    }

    void bfs(int s) {
        dist.assign(n, -1);
        queue<int> q;
        q.push(s);
        dist[s] = 0;
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (auto nv : to[v]) {
                if (nv.cap > 0 && dist[nv.to] < 0) {
                    dist[nv.to] = dist[v] + 1;
                    q.push(nv.to);
                }
            }
        }
    }

    long long maxflow(int s, int t, int f) {//s:始点, t:終点
        long long res = 0, flow = 0;
        while (true) {
            bfs(s);
            if (dist[t] < 0) break;

            iter.assign(n, 0);
            while (flow = dfs(s, t, f)) {
                res += flow;
                f -= flow;
            }
            if (f == 0) return res;
        };
        return res;
    }
};


int main()
{
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    int n, e, q;
    cin >> n >> e >> q;

    Dinic dn(n);
    vii<pair<int, int>> vec(n, vi<pair<int, int>>(n, { -1, -1 }));
        
    rep(i, e) {
        int f, t;
        cin >> f >> t;
        f--, t--;
        if (f > t) swap(f, t);
        dn.addedge(f, t, 1);
        vec[f][t] = { dn.to[t].back().rev, dn.to[f].back().rev };
    }

    vi<int> ans;
    int flow = dn.maxflow(0, n - 1, n);
    rep(i, q) {
        int m, a, b;
        cin >> m >> a >> b;
        a--, b--;
        if (a > b) swap(a, b);
        if (m == 1) {
            if (vec[a][b].first == -1 ) {
                dn.addedge(a, b, 1);
                vec[a][b] = {dn.to[b].back().rev, dn.to[a].back().rev};
            }
            else {
                dn.to[a][vec[a][b].first].cap = 1;
                dn.to[b][vec[a][b].second].cap = 1;
            }
            flow += dn.maxflow(0, n - 1, n);
        }
        else {
            if (dn.to[a][vec[a][b].first].cap == 0) {
                int tf = dn.maxflow(a, b, 1);
                if (tf == 0) {
                    dn.maxflow(n - 1, b, 1);
                    dn.maxflow(a, 0, 1);
                    flow--;
                }
            }
            else if (dn.to[b][vec[a][b].second].cap == 0) {
                int tf = dn.maxflow(b, a, 1);
                if (tf == 0) {
                    dn.maxflow(n - 1, a, 1);
                    dn.maxflow(b, 0, 1);
                    flow--;
                }
            }
            
            dn.to[a][vec[a][b].first].cap = 0;
            dn.to[b][vec[a][b].second].cap = 0;
        }

        ans.push_back(flow);
    }

    for (auto elem : ans) cout << elem << endl;
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 6308
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;


struct Dinic {
public:
    const long long inf = 1e18;
    vector<int> dist; //sからの距離
    vector<int> iter; //どこまで調べたか

    struct edge {
        int to, rev; long long cap;
        edge(int t = 0, int r = 0, long long c = 0LL) : to(t), rev(r), cap(c) {}
    };

    int n;
    vector<vector<edge>> to;

    Dinic(int n_ = 1) : n(n_), to(n_), dist(n_), iter(n_) {}

    void addedge(int u, int v, long long cap) {//u->vにcapの容量
        int su = (int)to[u].size(), sv = (int)to[v].size();
        to[u].push_back({ v, sv, cap });
        to[v].push_back({ u, su, cap });
    }

    long long dfs(int v, int t, long long f) { //t: 終点, f: flow
        if (v == t) return f;
        int sv = (int)to[v].size();
        for (int& i = iter[v]; i < sv; i++) {
            edge& nv = to[v][i];
            if (dist[nv.to] <= dist[v] || nv.cap == 0) continue; //here
            long long nf = dfs(nv.to, t, min(f, nv.cap));
            if (nf > 0) {
                nv.cap -= nf;
                to[nv.to][nv.rev].cap += nf;
                return nf;
            }
        }
        return 0;
    }

    void bfs(int s) {
        dist.assign(n, -1);
        queue<int> q;
        q.push(s);
        dist[s] = 0;
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (auto nv : to[v]) {
                if (nv.cap > 0 && dist[nv.to] < 0) {
                    dist[nv.to] = dist[v] + 1;
                    q.push(nv.to);
                }
            }
        }
    }

    long long maxflow(int s, int t, int f) {//s:始点, t:終点
        long long res = 0, flow = 0;
        while (true) {
            bfs(s);
            if (dist[t] < 0) break;

            iter.assign(n, 0);
            while (flow = dfs(s, t, f)) {
                res += flow;
                f -= flow;
            }
            if (f == 0) return res;
        };
        return res;
    }
};


int main()
{
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    int n, e, q;
    cin >> n >> e >> q;

    Dinic dn(n);
    map<pair<int, int>, pair<int, int>> mp;
    rep(i, e) {
        int f, t;
        cin >> f >> t;
        f--, t--;
        if (f > t) swap(f, t);
        dn.addedge(f, t, 1);
        mp[{f, t}] = { dn.to[t].back().rev, dn.to[f].back().rev };
    }

    vi<int> ans;
    int flow = dn.maxflow(0, n - 1, n);
    rep(i, q) {
        int m, a, b;
        cin >> m >> a >> b;
        a--, b--;
        if (a > b) swap(a, b);
        if (m == 1) {
            if (!mp.count({ a, b })) {
                dn.addedge(a, b, 1);
                mp[{a, b}] = { dn.to[b].back().rev, dn.to[a].back().rev };
            }
            else {
                dn.to[a][mp[{a, b}].first].cap = 1;
                dn.to[b][mp[{a, b}].second].cap = 1;
            }
            flow += dn.maxflow(0, n - 1, n);
        }
        else {
            if (dn.to[a][mp[{a, b}].first].cap == 0) {
                int tf = dn.maxflow(a, b, 1);
                if (tf == 0) {
                    dn.maxflow(n - 1, b, 1);
                    dn.maxflow(a, 0, 1);
                    flow--;
                }
            }
            else if (dn.to[b][mp[{a, b}].second].cap == 0) {
                int tf = dn.maxflow(b, a, 1);
                if (tf == 0) {
                    dn.maxflow(n - 1, a, 1);
                    dn.maxflow(b, 0, 1);
                    flow--;
                }
            }
            
            dn.to[a][mp[{a, b}].first].cap = 0;
            dn.to[b][mp[{a, b}].second].cap = 0;                        
        }

        ans.push_back(flow);
    }

    for (auto elem : ans) cout << elem << endl;
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 5576
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;


struct Dinic {
private:
    long long inf = 1e18;
    vector<int> dist; //sからの距離
    vector<int> iter; //どこまで調べたか
public:
    struct edge {
        int to, rev; long long cap;
        edge(int t = 0, int r = 0, long long c = 0LL) : to(t), rev(r), cap(c) {}
    };

    int n;
    vector<vector<edge>> to;

    Dinic(int n_ = 1) : n(n_), to(n_), dist(n_), iter(n_) {}

    void addedge(int u, int v, long long cap) {//u->vにcapの容量
        int su = (int)to[u].size(), sv = (int)to[v].size();
        to[u].push_back({ v, sv, cap });
        to[v].push_back({ u, su, cap });
    }

    long long dfs(int v, int t, long long f) { //t: 終点, f: flow
        if (v == t) return f;
        int sv = (int)to[v].size();
        for (int& i = iter[v]; i < sv; i++) {
            edge& nv = to[v][i];
            if (dist[nv.to] <= dist[v] || nv.cap == 0) continue; //here
            long long nf = dfs(nv.to, t, min(f, nv.cap));
            if (nf > 0) {
                nv.cap -= nf;
                to[nv.to][nv.rev].cap += nf;
                return nf;
            }
        }
        return 0;
    }

    void bfs(int s) {
        dist.assign(n, -1);
        queue<int> q;
        q.push(s);
        dist[s] = 0;
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (auto nv : to[v]) {
                if (nv.cap > 0 && dist[nv.to] < 0) {
                    dist[nv.to] = dist[v] + 1;
                    q.push(nv.to);
                }
            }
        }
    }

    long long maxflow(int s, int t) {//s:始点, t:終点
        long long res = 0, flow = 0;
        while (true) {
            bfs(s);
            if (dist[t] < 0) break;

            iter.assign(n, 0);
            while (flow = dfs(s, t, inf)) res += flow;
        };
        return res;
    }
};


int main()
{
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    int n, e, q;
    cin >> n >> e >> q;

    set<pair<int, int>> st;
    rep(i, e) {
        int f, t;
        cin >> f >> t;
        f--, t--;
        if (f > t) swap(f, t);
        st.insert({ f, t });
    }

    vi<int> ans;
    Dinic dn(n);
    for (auto elem : st) dn.addedge(elem.first, elem.second, 1);
    int flow = dn.maxflow(0, n - 1);
    rep(i, q) {
        int m, a, b;
        cin >> m >> a >> b;
        a--, b--;
        if (a > b) swap(a, b);
        if (m == 1) {
            st.insert({ a, b });
            dn.addedge(a, b, 1);
            flow += dn.maxflow(0, n - 1);
        }
        else {
            st.erase({ a, b });
            Dinic nxt(n);
            swap(dn, nxt);
            for (auto elem : st) dn.addedge(elem.first, elem.second, 1);
            flow = dn.maxflow(0, n - 1);
        }

        ans.push_back(flow);
    }

    for (auto elem : ans) cout << elem << endl;
    return 0;
}
accuracy: 1
time_ms: 1930
memory_kb: 6168
final_rank: 11

code_snippet: #include <bits/stdc++.h>

struct Flow {
    int n;
    int cur_flow;
    std::vector<std::vector<bool>> ord, rev, exist;
    std::vector<bool> used;
    Flow(int n): n(n), cur_flow(0), ord(n, std::vector<bool>(n)), rev(n, std::vector<bool>(n)), exist(n, std::vector<bool>(n)), used(n) {}
    void add_edge(int u, int v) {
        assert(!exist[u][v]);
        assert(!exist[v][u]);
        exist[u][v] = exist[v][u] = true;
        ord[u][v] = ord[v][u] = true;
        rev[u][v] = rev[v][u] = false;
    }

    // {n - 1} -> u -> v -> 1
    void get_path(int u, int v) {
        assert(rev[u][v]);
        rev[u][v] = false;
        ord[v][u] = true;
        auto dfs = [&](auto self, int u, int sink) -> bool {
            if (u == sink) return true;
            used[u] = true;
            for (int v = 0; v < n; v++) {
                if (exist[u][v] && rev[u][v] && !used[v]) {
                    if (self(self, v, sink)) {
                        rev[u][v] = false;
                        ord[v][u] = true;
                        return true;
                    }
                }
            }
            return false;
        };
        used.assign(n, false);
        dfs(dfs, n - 1, u);
        used.assign(n, false);
        dfs(dfs, v, 0);
    }

    void delete_edge(int u, int v) {
        assert(exist[u][v]);
        assert(exist[v][u]);
        if ((ord[u][v] && ord[v][u]) || (rev[u][v] && rev[v][u])) {
            exist[u][v] = exist[v][u] = false;
            ord[u][v] = ord[v][u] = false;
            rev[u][v] = rev[v][u] = false;
            return;
        }
        // {n - 1} -> 0;
        (rev[u][v] ? get_path(u, v) : get_path(v, u));
        exist[u][v] = exist[v][u] = false;
        ord[u][v] = ord[v][u] = false;
        cur_flow--;
    }
    int flow() {
        int res = 0;
        while (true) {
            used.assign(n, false);
            int delta = dfs(0);
            if (delta == 0) break;
            res += delta;
        }
        return cur_flow += res;
    }
    int dfs(int u) {
        if (u == n - 1) return 1;
        used[u] = true;
        for (int v = 0; v < n; v++) {
            if (used[v]) continue;
            if (!exist[u][v]) continue;
            if (ord[u][v] || rev[u][v]) {
                if (dfs(v)) {
                    if (ord[u][v]) {
                        ord[u][v] = false;
                        rev[v][u] = true;
                    } else {
                        rev[u][v] = false;
                        ord[v][u] = true;
                    }
                    return 1;
                }
            }
        }
        return 0;
    }
};

int main() {
    int n, m, q;
    std::cin >> n >> m >> q;
    Flow flow(n);
    for (int i = 0; i < m; i++) {
        int u, v;
        std::cin >> u >> v;
        u--; v--;
        flow.add_edge(u, v);
    }
    while (q--) {
        int m, u, v;
        std::cin >> m >> u >> v;
        u--; v--;
        if (m == 1) {
            flow.add_edge(u, v);
        } else {
            flow.delete_edge(u, v);
        }
        std::cout << flow.flow() << '\n';
    }
}
accuracy: 1
time_ms: 400
memory_kb: 3632
final_rank: 1

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
using namespace zawa;

struct E {
    bool f{}, r{};
    E() = default;
    E(bool f, bool r) : f{f}, r{r} {}
    void flow() {
        f ^= 1;
        r ^= 1;
    }
    friend std::ostream& operator<<(std::ostream& os, const E& e) {
        if (!e.f and !e.r) os << 0;
        else if (e.f) os << 1;
        else os << 2;
        return os;
    }
};

const int N{510};
E g[N][N];

int n, m, q;

int through(int u, int v) {
    if (g[v][u].r) return 2;
    else if (g[u][v].f) return 1;
    else return 0;
}

bool dfsflow(int v, int t, std::vector<bool>& vis) {
    vis[v] = true;
    if (v == t) return true;
    for (int i{} ; i < n ; i++) if (!vis[i]) {
        int e{through(v, i)};
        if (e == 0) continue;
        if (!dfsflow(i, t, vis)) continue;
        if (e == 1) g[v][i].flow();
        else g[i][v].flow();
        return true;
    }
    return false;
}

bool dfselim(int v, int t, std::vector<bool>& vis) {
    vis[v] = true;
    if (v == t) return true;
    for (int i{} ; i < n ; i++) if (!vis[i]) {
        int e{through(v, i)};
        // std::cout << '(' << v << ',' << i << ')' << " is " << e << std::endl;
        if (e != 2) continue;
        if (!dfselim(i, t, vis)) continue;
        g[i][v].flow();
        return true;
    }
    return false;
}

bool flow(int s, int t) {
    std::vector<bool> vis(n);
    return dfsflow(s, t, vis);
}

bool elim(int s, int t) {
    // std::cerr << "eliminate " << s << ' ' << t << std::endl;
    std::vector<bool> vis(n);
    return dfselim(s, t, vis);
}

int main() {
    SetFastIO();

    std::cin >> n >> m >> q;
    for (int i{} ; i < n ; i++) for (int j{} ; j < n ; j++) g[i][j] = E{};
    for (int _{} ; _ < m ; _++) {
        int f, t; std::cin >> f >> t;
        f--; t--;
        g[f][t].f = true;
        g[t][f].f = true;
    }

    int ans{};
    while (flow(0, n - 1)) ans++;

    for (int _{} ; _ < q ; _++) {
        int t, a, b; std::cin >> t >> a >> b;
        // std::cout << t << ' ' << a << ' ' << b << std::endl;
        a--; b--;
        if (t == 1) {
            assert(!g[a][b].f and !g[b][a].f);
            assert(!g[a][b].r and !g[b][a].r);
            g[a][b].f = true;
            g[b][a].f = true;
            ans += flow(0, n - 1);
        }
        else if (t == 2) {
            if (g[a][b].f and g[b][a].f) {
                // std::cerr << "type " << 1 << std::endl;
                ;
            }
            else if (g[a][b].r and g[b][a].r) {
                // std::cerr << "type " << 2 << std::endl;
                g[a][b].flow();
                g[b][a].flow();
            }
            else if (g[a][b].r) {
                if (!flow(a, b)) {
                    assert(elim(n - 1, b));
                    g[a][b].flow();
                    assert(elim(a, 0));
                    ans--;
                }
                else {
                    g[a][b].flow();
                }
            }
            else if (g[b][a].r) {
                // std::cerr << "type " << 4 << std::endl;
                if (!flow(b, a)) {
                    assert(elim(n - 1, a));
                    g[b][a].flow();
                    assert(elim(b, 0));
                    ans--;
                }
                else {
                    g[b][a].flow();
                }
            }
            else {
                assert(!"aaa");
            }
            assert(g[a][b].f and g[b][a].f);
            assert(!g[a][b].r and !g[a][b].r);
            g[a][b].f = g[b][a].f = false;
        }
        else {
            assert(false);
        }
        std::cout << ans << std::endl;
    }
}
accuracy: 1
time_ms: 340
memory_kb: 3916
final_rank: 2

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
using namespace zawa;

struct E {
    bool exist;
    bool f, revf;
    E() : exist{false}, f{false}, revf{false} {}
    void on() {
        assert(!exist);
        exist = f = true;
    }
    void off() {
        assert(exist);
        exist = f = revf = false;
    }
    void flip() {
        f ^= 1;
        revf ^= 1;
    }
    bool flowed() const {
        return exist and !f;
    }
};

enum state {
    uv,
    vu,
    cannot, 
};

int main() {
    SetFastIO();

    int n, m, q; std::cin >> n >> m >> q;
    std::vector g(n, std::vector<E>(n));
    
    for (int _{} ; _ < m ; _++) {
        int a, b; std::cin >> a >> b;
        a--; b--;
        g[a][b].on();
        g[b][a].on();
    }

    auto can{[&](int u, int v) -> state {
        if (g[v][u].exist and g[v][u].revf) return vu;
        else if (g[u][v].exist and g[u][v].f) return uv;
        else return cannot;
    }};

    auto flow{[&](int s, int t) -> bool {
        std::vector<bool> vis(n);  
        auto dfs{[&](auto dfs, int v) -> bool {
            vis[v] = true;
            if (v == t) return true;
            for (int x{} ; x < n ; x++) if (!vis[x]) {
                auto e{can(v, x)}; 
                if (e == cannot) continue;
                if (dfs(dfs, x)) {
                    if (e == uv) g[v][x].flip();
                    else if (e == vu) g[x][v].flip();
                    return true;
                }
            }
            return false;
        }};
        return dfs(dfs, s);
    }};

    int ans{};
    while (flow(0, n - 1)) ans++;

    for (int _{} ; _ < q ; _++) {
        int t, a, b; std::cin >> t >> a >> b;
        a--; b--;
        if (t == 1) {
            g[a][b].on();
            g[b][a].on();
            ans += flow(0, n - 1);
        }
        else if (t == 2) {
            assert(g[a][b].exist and g[b][a].exist);
            if (!g[a][b].flowed() and !g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed() and g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed()) {
                if (!flow(a, b)) {
                    ans--;
                    flow(n - 1, b);
                    g[a][b].flip();
                    flow(a, 0);
                }
            } 
            else if (g[b][a].flowed()) {
                if (!flow(b, a)) {
                    ans--;
                    flow(n - 1, a);
                    g[b][a].flip();
                    flow(b, 0);
                }
            }
            else {
                assert(false);
            }
            g[a][b].off();
            g[b][a].off();
        }
        else {
            assert(false);
        }
        std::cout << ans << '\n';
    }
}
accuracy: 0.15517241379310345
time_ms: 210
memory_kb: 3700
final_rank: 17

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
using namespace zawa;

struct E {
    bool exist;
    bool f, revf;
    E() : exist{false}, f{false}, revf{false} {}
    void on() {
        assert(!exist);
        exist = f = true;
    }
    void off() {
        assert(exist);
        exist = f = revf = false;
    }
    void flip() {
        f ^= 1;
        revf ^= 1;
    }
    bool flowed() const {
        return exist and !f;
    }
};

enum state {
    uv,
    vu,
    cannot, 
};

int main() {
    SetFastIO();

    int n, m, q; std::cin >> n >> m >> q;
    std::vector g(n, std::vector<E>(n));
    
    for (int _{} ; _ < m ; _++) {
        int a, b; std::cin >> a >> b;
        a--; b--;
        g[a][b].on();
        g[b][a].on();
    }

    auto can{[&](int u, int v) -> state {
        if (g[v][u].exist and g[v][u].revf) return vu;
        else if (g[u][v].exist and g[u][v].f) return uv;
        else return cannot;
    }};

    auto flow{[&](int s, int t) -> bool {
        std::vector<bool> vis(n);  
        auto dfs{[&](auto dfs, int v) -> bool {
            vis[v] = true;
            if (v == t) return true;
            for (int x{} ; x < n ; x++) if (!vis[x]) {
                auto e{can(v, x)}; 
                if (e == cannot) continue;
                if (dfs(dfs, x)) {
                    if (e == uv) g[v][x].flip();
                    else if (e == vu) g[x][v].flip();
                    return true;
                }
            }
            return false;
        }};
        return dfs(dfs, s);
    }};

    int ans{};
    while (flow(0, n - 1)) ans++;

    for (int _{} ; _ < q ; _++) {
        int t, a, b; std::cin >> t >> a >> b;
        a--; b--;
        if (t == 1) {
            g[a][b].on();
            g[b][a].on();
            ans += flow(0, n - 1);
        }
        else if (t == 2) {
            assert(g[a][b].exist and g[b][a].exist);
            if (!g[a][b].flowed() and !g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed() and g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed()) {
                if (!flow(a, b)) {
                    ans--;
                    assert(flow(n - 1, b));
                    assert(g[a][b].flowed());
                    g[a][b].flip();
                    assert(flow(a, 0));
                }
            } 
            else if (g[b][a].flowed()) {
                if (!flow(b, a)) {
                    ans--;
                    assert(flow(n - 1, a));
                    assert(g[b][a].flowed());
                    g[b][a].flip();
                    assert(flow(b, 0));
                }
            }
            else {
                assert(false);
            }
            g[a][b].off();
            g[b][a].off();
        }
        else {
            assert(false);
        }
        std::cout << ans << '\n';
    }
}
accuracy: 0.15517241379310345
time_ms: 210
memory_kb: 3760
final_rank: 18

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
using namespace zawa;

struct E {
    bool exist;
    bool f, revf;
    E() : exist{false}, f{false}, revf{false} {}
    void on() {
        assert(!exist);
        exist = f = true;
    }
    void off() {
        assert(exist);
        exist = f = revf = false;
    }
    void flip() {
        f ^= 1;
        revf ^= 1;
    }
    bool flowed() const {
        return exist and !f;
    }
};

enum state {
    uv,
    vu,
    cannot, 
};

int main() {
    SetFastIO();

    int n, m, q; std::cin >> n >> m >> q;
    std::vector g(n, std::vector<E>(n));
    
    for (int _{} ; _ < m ; _++) {
        int a, b; std::cin >> a >> b;
        a--; b--;
        g[a][b].on();
        g[b][a].on();
    }

    auto can{[&](int u, int v) -> state {
        if (g[v][u].exist and g[v][u].revf) return vu;
        else if (g[u][v].exist and g[u][v].f) return uv;
        else return cannot;
    }};

    auto flow{[&](int s, int t) -> bool {
        std::vector<bool> vis(n);  
        auto dfs{[&](auto dfs, int v) -> bool {
            vis[v] = true;
            if (v == t) return true;
            for (int x{} ; x < n ; x++) if (!vis[x]) {
                auto e{can(v, x)}; 
                if (e == cannot) continue;
                if (dfs(dfs, x)) {
                    if (e == uv) g[v][x].flip();
                    else if (e == vu) g[x][v].flip();
                    return true;
                }
            }
            return false;
        }};
        return dfs(dfs, s);
    }};

    int ans{};
    while (flow(0, n - 1)) ans++;

    for (int _{} ; _ < q ; _++) {
        int t, a, b; std::cin >> t >> a >> b;
        a--; b--;
        if (t == 1) {
            g[a][b].on();
            g[b][a].on();
            ans += flow(0, n - 1);
        }
        else if (t == 2) {
            assert(g[a][b].exist and g[b][a].exist);
            if (!g[a][b].flowed() and !g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed() and g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed()) {
                if (!flow(a, b)) {
                    ans--;
                    assert(flow(n - 1, b));
                    g[a][b].flip();
                    assert(flow(a, 0));
                }
            } 
            else if (g[b][a].flowed()) {
                if (!flow(b, a)) {
                    ans--;
                    assert(flow(n - 1, a));
                    g[b][a].flip();
                    assert(flow(b, 0));
                }
            }
            else {
                assert(false);
            }
            g[a][b].off();
            g[b][a].off();
        }
        else {
            assert(false);
        }
        std::cout << ans << '\n';
    }
}
accuracy: 0.15517241379310345
time_ms: 200
memory_kb: 3704
final_rank: 16

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
using namespace zawa;

struct E {
    bool exist;
    bool f, revf;
    E() : exist{false}, f{false}, revf{false} {}
    void on() {
        assert(!exist);
        exist = f = true;
    }
    void off() {
        assert(exist);
        exist = f = revf = false;
    }
    void flip() {
        f ^= 1;
        revf ^= 1;
    }
    bool flowed() const {
        return exist and !f;
    }
};

enum state {
    uv,
    vu,
    cannot, 
};

int main() {
    SetFastIO();

    int n, m, q; std::cin >> n >> m >> q;
    std::vector g(n, std::vector<E>(n));
    
    for (int _{} ; _ < m ; _++) {
        int a, b; std::cin >> a >> b;
        a--; b--;
        g[a][b].on();
        g[b][a].on();
    }

    auto can{[&](int u, int v) -> state {
        if (g[u][v].exist and g[u][v].f) return uv;
        else if (g[v][u].exist and g[v][u].revf) return vu;
        else return cannot;
    }};

    auto flow{[&](int s, int t) -> bool {
        std::vector<bool> vis(n);  
        auto dfs{[&](auto dfs, int v) -> bool {
            vis[v] = true;
            if (v == t) return true;
            for (int x{} ; x < n ; x++) if (!vis[x]) {
                auto e{can(v, x)}; 
                if (e == cannot) continue;
                if (dfs(dfs, x)) {
                    if (e == uv) g[v][x].flip();
                    else if (e == vu) g[x][v].flip();
                    return true;
                }
            }
            return false;
        }};
        return dfs(dfs, s);
    }};

    int ans{};
    while (flow(0, n - 1)) ans++;

    for (int _{} ; _ < q ; _++) {
        int t, a, b; std::cin >> t >> a >> b;
        a--; b--;
        if (t == 1) {
            g[a][b].on();
            g[b][a].on();
            ans += flow(0, n - 1);
        }
        else if (t == 2) {
            assert(g[a][b].exist and g[b][a].exist);
            if (!g[a][b].flowed() and !g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed() and g[b][a].flowed()) {
                ;
            }
            else if (g[a][b].flowed()) {
                if (!flow(a, b)) {
                    ans--;
                    assert(flow(n - 1, b));
                    g[a][b].flip();
                    assert(flow(a, 0));
                }
            } 
            else if (g[b][a].flowed()) {
                if (!flow(b, a)) {
                    ans--;
                    assert(flow(n - 1, a));
                    g[b][a].flip();
                    assert(flow(b, 0));
                }
            }
            else {
                assert(false);
            }
            g[a][b].off();
            g[b][a].off();
        }
        else {
            assert(false);
        }
        std::cout << ans << '\n';
    }
}
accuracy: 0.15517241379310345
time_ms: 240
memory_kb: 3740
final_rank: 20

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
using namespace zawa;

struct E {
    bool exist;
    bool f, revf;
    E() : exist{false}, f{false}, revf{false} {}
    void on() {
        assert(!exist);
        exist = f = true;
    }
    void off() {
        assert(exist);
        exist = f = revf = false;
    }
    void flip() {
        f ^= 1;
        revf ^= 1;
    }
    bool flowed() const {
        return exist and !f;
    }
};

enum state {
    uv,
    vu,
    cannot, 
};

int main() {
    SetFastIO();

    int n, m, q; std::cin >> n >> m >> q;
    std::vector g(n, std::vector<E>(n));
    
    for (int _{} ; _ < m ; _++) {
        int a, b; std::cin >> a >> b;
        a--; b--;
        g[a][b].on();
        g[b][a].on();
    }

    auto can{[&](int u, int v) -> state {
        if (g[u][v].exist and g[u][v].f) return uv;
        else if (g[v][u].exist and g[v][u].revf) return vu;
        else return cannot;
    }};

    auto flow{[&](int s, int t) -> bool {
        std::vector<bool> vis(n);  
        auto dfs{[&](auto dfs, int v) -> bool {
            vis[v] = true;
            if (v == t) return true;
            for (int x{} ; x < n ; x++) if (!vis[x]) {
                auto e{can(v, x)}; 
                if (e == cannot) continue;
                if (dfs(dfs, x)) {
                    if (e == uv) g[v][x].flip();
                    else if (e == vu) g[x][v].flip();
                    return true;
                }
            }
            return false;
        }};
        return dfs(dfs, s);
    }};

    int ans{};
    while (flow(0, n - 1)) ans++;

    for (int _{} ; _ < q ; _++) {
        int t, a, b; std::cin >> t >> a >> b;
        a--; b--;
        if (t == 1) {
            g[a][b].on();
            g[b][a].on();
            ans += flow(0, n - 1);
        }
        else if (t == 2) {
            assert(g[a][b].exist and g[b][a].exist);
            if (!(g[a][b].flowed() ^ g[b][a].flowed())) {
                ;
            }
            else if (g[a][b].flowed()) {
                if (!flow(a, b)) {
                    ans--;
                    assert(flow(n - 1, b));
                    g[a][b].flip();
                    assert(flow(a, 0));
                }
            } 
            else if (g[b][a].flowed()) {
                if (!flow(b, a)) {
                    ans--;
                    assert(flow(n - 1, a));
                    g[b][a].flip();
                    assert(flow(b, 0));
                }
            }
            else {
                assert(false);
            }
            g[a][b].off();
            g[b][a].off();
        }
        else {
            assert(false);
        }
        std::cout << ans << '\n';
    }
}
accuracy: 0.15517241379310345
time_ms: 240
memory_kb: 3704
final_rank: 19

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

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

bool is_end = false;

/*
目的：max flow を求める
特徴：max_flow を呼び出したのちに、add_edge が可能
(max_flow は「前回の状態からどれだけ流せるか」を返すので、flow を流す場所 s, t を変えるとおかしな結果になる)
*/
template<class flow_t = long long>
struct FordFulkerson
{
	
	int siz;
	vector<vector<flow_t>> graph;
	vector<bool> used;
	
	FordFulkerson(int n) : siz(n), graph(n, vector<flow_t>(n, 0)), used(siz, false) { }
	
	void add_edge(int from, int to, flow_t cap)
	{
		assert(from < siz && to < siz);
		graph[from][to] += cap;
	}
	
	flow_t dfs(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (cap > 0 && !used[to])
			{
				flow_t f = dfs(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	// max flow on s -> t
	flow_t max_flow(int s, int t)
	{
		flow_t flow = 0;
		flow_t INF = 1e9;  // INF の上限値に注意
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs(s, t, INF);
			flow += f;
			
			if (f == 0) {return flow;}
		}
		// 絶対に到達しないはず
		return 0;
	}
	
	flow_t dfs2(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (graph[v][to] - graph[to][v] > 0 && !used[to])
			{
				flow_t f = dfs2(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	flow_t limit_flow(int s, int t, int limit)
	{
		flow_t flow = 0;
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs(s, t, limit);
			flow += f;
			limit -= f;
			
			if (f == 0) {return flow;}
		}
		return 0;
	}
	
	void loosen(int s, int t)
	{
		used.assign(siz, false);
		
		vector<vector<bool>> isneed(siz, vector<bool>(siz, false));
		queue<int> que;
		que.emplace(s);
		used[s] = true;
		
		while (!que.empty())
		{
			int v = que.front();
			que.pop();
			
			for (int nv = 0; nv < siz; ++nv)
			{
				if (graph[v][nv] < graph[nv][v])
				{
					isneed[v][nv] = isneed[nv][v] = true;
					if (used[nv]) {continue;}
					used[nv] = true;
					que.emplace(nv);
				}
			}
		}
		
		for (int i = 0; i < siz; ++i)
		{
			for (int j = i; j < siz; ++j)
			{
				if (isneed[i][j]) continue;
				int mid = (graph[i][j] + graph[j][i]) / 2;
				graph[i][j] = graph[j][i] = mid;
			}
		}
		
		return;
	}
	
};

void output(FordFulkerson<int> &g)
{
	int n = g.siz;
	
	cout << "cap" << endl;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			cout << g.graph[i][j] << " ";
		}
		cout << endl;
	}
	
	cout << "flow" << endl;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			int f = (g.graph[j][i]) / 2;
			cout << f << " ";
		}
		cout << endl;
	}
	
	cout << endl;
	
	return;
}

void calc()
{
	int N, E, Q; cin >> N >> E >> Q;
	FordFulkerson<int> g(N);
	
	for (int i = 0; i < E; ++i)
	{
		int f, t; cin >> f >> t;
		f--, t--;
		g.add_edge(f, t, 1);
		g.add_edge(t ,f, 1);
	}
	
	int S = 0, T = N-1;
	int sum = g.max_flow(S, T);
	
	for (int q = 0; q < Q; ++q)
	{
		int m, a, b; cin >> m >> a >> b;
		a--, b--;
		
		if (m == 1)
		{
			// connect (a, b)
			g.add_edge(a, b, 1);
			g.add_edge(b, a, 1);
			sum += g.max_flow(S, T);
		}
		else
		{
			assert(g.graph[a][b] + g.graph[b][a] > 0);
			// cut (a, b)
			if (g.graph[a][b] == 0)
			{
				// S -> a -> b -> T flow exists
				g.graph[a][b] = g.graph[b][a] = 0;
				int f = g.limit_flow(a, b, 1);
				
				if (f == 0)
				{
					sum -= 1;
					f = g.limit_flow(T, b, 1);
					assert(T == b || f == 1);
					f = g.limit_flow(a, S, 1);
					assert(S == a || f == 1);
				}
				else
				{
					;
				}
			}
			else if (g.graph[b][a] == 0)
			{
				// S -> b -> a -> T flow exists
				g.graph[a][b] = g.graph[b][a] = 0;
				int f = g.limit_flow(b, a, 1);
				
				if (f == 0)
				{
					sum -= 1;
					f = g.limit_flow(T, a, 1);
					assert(T == a || f == 1);
					f = g.limit_flow(b, S, 1);
					assert(S == b || f == 1);
				}
				else
				{
					;
				}
			}
			else
			{
				g.graph[a][b] = g.graph[b][a] = 0;
			}
			
		}
		
		cout << sum << endl;
		// g.loosen(S, T);
		
		// cout << m << " " << a << " " << b << endl;
		// output(g);
		
	}
	
	
	return;
}

int main()
{
	calc();
	
	return 0;
}
accuracy: 1
time_ms: 600
memory_kb: 4456
final_rank: 3

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

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

bool is_end = false;

/*
目的：max flow を求める
特徴：max_flow を呼び出したのちに、add_edge が可能
(max_flow は「前回の状態からどれだけ流せるか」を返すので、flow を流す場所 s, t を変えるとおかしな結果になる)
*/
template<class flow_t = long long>
struct FordFulkerson
{
	
	int siz;
	vector<vector<flow_t>> graph;
	vector<bool> used;
	
	FordFulkerson(int n) : siz(n), graph(n, vector<flow_t>(n, 0)), used(siz, false) { }
	
	void add_edge(int from, int to, flow_t cap)
	{
		assert(from < siz && to < siz);
		graph[from][to] += cap;
	}
	
	flow_t dfs(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (cap > 0 && !used[to])
			{
				flow_t f = dfs(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	// max flow on s -> t
	flow_t max_flow(int s, int t)
	{
		flow_t flow = 0;
		flow_t INF = 1e9;  // INF の上限値に注意
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs(s, t, INF);
			flow += f;
			
			if (f == 0) {return flow;}
		}
		// 絶対に到達しないはず
		return 0;
	}
	
	flow_t dfs2(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (graph[v][to] - graph[to][v] > 0 && !used[to])
			{
				flow_t f = dfs2(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	flow_t limit_flow(int s, int t, int limit)
	{
		flow_t flow = 0;
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs2(s, t, limit);
			flow += f;
			limit -= f;
			
			if (f == 0) {return flow;}
		}
		return 0;
	}
	
	void loosen(int s, int t)
	{
		used.assign(siz, false);
		
		vector<vector<bool>> isneed(siz, vector<bool>(siz, false));
		queue<int> que;
		que.emplace(s);
		used[s] = true;
		
		while (!que.empty())
		{
			int v = que.front();
			que.pop();
			
			for (int nv = 0; nv < siz; ++nv)
			{
				if (graph[v][nv] < graph[nv][v])
				{
					isneed[v][nv] = isneed[nv][v] = true;
					if (used[nv]) {continue;}
					used[nv] = true;
					que.emplace(nv);
				}
			}
		}
		
		for (int i = 0; i < siz; ++i)
		{
			for (int j = i; j < siz; ++j)
			{
				if (isneed[i][j]) continue;
				int mid = (graph[i][j] + graph[j][i]) / 2;
				graph[i][j] = graph[j][i] = mid;
			}
		}
		
		return;
	}
	
};

void output(FordFulkerson<int> &g)
{
	int n = g.siz;
	
	cout << "cap" << endl;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			cout << g.graph[i][j] << " ";
		}
		cout << endl;
	}
	
	cout << "flow" << endl;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			int f = (g.graph[j][i]) / 2;
			cout << f << " ";
		}
		cout << endl;
	}
	
	cout << endl;
	
	return;
}

void calc()
{
	int N, E, Q; cin >> N >> E >> Q;
	FordFulkerson<int> g(N);
	
	for (int i = 0; i < E; ++i)
	{
		int f, t; cin >> f >> t;
		f--, t--;
		g.add_edge(f, t, 1);
		g.add_edge(t ,f, 1);
	}
	
	int S = 0, T = N-1;
	int sum = g.max_flow(S, T);
	
	for (int q = 0; q < Q; ++q)
	{
		int m, a, b; cin >> m >> a >> b;
		a--, b--;
		
		if (m == 1)
		{
			// connect (a, b)
			g.add_edge(a, b, 1);
			g.add_edge(b, a, 1);
			sum += g.max_flow(S, T);
		}
		else
		{
			assert(g.graph[a][b] + g.graph[b][a] > 0);
			// cut (a, b)
			if (g.graph[a][b] == 0)
			{
				// S -> a -> b -> T flow exists
				int f = g.limit_flow(T, b, 1);
				assert(T == b || f == 1);
				f = g.limit_flow(a, S, 1);
				assert(S == a || f == 1);
				
				g.graph[b][a] -= 1;
				g.graph[a][b] += 1;
				sum -= 1;
			}
			if (g.graph[b][a] == 0)
			{
				// S -> b -> a -> T flow exists
				int f = g.limit_flow(T, a, 1);
				assert(T == a || f == 1);
				f = g.limit_flow(b, S, 1);
				assert(S == b || f == 1);
				
				g.graph[a][b] -= 1;
				g.graph[b][a] += 1;
				sum -= 1;
			}
			g.graph[a][b] = g.graph[b][a] = 0;
			sum += g.max_flow(S, T);
		}
		
		cout << sum << endl;
		g.loosen(S, T);
		
		// cout << m << " " << a << " " << b << endl;
		// output(g);
		
	}
	
	
	return;
}

int main()
{
	calc();
	
	return 0;
}
accuracy: 1
time_ms: 1410
memory_kb: 4520
final_rank: 8

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

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

bool is_end = false;

/*
目的：max flow を求める
特徴：max_flow を呼び出したのちに、add_edge が可能
(max_flow は「前回の状態からどれだけ流せるか」を返すので、flow を流す場所 s, t を変えるとおかしな結果になる)
*/
template<class flow_t = long long>
struct FordFulkerson
{
	
	int siz;
	vector<vector<flow_t>> graph;
	vector<bool> used;
	
	FordFulkerson(int n) : siz(n), graph(n, vector<flow_t>(n, 0)), used(siz, false) { }
	
	void add_edge(int from, int to, flow_t cap)
	{
		assert(from < siz && to < siz);
		graph[from][to] += cap;
	}
	
	flow_t dfs(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (cap > 0 && !used[to])
			{
				flow_t f = dfs(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	// max flow on s -> t
	flow_t max_flow(int s, int t)
	{
		flow_t flow = 0;
		flow_t INF = 1e9;  // INF の上限値に注意
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs(s, t, INF);
			flow += f;
			
			if (f == 0) {return flow;}
		}
		// 絶対に到達しないはず
		return 0;
	}
	
	flow_t dfs2(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (graph[v][to] - graph[to][v] > 0 && !used[to])
			{
				flow_t f = dfs2(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	flow_t limit_flow(int s, int t, int limit)
	{
		flow_t flow = 0;
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs2(s, t, limit);
			flow += f;
			limit -= f;
			
			if (f == 0) {return flow;}
		}
		return 0;
	}
	
};

void output(FordFulkerson<int> &g)
{
	int n = g.siz;
	
	cout << "cap" << endl;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			cout << g.graph[i][j] << " ";
		}
		cout << endl;
	}
	
	cout << "flow" << endl;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			int f = (g.graph[j][i]) / 2;
			cout << f << " ";
		}
		cout << endl;
	}
	
	cout << endl;
	
	return;
}

void calc()
{
	int N, E, Q; cin >> N >> E >> Q;
	FordFulkerson<int> g(N);
	
	for (int i = 0; i < E; ++i)
	{
		int f, t; cin >> f >> t;
		f--, t--;
		g.add_edge(f, t, 1);
		g.add_edge(t ,f, 1);
	}
	
	int S = 0, T = N-1;
	int sum = g.max_flow(S, T);
	
	for (int q = 0; q < Q; ++q)
	{
		int m, a, b; cin >> m >> a >> b;
		a--, b--;
		
		if (m == 1)
		{
			// connect (a, b)
			g.add_edge(a, b, 1);
			g.add_edge(b, a, 1);
			sum += g.max_flow(S, T);
		}
		else
		{
			assert(g.graph[a][b] + g.graph[b][a] > 0);
			// cut (a, b)
			if (g.graph[a][b] == 0)
			{
				// S -> a -> b -> T flow exists
				int f = g.limit_flow(T, b, 1);
				assert(T == b || f == 1);
				f = g.limit_flow(a, S, 1);
				assert(S == a || f == 1);
				
				g.graph[b][a] -= 1;
				g.graph[a][b] += 1;
				sum -= 1;
			}
			if (g.graph[b][a] == 0)
			{
				// S -> b -> a -> T flow exists
				int f = g.limit_flow(T, a, 1);
				assert(T == a || f == 1);
				f = g.limit_flow(b, S, 1);
				assert(S == b || f == 1);
				
				g.graph[a][b] -= 1;
				g.graph[b][a] += 1;
				sum -= 1;
			}
			g.graph[a][b] = g.graph[b][a] = 0;
			sum += g.max_flow(S, T);
		}
		
		cout << sum << endl;
	}
	
	
	return;
}

int main()
{
	calc();
	
	return 0;
}
accuracy: 0.3275862068965517
time_ms: 110
memory_kb: 4460
final_rank: 12

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

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

bool is_end = false;

/*
目的：max flow を求める
特徴：max_flow を呼び出したのちに、add_edge が可能
(max_flow は「前回の状態からどれだけ流せるか」を返すので、flow を流す場所 s, t を変えるとおかしな結果になる)
*/
template<class flow_t = long long>
struct FordFulkerson
{
	
	int siz;
	vector<vector<flow_t>> graph;
	vector<bool> used;
	
	FordFulkerson(int n) : siz(n), graph(n, vector<flow_t>(n, 0)), used(siz, false) { }
	
	void add_edge(int from, int to, flow_t cap)
	{
		assert(from < siz && to < siz);
		graph[from][to] += cap;
	}
	
	flow_t dfs(int v, int target, flow_t flow)
	{
		if (v == target) {return flow;}
		used[v] = true;
		
		for (int to = 0; to < siz; ++to)
		{
			flow_t cap = graph[v][to];
			if (cap > 0 && !used[to])
			{
				flow_t f = dfs(to, target, min(flow, cap));
				if (f > 0)
				{
					graph[v][to] -= f;
					graph[to][v] += f;
					return f;
				}
			}
		}
		return 0;
	}
	
	// max flow on s -> t
	flow_t max_flow(int s, int t)
	{
		flow_t flow = 0;
		flow_t INF = 1e9;  // INF の上限値に注意
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs(s, t, INF);
			flow += f;
			
			if (f == 0) {return flow;}
		}
		// 絶対に到達しないはず
		return 0;
	}
	
	flow_t limit_flow(int s, int t, int limit)
	{
		flow_t flow = 0;
		flow_t INF = 1e9;
		while (true)
		{
			used.assign(siz, false);
			flow_t f = dfs(s, t, limit);
			flow += f;
			limit -= f;
			
			if (f == 0) {return flow;}
		}
		return 0;
	}
	
};

void calc()
{
	int N, E, Q; cin >> N >> E >> Q;
	FordFulkerson<int> g(N);
	
	for (int i = 0; i < E; ++i)
	{
		int f, t; cin >> f >> t;
		f--, t--;
		g.add_edge(f, t, 1);
		g.add_edge(t ,f, 1);
	}
	
	int S = 0, T = N-1;
	int sum = g.max_flow(S, T);
	
	for (int q = 0; q < Q; ++q)
	{
		int m, a, b; cin >> m >> a >> b;
		a--, b--;
		
		if (m == 1)
		{
			// connect (a, b)
			g.add_edge(a, b, 1);
			g.add_edge(b, a, 1);
			sum += g.max_flow(S, T);
		}
		else
		{
			// cut (a, b)
			if (g.graph[a][b] == 0)
			{
				// S -> a -> b -> T flow exists
				int f = g.limit_flow(T, b, 1);
				assert(f == 1);
				f = g.limit_flow(a, S, 1);
				assert(f == 1);
				
				g.graph[b][a] -= 1;
				g.graph[a][b] += 1;
				sum -= 1;
			}
			if (g.graph[b][a] == 0)
			{
				// S -> b -> a -> T flow exists
				int f = g.limit_flow(T, a, 1);
				assert(f == 1);
				f = g.limit_flow(b, S, 1);
				assert(f == 1);
				
				g.graph[a][b] -= 1;
				g.graph[b][a] += 1;
				sum -= 1;
			}
			g.graph[a][b] = g.graph[b][a] = 0;
			sum += g.max_flow(S, T);
		}
		
		cout << sum << endl;
	}
	
	
	return;
}

int main()
{
	calc();
	
	return 0;
}
accuracy: 0.2413793103448276
time_ms: 100
memory_kb: 4352
final_rank: 15

code_snippet: #include <algorithm>
#include <limits>
#include <queue>
#include <vector>

namespace luz {

  class MaxFlowGraph {
    using usize = std::size_t;
    using Cap = long long;

    struct Edge {
      usize to, rev;
      Cap cap;
    };

    usize n;
    std::vector< Cap > min_cost;
    std::vector< usize > iter;
    std::vector< std::vector< Edge > > g;

    bool build_augment_path(usize s, usize t) {
      min_cost.assign(n, -1);
      std::queue< usize > que;

      min_cost[s] = 0;
      que.push(s);

      while (not que.empty() and min_cost[t] == -1) {
        usize v = que.front();
        que.pop();

        for (const auto &e: g[v]) {
          if (e.cap > 0 and min_cost[e.to] == -1) {
            min_cost[e.to] = min_cost[v] + 1;
            que.push(e.to);
          }
        }
      }

      return min_cost[t] != -1;
    }

    Cap find_augment_path(usize v, usize t, Cap flow_limit) {
      if (v == t) return flow_limit;

      for (usize &i = iter[v]; i < g[v].size(); i++) {
        Edge &e = g[v][i];

        if (e.cap > 0 and min_cost[v] + 1 == min_cost[e.to]) {
          Cap d = find_augment_path(e.to, t, std::min(flow_limit, e.cap));

          if (d > 0) {
            e.cap -= d;
            g[e.to][e.rev].cap += d;
            return d;
          }
        }
      }

      return 0;
    }

   public:
    const Cap INF = std::numeric_limits< Cap >::max();

    explicit MaxFlowGraph(usize n): n(n), g(n) {}

    usize add_directed_edge(usize from, usize to, Cap cap) {
      // assert(from < n and to < n and from != to);
      usize idx = g[from].size();
      g[from].emplace_back(Edge { to, g[to].size(), cap });
      g[to].emplace_back(Edge { from, idx, 0 });
      return idx;
    }

    // 1. O(n^2 m) in general
    // 2. other case: see docs "dinic-time-complexity.pdf"
    Cap max_flow(usize s, usize t, Cap flow_limit) {
      // assert(s < n and t < n and s != t);
      Cap flow = 0, add = 0;

      while (build_augment_path(s, t) and flow < flow_limit) {
        iter.assign(n, 0);

        do {
          add = find_augment_path(s, t, flow_limit - add);
          flow += add;
        } while (add > 0);
      }

      return flow;
    }

    Cap max_flow(usize s, usize t) {
      return max_flow(s, t, INF);
    }

    Cap link(usize s, usize t, usize from, usize idx, Cap f){
      g[from][idx].cap += f;
      return max_flow(s, t, f);
    }

    Cap cut(usize s, usize t, usize from, usize idx){
      auto &e = g[from][idx];
      usize to = e.to;
      Cap rem = g[to][e.rev].cap;

      if(rem == 0) return e.cap = 0;
      e.cap = g[to][e.rev].cap = 0;

      Cap cap = rem - max_flow(from, to, rem);
      if (from != s and cap != 0) max_flow(from, s, cap);
      if (t != to and cap != 0) max_flow(t, to, cap);
      return -cap;
    }

  };

} // namespace luz

#include <iostream>
#include <map>

int main() {
  using usize = std::size_t;

  usize n, e, q;
  std::cin >> n >> e >> q;
  
  luz::MaxFlowGraph g(n);
  std::vector< std::map< usize, usize > > eidxs(n);
  while (e--) {
    usize u, v;
    std::cin >> u >> v;
    u--; v--;
    eidxs[u][v] = g.add_directed_edge(u, v, 1);
    eidxs[v][u] = g.add_directed_edge(v, u, 1);
  }

  std::vector< usize > qs(q), us(q), vs(q);
  for (usize i = 0; i < q; i++) {
    usize u, v;
    std::cin >> qs[i] >> u >> v;
    u--; v--;

    us[i] = u;
    vs[i] = v;

    if (eidxs[u].count(v)) continue;
    eidxs[u][v] = g.add_directed_edge(u, v, 0);
    eidxs[v][u] = g.add_directed_edge(v, u, 0);
  }

  usize s = 0, t = n - 1;
  int flow = g.max_flow(s, t);
  for (usize i = 0; i < q; i++) {
    usize u = us[i], v = vs[i];
    
    if (qs[i] == 1) {
      flow += g.link(s, t, u, eidxs[u][v], 1);
      flow += g.link(s, t, v, eidxs[v][u], 1);
    }
    
    if (qs[i] == 2) {
      flow += g.cut(s, t, u, eidxs[u][v]);
      flow += g.cut(s, t, v, eidxs[v][u]);
    }

    std::cout << flow << std::endl;
  }
}
accuracy: 1
time_ms: 720
memory_kb: 8320
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")

#define rep(i,n) for(ll i=0;i<n;i++)
#define repl(i,l,r) for(ll i=(l);i<(r);i++)
#define per(i,n) for(ll i=(n)-1;i>=0;i--)
#define perl(i,r,l) for(ll i=r-1;i>=l;i--)
#define fi first
#define se second
#define pb push_back
#define ins insert
#define pqueue(x) priority_queue<x,vector<x>,greater<x>>
#define all(x) (x).begin(),(x).end()
#define CST(x) cout<<fixed<<setprecision(x)
#define vtpl(x,y,z) vector<tuple<x,y,z>>
#define rev(x) reverse(x);
using ll=long long;
using vl=vector<ll>;
using vvl=vector<vector<ll>>;
using pl=pair<ll,ll>;
using vpl=vector<pl>;
using vvpl=vector<vpl>;
const ll MOD=1000000007;
const ll MOD9=998244353;
const int inf=1e9+10;
const ll INF=4e18;
const ll dy[9]={1,0,-1,0,1,1,-1,-1,0};
const ll dx[9]={0,1,0,-1,1,-1,1,-1,0};
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
struct fordfulkerson{
    ll n;
    vector<vector<ll>> g;
    vector<bool> used;
    fordfulkerson(ll _n):n(_n){
        g.resize(n,vector<ll>(n));used.resize(n);
    }
    ll dfs(ll v,ll t,ll f){
        if(v==t)return f;
        used[v]=true;
        for(ll i=0;i<used.size();i++){
            if(!used[i]&&g[v][i]){
                ll d=dfs(i,t,min(f,g[v][i]));
                if(d>0){
                    g[v][i]-=d;g[i][v]+=d;
                    return d;
                }
            }
        }
        return 0;
    }
    ll max_flow(ll s,ll t,ll limit=INF){
        ll ans=0;
        while(1){
            used.assign(n,false);
            int f=dfs(s,t,limit);
            ans+=f;
            limit-=f;
            if(f==0||limit==0)return ans;
        }

    }
};
int main(){
    ll n;cin >> n;
    fordfulkerson f(n);
    ll m;cin >> m;
    ll q;cin >> q;
    rep(_,m){
        ll a,b;cin >>a  >> b;a--;b--;
        f.g[a][b]=1;f.g[b][a]=1;
    }
    ll ans=f.max_flow(0,n-1);
    rep(_,q){
        ll t,a,b;cin >> t >> a >> b;a--;b--;
        if(t==1){
            f.g[a][b]=1;f.g[b][a]=1;
        }
        else{
            if(f.g[a][b]==0){
                int d=f.max_flow(a,b,1);
                if(d==0){
                    f.max_flow(n-1,0,1);
                    f.max_flow(a,b,1);
                    ans--;
                }
            }
            else if(f.g[b][a]==0){
                int d=f.max_flow(b,a,1);
                if(d==0){
                    f.max_flow(n-1,0,1);
                    f.max_flow(b,a,1);
                    ans--;
                }
            }
            f.g[a][b]=0;f.g[b][a]=0;
        }
        ans+=f.max_flow(0,n-1);
        cout << ans << endl;
        /*rep(i,n){
            rep(j,n)cout << f.g[i][j] <<" ";cout << endl;
        }*/
    }
}
accuracy: 1
time_ms: 660
memory_kb: 5452
final_rank: 7

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

//constexpr long long int MOD = 1000000007;
constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-8;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

struct Flow {
	vector<vector<pair<int, int>>>edge;
	int ans = 0;
	Flow(int sz) {
		edge.resize(sz);
	}
	bool Go(int from, int to) {
		vector<int>bef(edge.size(), -1);
		queue<int>Q;
		Q.push(from);
		while (!Q.empty()) {
			int cn = Q.front();
			Q.pop();
			for (auto i : edge[cn]) {
				if (bef[i.first] == -1 && i.second == 1) {
					bef[i.first] = cn;
					Q.push(i.first);
				}
			}
		}
		if (bef[to] == -1)return false;
		int p = to;
		while (p != from) {
			int nx = 1;
			for (int i = 0; i < edge[p].size(); i++) {
				if (edge[p][i].first == bef[p]) {
					nx ^= edge[p][i].second;
					edge[p][i].second = 1;
				}
			}
			for (int i = 0; i < edge[bef[p]].size(); i++) {
				if (edge[bef[p]][i].first == p) {
					edge[bef[p]][i].second =nx;
				}
			}
			p = bef[p];
		}
		return true;
	}
	void DelGo(int from,int to) {
		if (from == to)return;
		vector<int>bef(edge.size(), -1);
		queue<int>Q;
		Q.push(from);
		while (!Q.empty()) {
			int cn = Q.front();
			Q.pop();
			for (auto i : edge[cn]) {
				if (bef[i.first] == -1 && i.second == 1) {
					for (int j = 0; j < edge[i.first].size(); j++) {
						if (edge[i.first][j].first == cn && edge[i.first][j].second == 0) {
							bef[i.first] = cn;
							Q.push(i.first);
						}
					}
				}
			}
		}
		int p = to;
		while (p != from) {
			for (int i = 0; i < edge[p].size(); i++) {
				if (edge[p][i].first == bef[p]) {
					edge[p][i].second = 1;
				}
			}
			for (int i = 0; i < edge[bef[p]].size(); i++) {
				if (edge[bef[p]][i].first == p) {
					edge[bef[p]][i].second = 1;
				}
			}
			p = bef[p];
		}
	}
	int AddEdge(int u, int v) {
		edge[u].push_back({ v,1 });
		edge[v].push_back({ u,1 });
		if (Go(0, edge.size() - 1))ans++;
		return ans;
	}
	void Init(vector<int>u, vector<int>v) {
		for (int i = 0; i < u.size(); i++) {
			edge[u[i]].push_back({ v[i],1 });
			edge[v[i]].push_back({ u[i],1 });
		}
		while (Go(0, edge.size() - 1)) {
			ans++;
		}
	}
	int DeleteEdge(int u, int v) {
		{
			for (int i = 0; i < edge[u].size(); i++) {
				if (edge[u][i].first == v && edge[u][i].second == 0) {
					ans--;
					DelGo(edge.size() - 1, v);
					DelGo(v, u);
					DelGo(u, 0);
					for (int j = 0; j < edge[u].size(); j++) {
						if (edge[u][j].first == v) {
							swap(edge[u][j], edge[u].back());
							edge[u].pop_back();
							break;
						}
					}
					for (int j = 0; j < edge[v].size(); j++) {
						if (edge[v][j].first == u) {
							swap(edge[v][j], edge[v].back());
							edge[v].pop_back();
							break;
						}
					}
				}
			}
		}
		{
			for (int i = 0; i < edge[v].size(); i++) {
				if (edge[v][i].first == u && edge[v][i].second == 0) {
					ans--;
					DelGo(edge.size() - 1, u);
					DelGo(u, v);
					DelGo(v, 0);
					for (int j = 0; j < edge[u].size(); j++) {
						if (edge[u][j].first == v) {
							swap(edge[u][j], edge[u].back());
							edge[u].pop_back();
							break;
						}
					}
					for (int j = 0; j < edge[v].size(); j++) {
						if (edge[v][j].first == u) {
							swap(edge[v][j], edge[v].back());
							edge[v].pop_back();
							break;
						}
					}
				}
			}
		}
		for (int j = 0; j < edge[u].size(); j++) {
			if (edge[u][j].first == v) {
				swap(edge[u][j], edge[u].back());
				edge[u].pop_back();
				break;
			}
		}
		for (int j = 0; j < edge[v].size(); j++) {
			if (edge[v][j].first == u) {
				swap(edge[v][j], edge[v].back());
				edge[v].pop_back();
				break;
			}
		}
	//	cout << "##################" << endl;
	//	DEBUG();
	//	cout << "----------------" << endl;
		if (Go(0, edge.size() - 1))ans++;
		return ans;
	}
	void DEBUG() {
		for (int i = 0; i < edge.size(); i++) {
			for (auto j : edge[i]) {
				cout << i << " " << j.first << " " << j.second << endl;
			}
		}
	}
};

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

	cin >> N >> M >> K;
	vector<int>u;
	vector<int>v;
	for (int i = 0; i < M; i++) {
		cin >> L >> R;
		L--, R--;
		u.push_back(L);
		v.push_back(R);
	}
	Flow f(N);
	f.Init(u, v);
	while (K--) {
		int a, b, c;
		cin >> a >> b >> c;
		b--, c--;
		if (a == 1) {
			cout << f.AddEdge(b, c) << endl;
		}
		else {
			cout << f.DeleteEdge(b, c) << endl;
		}
	//	f.DEBUG();
	}
}
accuracy: 1
time_ms: 760
memory_kb: 4168
final_rank: 4

code_snippet: #define MOD_TYPE 2

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

#if 1
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#endif

#if 0
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
using namespace __gnu_pbds;
using namespace __gnu_cxx;
template <typename T>
using extset =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#endif

#if 0
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
using Int = boost::multiprecision::cpp_int;
using lld = boost::multiprecision::cpp_dec_float_100;
#endif

#pragma region Macros

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
template <typename T>
using smaller_queue = priority_queue<T, vector<T>, greater<T>>;

constexpr ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
constexpr int INF = (int)1e9 + 10;
constexpr ll LINF = (ll)4e18;
const double PI = acos(-1.0);
constexpr double EPS = 1e-11;
constexpr int Dx[] = {0, 0, -1, 1, -1, 1, -1, 1, 0};
constexpr int Dy[] = {1, -1, 0, 0, -1, -1, 1, 1, 0};

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define REPI(i, m, n) for (int i = m; i < (int)(n); ++i)
#define repi(i, n) REPI(i, 0, n)
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";
#define UNIQUE(v) v.erase(unique(all(v)), v.end())

struct io_init {
  io_init() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << setprecision(30) << setiosflags(ios::fixed);
  };
} io_init;
template <typename T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
inline ll floor(ll a, ll b) {
  if (b < 0) a *= -1, b *= -1;
  if (a >= 0) return a / b;
  return -((-a + b - 1) / b);
}
inline ll ceil(ll a, ll b) { return floor(a + b - 1, b); }
template <typename A, size_t N, typename T>
inline void Fill(A (&array)[N], const T &val) {
  fill((T *)array, (T *)(array + N), val);
}
template <typename T>
vector<T> compress(vector<T> &v) {
  vector<T> val = v;
  sort(all(val)), val.erase(unique(all(val)), val.end());
  for (auto &&vi : v) vi = lower_bound(all(val), vi) - val.begin();
  return val;
}
template <typename T, typename U>
constexpr istream &operator>>(istream &is, pair<T, U> &p) noexcept {
  is >> p.first >> p.second;
  return is;
}
template <typename T, typename U>
constexpr ostream &operator<<(ostream &os, pair<T, U> p) noexcept {
  os << p.first << " " << p.second;
  return os;
}
template <typename T>
constexpr istream &operator>>(istream &is, vector<T> &v) noexcept {
  for (int i = 0; i < v.size(); i++) is >> v[i];
  return is;
}
template <typename T>
constexpr ostream &operator<<(ostream &os, vector<T> &v) noexcept {
  for (int i = 0; i < v.size(); i++)
    os << v[i] << (i + 1 == v.size() ? "" : " ");
  return os;
}
template <typename T>
constexpr void operator--(vector<T> &v, int) noexcept {
  for (int i = 0; i < v.size(); i++) v[i]--;
}

random_device seed_gen;
mt19937_64 engine(seed_gen());

#pragma endregion

// --------------------------------------

const int MAX_V = 500;
set<int> G[MAX_V];

vector<vector<int>> paths;
set<pii> used_edge;
map<pii, int> mp;

bool used[MAX_V];
bool dfs(int u, int sink, vector<int> &path) {
  if (u == sink) {
    path.push_back(u);
    return true;
  }
  used[u] = true;
  for (auto v : G[u]) {
    if (used[v]) continue;
    bool f = dfs(v, sink, path);
    if (f) {
      path.push_back(u);
      // 残余グラフを押し戻す場合は双方向に張り直す
      if (used_edge.count({u, v})) {
        G[v].insert(u);
        used_edge.erase({u, v});
        used_edge.erase({v, u});
      } else {
        G[u].erase(v);
        G[v].insert(u);
        used_edge.insert({u, v});
        used_edge.insert({v, u});
      }
      return true;
    }
  }
  return false;
}

int n;
int ans = 0;

void calc() {
  while (1) {
    fill(used, used + MAX_V, false);
    vector<int> path;
    bool f = dfs(0, n - 1, path);
    if (not f) return;
    reverse(all(path));
    rep(i, path.size() - 1) { mp[{path[i], path[i + 1]}] = paths.size(); }
    paths.push_back(path);
    ans++;
  }
}

void add(int u, int v) {
  assert(not G[u].count(v));
  assert(not G[v].count(u));
  assert(not used_edge.count({u, v}));
  assert(not used_edge.count({v, u}));
  G[u].insert(v);
  G[v].insert(u);
  calc();
}

void del(int u, int v) {
  if (used_edge.count({u, v})) {  // 流した
    int pi;
    if (G[u].count(v))  // 残余グラフに u->v がある ＝ v->u で使った
      pi = mp[{v, u}];
    else
      pi = mp[{u, v}];
    rep(i, paths[pi].size() - 1) {
      int u = paths[pi][i];
      int v = paths[pi][i + 1];
      G[u].insert(v);
      used_edge.erase({u, v});
      used_edge.erase({v, u});
    }
    ans--;
  }
  G[u].erase(v);
  G[v].erase(u);
  calc();
}

void solve() {
  int m, q;
  cin >> n >> m >> q;
  rep(i, m) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    G[u].insert(v);
    G[v].insert(u);
  }
  calc();
  rep(i, q) {
    int m, u, v;
    cin >> m >> u >> v;
    u--, v--;
    if (m == 1)
      add(u, v);
    else
      del(u, v);
    cout << ans << "\n";
  }
}

int main() { solve(); }
accuracy: 0.2413793103448276
time_ms: 30
memory_kb: 3700
final_rank: 14