#include <bits/stdc++.h>
using namespace std;
const int N = 300000;
int parent[N], value[N];
void Init(int n) {
  for (int i = 0; i < n; i++) {
    parent[i] = i;
    value[i] = 0;
  }
}
int SetFind(int x) {
  return parent[x] = (parent[x] == x ? x : SetFind(parent[x]));
}
void SetUnion(int x, int y) {
  int px = SetFind(x), py = SetFind(y);
  if (px != py) {
    parent[py] = px;
    value[px] = max(max(value[px], value[py]),
                    1 + (value[px] + 1) / 2 + (value[py] + 1) / 2);
  }
}
vector<int> adj[N];
void Dfs(int root, int prev, int depth, int* res, int* node) {
  if (depth > *res) {
    *res = depth;
    *node = root;
  }
  for (const auto& i : adj[root]) {
    if (i == prev) continue;
    Dfs(i, root, depth + 1, res, node);
  }
}
int main() {
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  Init(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    adj[a - 1].push_back(b - 1);
    adj[b - 1].push_back(a - 1);
    SetUnion(a - 1, b - 1);
  }
  for (int i = 0; i < n; i++) {
    if (SetFind(i) == i) {
      int res = 0, node = i;
      Dfs(i, -1, 0, &res, &node);
      int leaf = node;
      res = 0;
      Dfs(leaf, -1, 0, &res, &node);
      value[i] = res;
    }
  }
  int a, b, cmd;
  for (int i = 0; i < q; i++) {
    scanf("%d", &cmd);
    if (cmd == 1) {
      scanf("%d", &a);
      printf("%d\n", value[SetFind(a - 1)]);
    } else {
      scanf("%d %d", &a, &b);
      SetUnion(a - 1, b - 1);
    }
  }
  return 0;
}
