#include <bits/stdc++.h>
using namespace std;
int n, m, q, f[1001000], l[1001000], head[1001000], p[2];
bool vis[1001000];
struct Edge {
  int next, to;
} e[1001000];
int cha(int k) { return k == f[k] ? k : f[k] = cha(f[k]); }
void bing(int k1, int k2) { f[cha(k1)] = cha(k2); }
void read() {
  cin >> n >> m >> q;
  int m1, m2, c = 0;
  for (int i = 1; i <= n; i++) f[i] = i;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &m1, &m2);
    bing(m1, m2);
    e[++c].next = head[m1];
    e[c].to = m2;
    head[m1] = c;
    e[++c].next = head[m2];
    e[c].to = m1;
    head[m2] = c;
  }
}
void dfs1(int k, int len) {
  vis[k] = 1;
  if (len > p[0]) {
    p[0] = len;
    p[1] = k;
  }
  for (int i = head[k]; i; i = e[i].next) {
    if (vis[e[i].to]) continue;
    dfs1(e[i].to, len + 1);
  }
  vis[k] = 0;
  return;
}
int dfs2(int k, int len) {
  int mm = len;
  vis[k] = 1;
  for (int i = head[k]; i; i = e[i].next) {
    if (vis[e[i].to]) continue;
    mm = max(dfs2(e[i].to, len + 1), mm);
  }
  return mm;
}
void init() {
  int fa;
  for (int i = 1; i <= n; i++) {
    fa = cha(i);
    if (l[fa] || fa == i) continue;
    vis[fa] = 1;
    p[0] = p[1] = -1;
    dfs1(fa, 0);
    vis[fa] = 0;
    l[fa] = dfs2(p[1], 0);
  }
}
void merge(int k1, int k2) {
  int f1 = cha(k1), f2 = cha(k2);
  if (f1 == f2) return;
  l[f2] = max(l[f2], ((l[f1] - (l[f1] >> 1)) + (l[f2] - (l[f2] >> 1)) + 1));
  l[f2] = max(l[f2], l[f1]);
  bing(k1, k2);
}
int main() {
  read();
  init();
  int m1, m2;
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &m1, &m2);
    if (m1 & 1) {
      printf("%d\n", l[cha(m2)]);
    } else {
      scanf("%d", &m1);
      merge(m1, m2);
    }
  }
}
