#include <queue>
#include <cstdio>
#include <cstring>
#include <cassert>
using namespace std;

typedef int F;
const int MAXV = 505;
const int MAXE = 21005;
const F MAXF = 1<<29;

F cap[2*MAXE], flow[2*MAXE];
int level[MAXV], edge[MAXV], seen[MAXV], to[2*MAXE];

struct MaxFlow {
    int V, E, prev[2*MAXE];
    MaxFlow(int n) : E(0), V(n) { memset(edge, -1, sizeof(edge)); }
    void add_edge(int s, int t, F f, F g = 0) {
        flow[E] = 0; cap[E] = f; to[E] = t; prev[E] = edge[s]; edge[s] = E; E++;
        flow[E] = 0; cap[E] = g; to[E] = s; prev[E] = edge[t]; edge[t] = E; E++;
    }
    void make_level(int s) { // bfs
        memset(level, -1, sizeof(level));
        queue<int> q; q.push(s); level[s] = 0;
        while(!q.empty()) {
            int v = q.front(); q.pop();
            for (int e = edge[v]; e != -1; e = prev[e]) {
                if (cap[e] - flow[e] > 0 && level[to[e]] == -1)
                    q.push(to[e]), level[to[e]] = level[v]+1;
            }
        }
    }
    F augment(int s, int t, F f) { // dfs
        if (s == t || f == 0) return f;
        seen[s] = 1;
        F r = 0;
        for (int e = edge[s]; e != -1; e = prev[e]) {
            if (seen[to[e]] == 0 && level[to[e]] > level[s] && cap[e] - flow[e] > 0) {
                F g = augment(to[e], t, min(f - r, cap[e] - flow[e]));
                if (g > 0) flow[e] += g, flow[e^1] -= g, r += g;
                if (r == f) return r;
            }
        }
        return r;
    }
    F max_flow(int s, int t) {
        F f = 1, ret = 0;
        for (; f > 0; ) {
            make_level(s);
            memset(seen, 0, sizeof(seen));
            f = augment(s, t, MAXF);
            ret += f;
        }
        return ret;
    }
};

int use_edge[MAXV];
void calc_path(int s, int t, MaxFlow &mf) {
    queue<int> q; q.push(s);
    memset(seen, -1, sizeof(seen)); seen[s] = s;
    while(!q.empty()) {
        int v = q.front(); q.pop();
        for (int e = edge[v]; e != -1; e = mf.prev[e]) {
            if (seen[to[e]] == -1 && flow[e] > 0) {
                seen[to[e]] = v;
                use_edge[to[e]] = e;
                q.push(to[e]);
            }
        }
    }
    for (int v = t; v != seen[v]; v = seen[v]) {
        flow[use_edge[v]] = flow[use_edge[v]^1] = 0;
    }
}

F augment_path(int s, int t, MaxFlow &mf) {
    queue<int> q; q.push(s);
    memset(seen, -1, sizeof(seen)); seen[s] = s;
    while(!q.empty()) {
        int v = q.front(); q.pop();
        for (int e = edge[v]; e != -1; e = mf.prev[e]) {
            if (seen[to[e]] == -1 && cap[e] - flow[e] > 0) {
                seen[to[e]] = v;
                use_edge[to[e]] = e;
                q.push(to[e]);
            }
        }
    }
    if (seen[t] == -1) return 0;
    for (int v = t; v != seen[v]; v = seen[v]) {
        flow[use_edge[v]]++;
        flow[use_edge[v]^1]--;
    }
    return 1;
}

int find_edge(int s, int t, const MaxFlow &mf) {
    for (int e = edge[s]; e != -1; e = mf.prev[e])
        if (to[e] == t) return e;
    return -1;
}

int main() {
    int N,E,Q,F,T;
    scanf("%d %d %d", &N, &E, &Q);
    MaxFlow mf(N);
    for (int i=0; i<E; ++i) {
        scanf("%d %d", &F, &T); F--, T--;
        mf.add_edge(F, T, 1, 1);
    }
    int f = mf.max_flow(0, N-1);
    int M, A, B;
    for (int i=0; i<Q; ++i) {
        scanf("%d %d %d", &M, &A, &B); A--, B--;
        int e = find_edge(A, B, mf);
        if (M == 1) {
            if (e >= 0) cap[e] = cap[e^1] = 1;
            else mf.add_edge(A, B, 1, 1);
        } else {
            assert(e >= 0);
            cap[e] = cap[e^1] = 0;
            if (flow[e] != 0) {
                f--;
                if (flow[e] < 0) swap(A, B);
                calc_path(0, A, mf);
                calc_path(B, N-1, mf);
                flow[e] = flow[e^1] = 0;
            }
        }
        f += augment_path(0, N-1, mf);
        printf("%d\n", f);
    }
}

Measured memory_bytes: 1696