#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
long long dx[] = {0, 0, 1, -1};
long long dy[] = {1, -1, 0, -1};
long long m, k, n, a[500005], ans = 0, sm = 0, res = 0, vis[300005] = {0},
                              vis1[300005] = {0}, diameter[300005] = {0};
multiset<long long> st1, st2;
string s1 = "one", s2 = "zero", s, ch = "";
vector<long long> v[300005], vnode, v1[50], v2[50], v3;
vector<pair<long long, long long> > vv;
vector<pair<long long, pair<long long, long long> > > vvv;
priority_queue<long long> pq;
map<pair<long long, long long>, long long> cost;
long long xa, xb, xc, ya, yb, yc, xres;
long long parent[500005], rank1[500005];
void make_set(long long v) {
  parent[v] = v;
  rank1[v] = 1;
  diameter[v] = 0;
}
long long find_set(long long v) {
  if (v == parent[v]) return v;
  return parent[v] = find_set(parent[v]);
}
void union_sets(long long a, long long b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    if (rank1[a] < rank1[b]) swap(a, b);
    parent[b] = a;
    rank1[a] += rank1[b];
  }
}
long long node, best;
void dfs(long long x, long long l) {
  vis[x] = 1;
  for (long long i = 0; i < v[x].size(); i++) {
    long long y = v[x][i];
    if (!vis[y]) dfs(y, l + 1);
  }
  if (l > best) {
    best = l;
    node = x;
  }
}
void dfs1(long long x, long long l) {
  vis1[x] = 1;
  for (long long i = 0; i < v[x].size(); i++) {
    long long y = v[x][i];
    if (!vis1[y]) dfs1(y, l + 1);
  }
  if (l > best) {
    best = l;
    node = x;
  }
}
long long f(long long x, long long y) {
  x = find_set(x);
  y = find_set(y);
  return (diameter[x] + 1) / 2 + (diameter[y] + 1) / 2 + 1;
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  long long i = 0, x, y, j = 0, z = 0, q, nb0 = 0, nb = 0, nbmax = 0, nbinf = 0,
            nb2 = 0, mm = 5e8, idx = 0, ok = 0, l, r, negatif = 0, positif = 0,
            l1, r1, t;
  multiset<long long>::iterator it, it1, it2;
  char c;
  cin >> n >> m >> q;
  for (i = 1; i <= n; i++) make_set(i);
  for (i = 1; i <= m; i++) {
    cin >> x >> y;
    v[x].push_back(y);
    v[y].push_back(x);
    union_sets(x, y);
  }
  memset(vis, 0, sizeof(vis));
  memset(vis1, 0, sizeof(vis1));
  for (i = 1; i <= n; i++) {
    if (!vis[i]) {
      node = find_set(i);
      best = 0;
      dfs(node, 0);
      dfs1(node, 0);
      diameter[find_set(i)] = best;
    }
  }
  while (q--) {
    long long op;
    cin >> op;
    if (op == 1) {
      cin >> x;
      cout << diameter[find_set(x)] << endl;
    } else {
      cin >> x >> y;
      ans = max(diameter[find_set(x)], diameter[find_set(y)]);
      if (find_set(x) != find_set((y))) ans = max(ans, f(x, y));
      union_sets(x, y);
      diameter[find_set(x)] = ans;
    }
  }
  return 0;
}
