#include <bits/stdc++.h>
using namespace std;
const int dx[] = {0, 0, -1, 1, 1, -1, -1, 1};
const int dy[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int N = 3e5 + 5;
int C[N], p[N];
int diam[N];
int n, m, q;
vector<int> adj[N];
void init() {
  for (int i = 0; i < N; i++) C[i] = 0, p[i] = i;
}
inline int findp(int x) { return x == p[x] ? x : p[x] = findp(p[x]); }
void merge(int u, int v, int d = -1) {
  u = findp(u);
  v = findp(v);
  if (u == v) return;
  if (C[u] < C[v]) swap(u, v);
  p[v] = u;
  if (~d)
    diam[u] =
        max(diam[u], max(diam[v], (diam[u] + 1) / 2 + (diam[v] + 1) / 2 + 1));
  if (C[u] == C[v]) C[u]++;
}
int MAXL;
int MAXNode;
int vis[N];
int visID = 1;
void dfs(int u, int level, int par = -1) {
  if (level > MAXL) MAXL = level, MAXNode = u;
  if (vis[u] == visID) return;
  vis[u] = visID;
  for (int i = 0; i < int((adj[u]).size()); i++)
    if (adj[u][i] != par) dfs(adj[u][i], level + 1, u);
}
int main() {
  int u, v;
  init();
  scanf("%d", &n), scanf("%d", &m), scanf("%d", &q);
  for (int i = 0; i < m; ++i) {
    scanf("%d", &u), scanf("%d", &v);
    u--, v--;
    adj[u].push_back(v);
    adj[v].push_back(u);
    merge(u, v);
  }
  memset(diam, -1, sizeof(diam));
  for (int i = 0; i < n; ++i) {
    int par = findp(i);
    if (diam[par] == -1) {
      MAXL = 0;
      dfs(i, 1);
      visID++;
      MAXL = 0;
      dfs(MAXNode, 1);
      diam[par] = MAXL - 1;
    }
  }
  int type;
  for (int i = 0; i < q; ++i) {
    scanf("%d", &type), scanf("%d", &u);
    if (type == 1) {
      printf("%d\n", diam[findp(u - 1)]);
    } else {
      scanf("%d", &v);
      merge(u - 1, v - 1, 1);
    }
  }
  return 0;
}
