#include <bits/stdc++.h>
using namespace std;
int MOD = 1000000007;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
inline long long toll(string s) {
  long long v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T>
inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
class UnionFind {
 private:
  vector<int> p, rank, setSize;
  int numSets;

 public:
  UnionFind(int N) {
    setSize.assign(N, 1);
    numSets = N;
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++) p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      numSets--;
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
        setSize[x] += setSize[y];
      } else {
        p[x] = y;
        setSize[y] += setSize[x];
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
  int numDisjointSets() { return numSets; }
  int sizeOfSet(int i) { return setSize[findSet(i)]; }
};
vector<vector<int> > g;
int dist = 0;
int furthest = 0;
int longest[1000002];
int done[1000002];
void dfs(int u, int c, int p = -1) {
  done[u] = 1;
  if (c >= dist) {
    dist = c;
    furthest = u;
  }
  for (int v : g[u]) {
    if (p != v) {
      dfs(v, c + 1, u);
    }
  }
}
void getDiameter(int u) {
  dist = 0;
  furthest = 0;
  dfs(u, 0);
  dfs(furthest, 0);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  UnionFind uf(n);
  g.assign(n, vector<int>());
  int tempU = -1;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    tempU = u;
    g[u].push_back(v);
    g[v].push_back(u);
    uf.unionSet(u, v);
  }
  for (int i = 0; i < n; i++) {
    if (!done[i]) {
      getDiameter(i);
      longest[uf.findSet(i)] = dist;
    }
  }
  while (q--) {
    int c, u, v;
    cin >> c >> u;
    u--;
    if (c == 1) {
      cout << longest[uf.findSet(u)] << endl;
      continue;
    }
    cin >> v;
    v--;
    if (uf.isSameSet(u, v)) {
      continue;
    }
    int p1 = uf.findSet(u), p2 = uf.findSet(v);
    int sz1 = (longest[p1] + 1) / 2, sz2 = (longest[p2] + 1) / 2;
    uf.unionSet(p1, p2);
    int p = uf.findSet(p1);
    longest[p] = max(sz1 + sz2 + 1, max(longest[p1], longest[p2]));
  }
  return 0;
}
