#include <bits/stdc++.h>
const int INF = 1e9;
const int N = 312312;
const double PI = 3.1415926535897932384626433832795;
using namespace std;
int p[N], size[N], diametr[N];
vector<int> g[N];
bool used[N];
int n;
int get(int v) {
  if (v == p[v]) return v;
  return p[v] = get(p[v]);
}
void union1(int x, int y) {
  x = get(x);
  y = get(y);
  if (x == y) return;
  if (size[x] > size[y]) swap(x, y);
  size[y] += size[x];
  p[x] = y;
}
void union2(int x, int y) {
  x = get(x);
  y = get(y);
  if (x == y) return;
  if (size[x] > size[y]) swap(x, y);
  size[y] += size[x];
  p[x] = y;
  diametr[y] = max(diametr[x], max(diametr[y], (diametr[x] + 1) / 2 +
                                                   (diametr[y] + 1) / 2 + 1));
}
int maxi = -1, maxind = -1;
void dfs(int v, int depth, int p) {
  if (depth > maxi) {
    maxi = depth;
    maxind = v;
  }
  for (int c = 0; c < g[v].size(); c++) {
    int to = g[v][c];
    if (to != p) dfs(to, depth + 1, v);
  }
}
int find(int v) {
  maxi = -1;
  dfs(v, 0, -1);
  maxi = -1;
  dfs(maxind, 0, -1);
  return maxi;
}
int main() {
  ios_base ::sync_with_stdio();
  int m, q, c, type, x, y;
  scanf("%d %d %d", &n, &m, &q);
  for (c = 1; c <= n; c++) {
    p[c] = c;
    size[c] = 1;
    diametr[c] = 0;
  }
  for (c = 1; c <= m; c++) {
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
    union1(x, y);
  }
  for (c = 1; c <= n; c++) {
    int zx = get(c);
    if (!used[zx]) {
      used[zx] = true;
      diametr[zx] = find(c);
    }
  }
  while (q--) {
    scanf("%d", &type);
    if (type == 1) {
      scanf("%d", &x);
      printf("%d\n", diametr[get(x)]);
    } else {
      scanf("%d %d", &x, &y);
      union2(x, y);
    }
  }
  return 0;
}
