#include <bits/stdc++.h>
using namespace std;
struct FAU {
  vector<int> p;
  vector<int> r;
  FAU(int n) {
    p.resize(n, -1);
    r.resize(n, 0);
  }
  int Find(int x) {
    if (p[x] == -1) return x;
    p[x] = Find(p[x]);
    return p[x];
  }
  bool Together(int x, int y) { return (Find(x) == Find(y)); }
  void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x == y) return;
    if (r[x] > r[y])
      p[y] = x;
    else
      p[x] = y;
    if (r[x] == r[y]) ++r[y];
    return;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  int n, m, q;
  cin >> n >> m >> q;
  FAU F(n);
  vector<vector<int> > G(n);
  for (int i = (1); i <= (m); ++i) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    G[u].push_back(v);
    G[v].push_back(u);
    F.Union(u, v);
  }
  vector<bool> vis(n, 0);
  vector<int> dist(n, 0);
  vector<int> root(n);
  for (int i = (0); i <= ((int)(root).size() - 1); ++i) root[i] = F.Find(i);
  for (int i = (0); i <= ((int)(G).size() - 1); ++i)
    if (!vis[i]) {
      queue<int> Q;
      Q.push(i);
      int c = F.Find(i);
      dist[i] = 0;
      while (!Q.empty()) {
        int q = Q.front();
        Q.pop();
        vis[q] = 1;
        for (int j = (0); j <= ((int)(G[q]).size() - 1); ++j)
          if (!vis[G[q][j]]) {
            int u = G[q][j];
            dist[u] = dist[q] + 1;
            if (dist[u] > dist[root[c]]) root[c] = u;
            Q.push(u);
          }
      }
    }
  for (int i = (0); i <= ((int)(G).size() - 1); ++i) dist[i] = vis[i] = 0;
  vector<int> farthest(n, 0);
  for (int i = (0); i <= ((int)(G).size() - 1); ++i)
    if (!vis[i] && i == F.Find(i)) {
      int v = root[i];
      queue<int> Q;
      Q.push(v);
      dist[v] = 0;
      while (!Q.empty()) {
        int q = Q.front();
        Q.pop();
        vis[q] = 1;
        for (int j = (0); j <= ((int)(G[q]).size() - 1); ++j)
          if (!vis[G[q][j]]) {
            int u = G[q][j];
            dist[u] = dist[q] + 1;
            if (dist[u] > farthest[i]) farthest[i] = dist[u];
            Q.push(u);
          }
      }
    }
  for (int i = (1); i <= (q); ++i) {
    int t, u, v;
    cin >> t >> u;
    u--;
    if (t == 1)
      cout << farthest[F.Find(u)] << '\n';
    else {
      cin >> v;
      v--;
      if (!F.Together(u, v)) {
        int findu = F.Find(u), findv = F.Find(v), longu = farthest[findu],
            longv = farthest[findv],
            longnew = (((longu) > (longv)) ? (longu) : (longv));
        longnew = (((longnew) > (1 + (longu + 1) / 2 + (longv + 1) / 2))
                       ? (longnew)
                       : (1 + (longu + 1) / 2 + (longv + 1) / 2));
        farthest[findu] = farthest[findv] = longnew;
        F.Union(u, v);
      }
    }
  }
  return 0;
}
