#include <bits/stdc++.h>
using namespace std;
int n, m, q;
vector<int> v[300009];
int d[300009];
int p[300009];
int pap[300009];
int l[300009];
bool done[300009];
int nd = -1, mx = 0;
void fill(int node, int pa) {
  pap[node] = pa;
  for (int i = 0; i < v[node].size(); i++) {
    if (v[node][i] != pa) return fill(v[node][i], node);
  }
}
void tree_diameter(int pa, int node, int val, bool st) {
  done[node] = st;
  if (val > mx) {
    mx = val;
    nd = node;
  }
  if (v[node].size() < 1) return;
  if (v[node].size() == 1 && v[node][0] == pa) {
    return;
  }
  for (int i = 0; i < v[node].size(); i++) {
    if (v[node][i] != pa) {
      tree_diameter(node, v[node][i], val + 1, st);
    }
  }
}
int get_pa(int node) {
  if (p[node] == node) return node;
  return p[node] = get_pa(p[node]);
}
void mrg(int node1, int node2) {
  int P1 = get_pa(node1), P2 = get_pa(node2);
  if (P1 == P2) return;
  p[P2] = P1;
}
void marg(int node1, int node2) {
  int P1 = get_pa(node1), P2 = get_pa(node2);
  if (P1 == P2) return;
  p[P2] = P1;
  int z, y;
  if (l[P2] % 2 == 0)
    z = l[P2] / 2;
  else
    z = l[P2] / 2 + 1;
  if (l[P1] % 2 == 0)
    y = l[P1] / 2;
  else
    y = l[P1] / 2 + 1;
  l[P1] = max(max(l[P2], l[P1]), z + y + 1);
}
int main() {
  cin >> n >> m >> q;
  for (int i = 0; i < n; i++) {
    p[i] = i;
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    v[a - 1].push_back(b - 1);
    v[b - 1].push_back(a - 1);
    mrg(a - 1, b - 1);
  }
  fill(0, 0);
  for (int i = 0; i < n; i++) {
    if (!done[i]) {
      nd = -1, mx = 0;
      tree_diameter(i, i, 0, 0);
      if (nd == -1) continue;
      mx = 0;
      tree_diameter(nd, nd, 0, 1);
      int TD = mx;
      l[get_pa(i)] = TD;
    }
  }
  for (int i = 0; i < q; i++) {
    int x;
    scanf("%d", &x);
    if (x == 1) {
      int a;
      scanf("%d", &a);
      cout << l[get_pa(a - 1)] << endl;
    } else {
      int a, b;
      scanf("%d%d", &a, &b);
      marg(a - 1, b - 1);
    }
  }
}
