#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int diameter[N], parent[N], sz[N];
bool used[N];
vector<int> graph[N];
int n, m, q, a, b, c, maxDepth, maxVertex;
void dfs(int u, int depth, int parent) {
  if (depth > maxDepth) {
    maxDepth = depth;
    maxVertex = u;
  }
  for (auto v : graph[u]) {
    if (v != parent) {
      dfs(v, depth + 1, u);
    }
  }
}
int getDiameter(int u) {
  maxDepth = -1;
  maxVertex = -1;
  dfs(u, 0, -1);
  maxDepth = -1;
  dfs(maxVertex, 0, -1);
  return maxDepth;
}
int getSet(int x) {
  if (parent[x] == x) return x;
  return parent[x] = getSet(parent[x]);
}
int getCeil(int x) { return (x + 1) / 2; }
void UnionSet1(int u, int v) {
  int x = getSet(u);
  int y = getSet(v);
  if (sz[x] > sz[y]) swap(x, y);
  sz[y] += sz[x];
  parent[x] = y;
}
void UnionSet2(int u, int v) {
  int x = getSet(u);
  int y = getSet(v);
  if (x == y) return;
  if (sz[x] > sz[y]) swap(x, y);
  sz[y] += sz[x];
  parent[x] = y;
  diameter[y] = max(getCeil(diameter[x]) + getCeil(diameter[y]) + 1,
                    max(diameter[x], diameter[y]));
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> q;
  for (int i = 1; i <= n; i++) {
    parent[i] = i;
    sz[i] = 1;
    diameter[i] = 0;
  }
  for (int i = 0; i < m; i++) {
    cin >> a >> b;
    graph[a].push_back(b);
    graph[b].push_back(a);
    UnionSet1(a, b);
  }
  for (int i = 1; i <= n; i++) {
    int par = getSet(i);
    if (!used[par]) {
      used[par] = 1;
      diameter[par] = getDiameter(i);
    }
  }
  for (int i = 1; i <= q; i++) {
    cin >> a;
    if (a == 1) {
      cin >> b;
      cout << diameter[getSet(b)] << "\n";
    } else if (a == 2) {
      cin >> b >> c;
      UnionSet2(b, c);
    }
  }
  return 0;
}
