#include <bits/stdc++.h>
using namespace std;
int head[300005], fa[300005];
int len[300005];
bool vis[300005], flag[300005];
int n, m, q, cnt, maxx, sta;
struct node {
  int nex, to;
} e[300005 << 1];
void add(int u, int v) {
  e[++cnt].to = v;
  e[cnt].nex = head[u];
  head[u] = cnt;
}
int find(int x) {
  if (fa[x] == x) {
    return x;
  }
  return fa[x] = find(fa[x]);
}
void merge(int a, int b) {
  int x = find(a), y = find(b);
  fa[x] = y;
}
void dfs1(int x, int val) {
  if (val > maxx) {
    maxx = val;
    sta = x;
  }
  for (register int i = head[x]; i; i = e[i].nex) {
    int to = e[i].to;
    if (!vis[to]) {
      vis[to] = 1;
      dfs1(to, val + 1);
    }
  }
  vis[x] = 0;
}
void dfs2(int x, int val) {
  if (val > maxx) {
    maxx = val;
  }
  for (register int i = head[x]; i; i = e[i].nex) {
    int to = e[i].to;
    if (!vis[to]) {
      vis[to] = 1;
      dfs2(to, val + 1);
    }
  }
  vis[x] = 0;
}
int main() {
  scanf("%d%d%d", &n, &m, &q);
  for (register int i = 1; i <= n; i++) {
    fa[i] = i;
  }
  for (register int i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    add(a, b), add(b, a);
    merge(a, b);
  }
  for (register int i = 1; i <= n; i++) {
    int x = find(i);
    if (flag[x]) {
      continue;
    }
    flag[x] = 1;
    vis[x] = 1;
    maxx = -1;
    dfs1(x, 0);
    vis[sta] = 1;
    maxx = -1;
    dfs2(sta, 0);
    len[x] = maxx;
  }
  for (register int i = 1; i <= q; i++) {
    int e;
    scanf("%d", &e);
    if (e == 1) {
      int x;
      scanf("%d", &x);
      int F = find(x);
      printf("%d\n", len[F]);
    } else {
      int x, y;
      scanf("%d%d", &x, &y);
      int a = find(x), b = find(y);
      if (a == b) {
        continue;
      }
      len[b] =
          max(max((len[a] + 1) / 2 + (len[b] + 1) / 2 + 1, len[a]), len[b]);
      merge(x, y);
    }
  }
  return 0;
}
