#include <bits/stdc++.h>
using namespace std;
class DSet {
  vector<int> father;

 public:
  DSet(int N) {
    father.resize(N);
    for (int i = 0; i < N; i++) father[i] = i;
  }
  int findset(int x) {
    if (father[x] == x) return x;
    return father[x] = findset(father[x]);
  }
  void unionset(int a, int b) { father[findset(a)] = findset(b); }
};
struct Node {
  bool visited;
  Node() { visited = false; }
};
struct Graph {
  vector<Node> nodes;
  vector<vector<int>> alist;
  Graph(int N) {
    nodes.resize(N, Node());
    alist.resize(N);
  }
  void addEdge(int a, int b) {
    alist[a].push_back(b);
    alist[b].push_back(a);
  }
};
int dfsVisit(Graph& g, DSet& ds, int node, vector<int>& diameters) {
  int maxDepth = 0;
  g.nodes[node].visited = true;
  for (int child : g.alist[node]) {
    if (!g.nodes[child].visited) {
      int depth = dfsVisit(g, ds, child, diameters) + 1;
      diameters[ds.findset(node)] =
          max(diameters[ds.findset(node)], depth + maxDepth);
      maxDepth = max(maxDepth, depth);
    }
  }
  return maxDepth;
}
void dfs(Graph& g, DSet& ds, vector<int>& diameters) {
  for (int i = 0; i < g.nodes.size(); i++) {
    if (!g.nodes[i].visited) dfsVisit(g, ds, i, diameters);
  }
}
inline int pathRadius(int diam) { return (diam / 2) + (diam & 1); }
void myunion(DSet& ds, vector<int>& diameters, int u, int v) {
  if (ds.findset(u) == ds.findset(v)) return;
  int d1 = diameters[ds.findset(u)], d2 = diameters[ds.findset(v)];
  int r1 = pathRadius(d1);
  int r2 = pathRadius(d2);
  int ndiameter = max(d1, max(d2, r1 + r2 + 1));
  ds.unionset(u, v);
  diameters[ds.findset(u)] = ndiameter;
}
int main() {
  int n, m, q, u, v;
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  while (cin >> n >> m >> q) {
    Graph g(n);
    DSet ds(n);
    for (int i = 0; i < m; i++) {
      cin >> u >> v;
      u--;
      v--;
      g.addEdge(u, v);
      ds.unionset(u, v);
    }
    vector<int> diameters(n, 0);
    dfs(g, ds, diameters);
    int type;
    for (int i = 0; i < q; i++) {
      cin >> type;
      if (type == 1) {
        cin >> u;
        u--;
        cout << diameters[ds.findset(u)] << endl;
      } else {
        cin >> u >> v;
        u--;
        v--;
        myunion(ds, diameters, u, v);
      }
    }
  }
}
