#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e6 + 10;
struct edge {
  int ver, nxt;
} e[MAXN];
int n, m, q, f[MAXN], maxn, dis[MAXN], st;
int cnt, head[MAXN];
bool vis[MAXN], vis2[MAXN];
void add(int u, int v) {
  e[++cnt].ver = v;
  e[cnt].nxt = head[u];
  head[u] = cnt;
}
int find(int x) {
  if (f[x] == x)
    return x;
  else
    return f[x] = find(f[x]);
}
void merge(int x, int y) {
  x = find(x);
  y = find(y);
  f[x] = y;
}
void dfs(int u, int val) {
  int i;
  if (maxn < val) {
    maxn = val;
    st = u;
  }
  for (i = head[u]; i; i = e[i].nxt) {
    int v = e[i].ver;
    if (!vis[v]) {
      vis[v] = true;
      dfs(v, val + 1);
    }
  }
  vis[u] = false;
}
void dfs2(int u, int val) {
  int i;
  if (maxn < val) maxn = val;
  for (i = head[u]; i; i = e[i].nxt) {
    int v = e[i].ver;
    if (!vis[v]) {
      vis[v] = true;
      dfs2(v, val + 1);
    }
  }
  vis[u] = false;
}
int main() {
  int i;
  scanf("%d %d %d", &n, &m, &q);
  for (i = 1; i <= n; i++) f[i] = i;
  for (i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    add(u, v);
    add(v, u);
    merge(u, v);
  }
  for (i = 1; i <= n; i++) {
    int u = find(i);
    if (vis2[u]) continue;
    maxn = -1;
    vis[u] = true;
    dfs(u, 0);
    maxn = -1;
    vis[st] = true;
    dfs2(st, 0);
    vis2[u] = true;
    dis[u] = maxn;
  }
  for (i = 1; i <= q; i++) {
    int op, u, v;
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d", &u);
      u = find(u);
      printf("%d\n", dis[u]);
    } else {
      scanf("%d %d", &u, &v);
      u = find(u);
      v = find(v);
      if (u == v) continue;
      dis[v] =
          max(max((dis[u] + 1) / 2 + (dis[v] + 1) / 2 + 1, dis[u]), dis[v]);
      merge(u, v);
    }
  }
  return 0;
}
