#include <bits/stdc++.h>
using namespace std;
int const N = 3e5 + 10;
int n, m, q, P[N], H[N], cnt;
struct Edge {
  int n, t;
} E[N << 1];
struct Node {
  int max, submax;
} Ns[N];
void insert(int f, int t) {
  E[cnt].t = t;
  E[cnt].n = H[f];
  H[f] = cnt++;
  E[cnt].t = f;
  E[cnt].n = H[t];
  H[t] = cnt++;
}
int find(int p) {
  if (P[p] == p)
    return p;
  else
    return P[p] = find(P[p]);
}
int pmerge(int l, int r) {
  int pl = find(l), pr = find(r);
  P[pl] = pr;
  return pr;
}
void dfs(int rt, int anc) {
  Ns[rt].max = Ns[rt].submax = 0;
  for (int i = H[rt], to; ~i; i = E[i].n)
    if ((to = E[i].t) != anc) dfs(to, rt);
  for (int i = H[rt], to; ~i; i = E[i].n)
    if ((to = E[i].t) != anc) {
      if (Ns[to].max + 1 >= Ns[rt].max) {
        Ns[rt].submax = Ns[rt].max;
        Ns[rt].max = Ns[to].max + 1;
      } else if (Ns[to].max + 1 > Ns[rt].submax)
        Ns[rt].submax = Ns[to].max + 1;
    }
}
int dfsd(int rt, int anc) {
  int d = Ns[rt].max + Ns[rt].submax;
  for (int i = H[rt], to; ~i; i = E[i].n)
    if ((to = E[i].t) != anc) d = max(d, dfsd(to, rt));
  return d;
}
int cald(int rt) {
  dfs(rt, -1);
  return dfsd(rt, -1);
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= n; i++) P[i] = i;
  memset(H, -1, sizeof(H));
  cnt = 0;
  for (int i = 0; i < m; i++) {
    int f, t;
    scanf("%d%d", &f, &t);
    insert(f, t);
    pmerge(f, t);
  }
  map<int, int> roots;
  for (int i = 1, j; i <= n; i++)
    if (roots.find(j = find(i)) == roots.end())
      roots.insert(make_pair(j, cald(j)));
  for (int i = 0; i < q; i++) {
    int q, x, y;
    scanf("%d", &q);
    if (q == 1) {
      scanf("%d", &x);
      printf("%d\n", roots[find(x)]);
    } else {
      scanf("%d%d", &x, &y);
      int px = find(x), py = find(y), lx = roots[px], ly = roots[py];
      if (px == py) continue;
      P[px] = py;
      roots[py] = max((lx + 1) / 2 + (ly + 1) / 2 + 1, max(lx, ly));
    }
  }
  return 0;
}
