#include <bits/stdc++.h>
using namespace std;
const int SIZEN = 300005;
struct edge {
  int to, next;
};
edge e[SIZEN << 1];
int head[SIZEN], sz;
int fa[SIZEN], val[SIZEN];
int ans, ttt;
bool vis[SIZEN], vvis[SIZEN];
void addedge(int u, int v) {
  e[sz].to = v;
  e[sz].next = head[u];
  head[u] = sz++;
}
void dfs1(int u, int ff, int l) {
  if (vis[u]) return;
  vis[u] = 1;
  vvis[u] = 1;
  if (l > ans) {
    ans = l;
    ttt = u;
  }
  for (int i = head[u]; i != -1; i = e[i].next) {
    int v = e[i].to;
    if (v == ff) continue;
    fa[v] = u;
    dfs1(v, u, l + 1);
  }
}
void dfs2(int u, int ff, int l) {
  if (vis[u] == 0) return;
  vis[u] = 0;
  if (l > ans) ans = l;
  for (int i = head[u]; i != -1; i = e[i].next) {
    int v = e[i].to;
    if (v == ff) continue;
    dfs2(v, u, l + 1);
  }
}
void init(int n) {
  for (int i = 1; i <= n; i++) fa[i] = i;
  memset(vis, 0, sizeof(vis[0]) * (n + 2));
  memset(vvis, 0, sizeof(vvis[0]) * (n + 2));
  memset(head, -1, sizeof(head[0]) * (n + 2));
  sz = 0;
}
void Union(int f1, int f2) {
  fa[f1] = f2;
  val[f2] = max(val[f2], (val[f2] + 1) / 2 + (val[f1] + 1) / 2 + 1);
  val[f2] = max(val[f2], val[f1]);
}
int Find(int x) { return x == fa[x] ? x : fa[x] = Find(fa[x]); }
void solve(int n, int m, int q) {
  init(n);
  int u, v;
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    addedge(u, v);
    addedge(v, u);
  }
  for (int i = 1; i <= n; i++) {
    if (!vvis[i]) {
      ans = -1;
      ttt = 0;
      dfs1(i, -1, 0);
      ans = -1;
      dfs2(ttt, -1, 0);
      int f1 = Find(ttt);
      val[f1] = ans;
    }
  }
  while (q--) {
    int op, x, y;
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d", &x);
      printf("%d\n", val[Find(x)]);
    } else {
      scanf("%d%d", &x, &y);
      int f1 = Find(x);
      int f2 = Find(y);
      if (f1 == f2) continue;
      Union(f1, f2);
    }
  }
  return;
}
int main() {
  int n, m, q;
  while (scanf("%d%d%d", &n, &m, &q) != EOF) solve(n, m, q);
}
