#include <bits/stdc++.h>
using namespace std;
vector<int> diameters;
class Union {
 public:
  vector<int> parent;
  vector<int> rank;
  Union(int size) {
    parent.resize(size);
    rank.resize(size);
    for (int i = 0; i < size; i++) {
      parent[i] = i;
    }
  }
  int find(int a) {
    if (parent[a] != a) {
      parent[a] = find(parent[a]);
    }
    return parent[a];
  }
  void merge(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b) {
      return;
    }
    if (rank[a] < rank[b]) {
      parent[a] = b;
    } else {
      parent[b] = a;
      if (rank[a] == rank[b]) {
        rank[a]++;
      }
    }
  }
  void best_merge(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b) {
      return;
    }
    if (rank[a] < rank[b]) {
      parent[a] = b;
      diameters[b] = max(max(diameters[a], diameters[b]),
                         (diameters[a] + 1) / 2 + (diameters[b] + 1) / 2 + 1);
    } else {
      parent[b] = a;
      diameters[a] = max(max(diameters[a], diameters[b]),
                         (diameters[a] + 1) / 2 + (diameters[b] + 1) / 2 + 1);
      if (rank[a] == rank[b]) {
        rank[a]++;
      }
    }
  }
};
int n;
int m;
int q;
vector<vector<int> > graph;
Union* set2;
vector<int> dist;
vector<bool> visited;
int dfs_visit(int s) {
  queue<int> Q;
  queue<int> P;
  dist[s] = 0;
  Q.push(s);
  int u = s;
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    visited[u] = true;
    P.push(u);
    for (int v : graph[u]) {
      if (!visited[v]) {
        dist[v] = dist[u] + 1;
        Q.push(v);
      }
    }
  }
  int v;
  while (!P.empty()) {
    v = P.front();
    P.pop();
    visited[v] = false;
  }
  return u;
}
int main() {
  scanf("%d %d %d", &n, &m, &q);
  graph.resize(n);
  visited.resize(n);
  diameters.resize(n);
  dist.resize(n, -1);
  set2 = new Union(n);
  for (int i = 0; i < m; i++) {
    int u;
    int v;
    scanf("%d", &u);
    scanf("%d", &v);
    u--;
    v--;
    graph[u].push_back(v);
    graph[v].push_back(u);
    set2->merge(u, v);
  }
  int node;
  int comp;
  for (int u = 0; u < n; u++) {
    comp = set2->find(u);
    if (diameters[comp]) {
      continue;
    }
    node = dfs_visit(dfs_visit(u));
    diameters[comp] = dist[node];
  }
  int type;
  int u;
  int v;
  int d1, d2;
  int diameter;
  int min_diameter;
  int max_diameter;
  int fix_diameter;
  int city;
  for (int i = 0; i < q; i++) {
    scanf("%d", &type);
    if (type == 1) {
      scanf("%d", &city);
      printf("%d\n", diameters[set2->find(city - 1)]);
    }
    if (type == 2) {
      scanf("%d %d", &u, &v);
      u = set2->find(u - 1);
      v = set2->find(v - 1);
      if (u == v) {
        continue;
      }
      set2->best_merge(u, v);
    }
  }
  return 0;
}
