#include <bits/stdc++.h>
template <class T>
inline void in(T &x) {
  x = 0;
  register char c = getchar();
  while (!isdigit(c)) c = getchar();
  while (isdigit(c)) x = (x << 1) + (x << 3) + c - 48, c = getchar();
}
int dot, line, q, cnt, root, pos;
int head[300050], dia[300050], bel[300050], dep[300050];
bool vis[300050];
struct Edge {
  int to, nex;
} edge[300050 << 1];
inline void addedge(const int &from, const int &to) {
  edge[++cnt] = {to, head[from]}, head[from] = cnt;
}
namespace DSU {
int find(const int &now) {
  return bel[now] == now ? now : bel[now] = find(bel[now]);
}
inline void combine(register int x, register int y) { bel[x] = find(y); }
}  // namespace DSU
void DFS(const int &now, const int &fa) {
  vis[now] = true;
  if (dep[now] > dep[pos]) pos = now;
  for (register int i = head[now]; i; i = edge[i].nex) {
    if (edge[i].to == fa) continue;
    dep[edge[i].to] = dep[now] + 1;
    DFS(edge[i].to, now);
  }
}
void merge(const int &now, const int &tar, const int &fa) {
  bel[now] = tar;
  for (register int i = head[now]; i; i = edge[i].nex) {
    if (edge[i].to == fa) continue;
    merge(edge[i].to, tar, now);
  }
}
void prework(const int &now) {
  pos = now;
  DFS(now, 0);
  root = pos;
  dep[root] = 0;
  DFS(root, 0);
  dia[root] = dep[pos];
  merge(root, root, 0);
}
int main(void) {
  int a, b, typ;
  in(dot), in(line), in(q);
  for (register int i = 1; i <= line; ++i)
    in(a), in(b), addedge(a, b), addedge(b, a);
  for (register int i = 1; i <= dot; ++i)
    if (!vis[i]) prework(i);
  while (q--) {
    in(typ);
    if (typ & 1)
      in(a), printf("%d\n", dia[DSU::find(a)]);
    else {
      in(a), in(b);
      register int x = DSU::find(a), y = DSU::find(b);
      if (x == y) continue;
      dia[y] = std::max(std::max(dia[y], dia[x]),
                        (dia[y] + 1) / 2 + (dia[x] + 1) / 2 + 1);
      DSU::combine(x, y);
    }
  }
}
