#include <bits/stdc++.h>
using namespace std;
const int N = 3e+5 + 50;
vector<int> adj[N];
int n, m, q;
bool vis[2][N];
int dis[2][N], d[N];
int parent[N], rank1[N];
void make_set(int x) {
  parent[x] = x;
  rank1[x] = 1;
  return;
}
int find_set(int x) {
  if (parent[x] == x) return x;
  return parent[x] = find_set(parent[x]);
}
void munion(int x, int y) {
  int a = find_set(x), b = find_set(y);
  if (a != b) {
    if (rank1[a] < rank1[b]) swap(a, b);
    parent[b] = a;
    if (rank1[a] == rank1[b]) rank1[a]++;
  }
  return;
}
int bfs(int v, int c) {
  queue<int> q;
  q.push(v);
  vis[c][v] = true;
  dis[c][v] = 0;
  int idx = v;
  while (!q.empty()) {
    int u;
    u = q.front();
    if (c == 0) munion(u, v);
    q.pop();
    for (auto it : adj[u]) {
      if (!vis[c][it]) {
        dis[c][it] = dis[c][u] + 1;
        vis[c][it] = true;
        q.push(it);
        if (dis[c][it] > dis[c][idx]) {
          idx = it;
        }
      }
    }
  }
  return idx;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m >> q;
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) make_set(i);
  for (int v = 1; v <= n; v++) {
    if (!vis[0][v]) {
      int u = bfs(v, 0);
      int x = dis[1][bfs(u, 1)];
      d[find_set(v)] = x;
    }
  }
  while (q--) {
    int t;
    cin >> t;
    if (t == 2) {
      int x, y;
      cin >> x >> y;
      int s1 = find_set(x), s2 = find_set(y);
      if (s1 == s2) continue;
      int df = max(1 + (d[s1] + 1) / 2 + (d[s2] + 1) / 2, max(d[s1], d[s2]));
      munion(x, y);
      d[s1] = d[s2] = d[find_set(x)] = df;
    } else {
      int u;
      cin >> u;
      cout << d[find_set(u)] << "\n";
    }
  }
}
