#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:256000000")
struct __ {
  __() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
  }
} _;
template <typename I>
inline void in(I l, I r) {
  while (l != r) cin >> *l, ++l;
}
template <typename I>
inline void out(I l, I r, char D = ' ') {
  if (l != r) {
    cout << *l;
    while (++l != r) cout << D << *l;
  }
  cout << '\n';
}
struct debug_t {
  template <typename T>
  debug_t& operator<<(const T& value) {
    return *this;
  }
} debug;
namespace DSU {
vector<int> parent, rank;
void init(int n) {
  parent = vector<int>(n);
  rank = vector<int>(n, 0);
  for (int i = 0; i < (n); ++i) parent[i] = i;
}
int find(int v) {
  if (parent[v] != v) return parent[v] = find(parent[v]);
  return v;
}
int merge(int a, int b) {
  a = find(a);
  b = find(b);
  if (a == b) return a;
  if (rank[a] > rank[b]) swap(a, b);
  parent[a] = b;
  if (rank[a] == rank[b]) ++rank[b];
  return b;
}
}  // namespace DSU
vector<int> mx_dist;
pair<int, int> find_far(vector<vector<int> >& g, int v, int p = -1) {
  pair<int, int> result = make_pair(0, v);
  for (int i = 0; i < (static_cast<int>((g[v]).size())); ++i) {
    int nxt = g[v][i];
    if (nxt != p) {
      pair<int, int> nxt_result = find_far(g, nxt, v);
      nxt_result.first += 1;
      result = max(result, nxt_result);
    }
  }
  return result;
}
int get_color_value(vector<vector<int> >& g, int v) {
  int n = static_cast<int>((g).size());
  pair<int, int> f;
  f = find_far(g, v);
  f = find_far(g, f.second);
  return f.first;
}
void calc_mx_dist(vector<vector<int> >& g) {
  int n = static_cast<int>((g).size());
  vector<int> used(n, 0);
  for (int i = 0; i < (n); ++i) {
    int color = DSU::find(i);
    if (!used[color]) {
      used[color] = 1;
      mx_dist[color] = get_color_value(g, i);
    }
  }
}
void req(int x, int y) {
  x = DSU::find(x);
  y = DSU::find(y);
  if (x != y) {
    int result = (mx_dist[x] + 1) / 2 + (mx_dist[y] + 1) / 2 + 1;
    int res = DSU::merge(x, y);
    mx_dist[res] = max(result, max(mx_dist[x], mx_dist[y]));
  }
}
int main() {
  int n, m, q;
  while (cin >> n >> m >> q) {
    DSU::init(n);
    mx_dist = vector<int>(n, 0);
    vector<vector<int> > g = vector<vector<int> >(n);
    while (m--) {
      int a, b;
      cin >> a >> b;
      --a;
      --b;
      g[a].push_back(b);
      g[b].push_back(a);
      DSU::merge(a, b);
    }
    calc_mx_dist(g);
    while (q--) {
      int code, a, b;
      cin >> code >> a;
      --a;
      if (code == 1)
        cout << mx_dist[DSU::find(a)] << "\n";
      else {
        cin >> b;
        --b;
        req(a, b);
      }
    }
  }
  return 0;
}
