#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 2;
int par[maxn], path[maxn];
bitset<maxn> mark;
vector<int> adj[maxn];
int maxh[maxn], dp[maxn], first_root[maxn], accentricity[maxn], max_path[maxn];
void getmaxh(int v, int p = -1, int froot = -1) {
  first_root[v] = froot;
  for (auto u : adj[v]) {
    if (u != p) {
      getmaxh(u, v, froot);
      maxh[v] = max(maxh[v], maxh[u] + 1);
    }
  }
}
void getdp(int v, int p = -1) {
  mark[v] = true;
  int mx1 = 0, mx2 = 0, ch = 0;
  for (auto u : adj[v]) {
    if (u != p) {
      if (maxh[u] >= mx1) {
        mx2 = mx1;
        mx1 = maxh[u];
      } else
        mx2 = max(mx2, maxh[u]);
      ch++;
    }
  }
  for (auto u : adj[v]) {
    if (u != p) {
      dp[u] = dp[v] + 1;
      if (maxh[u] != mx1) {
        dp[u] = max(dp[u], 2 + mx1);
      } else if (ch >= 2) {
        dp[u] = max(dp[u], 2 + mx2);
      }
      getdp(u, v);
    }
  }
  accentricity[v] = max(maxh[v], dp[v]);
  max_path[v] = maxh[v] + dp[v];
  if (ch >= 2) max_path[v] = max(max_path[v], mx1 + mx2 + 2);
  for (auto u : adj[v]) {
    if (u != p) max_path[v] = max(max_path[v], max_path[u]);
  }
}
void dfs(int v, int p = -1, int froot = -1) {
  mark[v] = true;
  par[v] = froot;
  for (auto u : adj[v]) {
    if (u != p) {
      dfs(u, v, froot);
    }
  }
}
int root(int v) {
  if (par[v] < 0) return v;
  return par[v] = root(par[v]);
}
void merge(int v, int u) {
  v = root(v);
  u = root(u);
  if (v == u) return;
  if (par[v] > par[u]) swap(v, u);
  int av = -par[v], au = -par[u];
  av--;
  au--;
  path[v] = max(path[v], av + au + 1);
  par[v] = min(par[v], par[u] - 1);
  par[u] = v;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  for (int i = 0; i < m; i++) {
    int v, u;
    cin >> v >> u;
    v--;
    u--;
    adj[v].push_back(u);
    adj[u].push_back(v);
  }
  for (int i = 0; i < n; i++) {
    if (!mark[i]) {
      getmaxh(i, -1, i);
      getdp(i);
    }
  }
  mark = 0;
  for (int i = 0; i < n; i++) {
    if (!mark[i] && (max_path[first_root[i]] + 1) / 2 == accentricity[i]) {
      dfs(i, -1, i);
      par[i] = -accentricity[i] - 1;
      path[i] = max_path[i];
    }
  }
  while (q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int x;
      cin >> x;
      x--;
      cout << path[root(x)] << endl;
    } else {
      int x, y;
      cin >> x >> y;
      x--;
      y--;
      merge(x, y);
    }
  }
}
