#include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#include <tuple>
#include <functional>
#include <set>

template <class Tp>
Tp inf() { return static_cast<Tp>(1) << (8*sizeof(Tp) - 3); }

template <class Tp>
struct Edge {
  size_t src, dst;
  Tp cap;
  size_t rev;
  Edge(size_t src, size_t dst, Tp cap, size_t rev):
    src(src), dst(dst), cap(cap), rev(rev)
  {}
};

template <class Tp>
struct graph: public std::vector<std::vector<Edge<Tp>>> {
  graph(size_t n): std::vector<std::vector<Edge<Tp>>>(n) {}

  void connect_with(size_t src, size_t dst, Tp cap) {
    (*this)[src].emplace_back(src, dst, cap, (*this)[dst].size());
    (*this)[dst].emplace_back(dst, src, cap, (*this)[src].size()-1);
  }

  void connect_to(size_t src, size_t dst, Tp cap) {
    (*this)[src].emplace_back(src, dst, cap, (*this)[dst].size());
    (*this)[dst].emplace_back(dst, src, 0, (*this)[src].size()-1);
  }

  void inspect() const {
    size_t n = this->size();
    fprintf(stderr, "vertex: %zu\n", n);
    for (size_t i = 0; i < n; ++i)
      for (const auto& e: (*this)[i]) {
        // fprintf(stderr, "%zu -> %zu, cap: %zu, rev: [%zu]\n",
        //         e.src, e.dst, e.cap, e.rev);
        if (e.cap == 0) {
          const auto& f = (*this)[e.dst][e.rev];
          if (f.cap == 0) continue;
          fprintf(stderr, "%zu -> %zu\n", e.src, e.dst);
        }
      }
  }
};

template <class Tp>
Tp max_flow(graph<Tp>& g, size_t s, size_t t, Tp f0 = inf<Tp>()) {
  Tp flow = Tp(0);
  std::vector<size_t> iter, cost;

  auto distance = [&](size_t s) {
    std::vector<size_t> res(g.size(), inf<size_t>());
    std::queue<size_t> q;
    res[s] = 0;
    q.emplace(s);
    while (!q.empty()) {
      size_t v = q.front();
      q.pop();
      for (const auto& e: g[v]) {
        if (static_cast<Tp>(0) < e.cap && res[e.dst] == inf<size_t>()) {
          res[e.dst] = res[v] + 1;
          q.push(e.dst);
        }
      }
    }
    return res;
  };

  std::function<Tp (size_t, Tp)> augment = [&](size_t v, Tp f)->Tp {
    if (v == t) return f;
    for (size_t& i = iter[v]; i < g[v].size(); ++i) {
      Edge<Tp>& e = g[v][i];
      if (Tp(0) < e.cap && cost[v] < cost[e.dst]) {
        Tp d = augment(e.dst, std::min(f, e.cap));
        if (Tp(0) < d) {
          e.cap -= d;
          g[e.dst][e.rev].cap += d;
          return d;
        }
      }
    }
    return static_cast<Tp>(0);
  };

  while (true) {
    cost = distance(s);
    if (cost[t] == inf<size_t>()) return flow;
    iter.assign(g.size(), 0);
    Tp f;
    while (Tp(0) < (f = augment(s, f0))) {
      flow += f;
      f0 -= f;
      if (!f0) return flow;
    }
  }
}

int main() {
  size_t N, E, Q;
  scanf("%zu %zu %zu", &N, &E, &Q);

  graph<intmax_t> g(N);
  std::set<std::pair<size_t, size_t>> es0;
  for (size_t i = 0; i < E; ++i) {
    size_t F, T;
    scanf("%zu %zu", &F, &T);
    --F;
    --T;
    g.connect_with(F, T, 1);
    es0.insert(std::minmax(F, T));
  }

  std::vector<std::tuple<int, size_t, size_t>> qs;
  std::set<std::pair<size_t, size_t>> es;
  for (size_t i = 0; i < Q; ++i) {
    int M;
    size_t A, B;
    scanf("%d %zu %zu", &M, &A, &B);
    --A;
    --B;
    if (A > B) std::swap(A, B);
    qs.emplace_back(M, A, B);
    if (!es0.count(std::make_pair(A, B)))
      es.emplace(A, B);
  }

  for (const auto& e: es) {
    size_t s, d;
    std::tie(s, d) = e;
    g.connect_with(s, d, 0);
  }

  // g.inspect();
  intmax_t first = max_flow(g, 0, N-1);
  // fprintf(stderr, "first: %jd\n", first);

  for (size_t i = 0; i < Q; ++i) {
    int M;
    size_t A, B;
    std::tie(M, A, B) = qs[i];
    intmax_t df = 0;

    // g.inspect();

    if (M == 1) {
      // connect
      // fprintf(stderr, "+ %zu %zu\n", A, B);
      for (auto& e: g[A]) {
        if (e.dst != B) continue;

        e.cap = 1;
        g[B][e.rev].cap = 1;
        df = max_flow(g, 0, N-1);
        break;
      }
      first += df;
      // fprintf(stderr, "delta: %jd\n", df);
      printf("%jd\n", first);
      continue;
    }

    if (M == 2) {
      // disconnect
      // fprintf(stderr, "- %zu %zu\n", A, B);
      for (auto& e: g[A]) {
        if (e.dst != B) continue;

        if (e.cap > 0 && g[B][e.rev].cap > 0) {
          e.cap = 0;
          g[B][e.rev].cap = 0;
          break;
        }

        if (e.cap == 0) {
          intmax_t tmp = max_flow(g, e.src, e.dst, 1L);
          if (tmp == 0) {
            df = -max_flow(g, N-1, 0, 1L);
            max_flow(g, e.src, e.dst, 1L);
          }
          e.cap = 0;
          g[B][e.rev].cap = 0;
          break;
        }
        if (g[B][e.rev].cap == 0) {
          intmax_t tmp = max_flow(g, e.dst, e.src, 1L);
          if (tmp == 0) {
            df = -max_flow(g, N-1, 0, 1L);
            max_flow(g, e.dst, e.src, 1L);
          }
          e.cap = 0;
          g[B][e.rev].cap = 0;
          break;
        }
      }
      first += df;
      // fprintf(stderr, "delta: %jd\n", df);
      printf("%jd\n", first);
      continue;
    }
  }

  // g.inspect();
}



Measured memory_bytes: 5540