#include <bits/stdc++.h>
using namespace std;
int const MAX_N = 600100;
int const INT_INF = 1000000000;
int my_rank[MAX_N], my_parent[MAX_N], diam_ancestor[MAX_N];
int d[MAX_N], och[MAX_N], nnew[MAX_N];
void make_set(int v) {
  my_parent[v] = v;
  diam_ancestor[v] = 0;
  my_rank[v] = 0;
}
int find_set(int v) {
  if (v != my_parent[v]) my_parent[v] = find_set(my_parent[v]);
  return my_parent[v];
}
void my_Link(int x, int y, int flag) {
  if (my_rank[x] > my_rank[y])
    my_parent[y] = x;
  else
    my_parent[x] = y;
  my_rank[y] += my_rank[x] == my_rank[y];
  if (flag) {
    int D1 = diam_ancestor[x];
    int D2 = diam_ancestor[y];
    int new_VVV = find_set(x);
    int val = (D1 + 1) / 2 + (D2 + 1) / 2 + 1;
    diam_ancestor[new_VVV] = max(D1, max(D2, val));
  }
}
void my_Union(int x, int y, int flag) {
  int V1 = find_set(x);
  int V2 = find_set(y);
  if (V1 == V2) return;
  my_Link(V1, V2, flag);
}
vector<int> e[MAX_N];
int main() {
  int n, m, q;
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 0; i < n; i++) make_set(i);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    my_Union(a, b, 0);
    e[a].push_back(b);
    e[b].push_back(a);
  }
  for (int i = 0; i < n; i++) d[i] = INT_INF;
  for (int i = 0; i < n; i++)
    if (!nnew[i]) {
      int p_read = 0, p_write = 1;
      och[p_read] = i;
      nnew[i] = 1;
      d[i] = 0;
      while (p_read < p_write) {
        int v = och[p_read];
        p_read++;
        for (int j = 0; j < (int)e[v].size(); j++) {
          int new_v = e[v][j];
          if (d[new_v] > d[v] + 1) {
            d[new_v] = d[v] + 1;
            och[p_write] = new_v;
            p_write++;
            nnew[new_v] = 1;
          }
        }
      }
      int mx_dist = -1, ans_vertex = -1;
      for (int j = 0; j < p_write; j++)
        if (d[och[j]] > mx_dist) {
          mx_dist = d[och[j]];
          ans_vertex = och[j];
        }
      for (int j = 0; j < p_write; j++) d[och[j]] = INT_INF;
      p_read = 0, p_write = 1;
      och[p_read] = ans_vertex;
      d[ans_vertex] = 0;
      while (p_read < p_write) {
        int v = och[p_read];
        p_read++;
        for (int j = 0; j < (int)e[v].size(); j++) {
          int new_v = e[v][j];
          if (d[new_v] > d[v] + 1) {
            d[new_v] = d[v] + 1;
            och[p_write] = new_v;
            p_write++;
          }
        }
      }
      mx_dist = -1;
      for (int j = 0; j < p_write; j++) mx_dist = max(mx_dist, d[och[j]]);
      diam_ancestor[find_set(i)] = mx_dist;
    }
  for (int i = 0; i < q; i++) {
    int tp;
    scanf("%d", &tp);
    if (tp == 2) {
      int a, b;
      scanf("%d%d", &a, &b);
      a--;
      b--;
      my_Union(a, b, 1);
    } else if (tp == 1) {
      int v;
      scanf("%d", &v);
      v--;
      int VVV = find_set(v);
      printf("%d\n", diam_ancestor[VVV]);
    }
  }
  return 0;
}
