#include <bits/stdc++.h>
using namespace std;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = 10 * x + ch - '0';
    ch = getchar();
  }
  return x * f;
}
const int Size = 300001;
vector<int> to[Size];
int dp[Size];
int len[Size];
int father[Size];
int n, m, q, ans, point, nowrt;
void PushEdge(int f, int t) { to[f].push_back(t); }
void dfs(int now, int lastnode, int dist) {
  father[now] = nowrt;
  if (dist > ans) {
    ans = dist;
    point = now;
  }
  int len = to[now].size();
  for (int i = 0; i < len; i++) {
    if (to[now][i] == lastnode) {
      continue;
    } else {
      dfs(to[now][i], now, dist + 1);
    }
  }
}
void init() {
  n = read();
  m = read();
  q = read();
  for (int i = 1; i <= n; i++) father[i] = i;
  for (int i = 1; i <= m; i++) {
    int f = read();
    int t = read();
    PushEdge(f, t);
    PushEdge(t, f);
  }
  for (int i = 1; i <= n; i++) {
    nowrt = i;
    if (father[i] == i) {
      ans = -1;
      dfs(i, i, 0);
      ans = -1;
      dfs(point, point, 0);
      dp[i] = ans;
    }
  }
}
int find(int x) {
  if (father[x] == x) return x;
  return father[x] = find(father[x]);
}
void Union(int x, int y) {
  int fx = find(x);
  int fy = find(y);
  if (fx == fy) return;
  father[fy] = fx;
  dp[fx] =
      max(max(dp[fx], dp[fy]), ((dp[fx] + 1) >> 1) + ((dp[fy] + 1) >> 1) + 1);
}
int main() {
  init();
  int op, x, y;
  while (q--) {
    op = read();
    if (op == 1) {
      x = read();
      printf("%d\n", dp[find(x)]);
    } else {
      x = read();
      y = read();
      Union(x, y);
    }
  }
  return 0;
}
