#include <bits/stdc++.h>   using namespace std;   int Set(int n, int pos) { return n = n | (1LL << pos); }   int reset(int n, int pos) { return n = n & ~(1LL << pos); }   bool check(int n, int pos) { return (bool)(n & (1LL << pos)); }   int mul(int a, int b) {     int c;     c = (a % 1000000007 * b % 1000000007) % 1000000007;     return c;   }   int add(int a, int b) {     int c;     c = (a % 1000000007 + b % 1000000007) % 1000000007;     return c;   }   int sub(int a, int b) {     int c;     c = ((a % 1000000007 - b % 1000000007) % 1000000007 + 1000000007) %         1000000007;     return c;   }   int par[300005];   int dis[300005];   int dia[300005];   vector<int> graph[300005];   int n, m, q;   void cle_par() {     for (int i = 1; i <= n; i++) {       par[i] = i;       dis[i] = -1;     }   }   int find_pr(int r) {     if (par[r] == r) {       return r;     }     return par[r] = find_pr(par[r]);   }   void in_edges() {     int u, v;     for (int i = 1; i <= m; i++) {       scanf( %d , &u);       scanf( %d , &v);       graph[u].push_back(v);       graph[v].push_back(u);       u = find_pr(u);       v = find_pr(v);       if (u != v) {         par[u] = v;       }     }   }   void bfs(int main_src) {     deque<int> q;     vector<int> nod;     dis[main_src] = 0;     q.push_back(main_src);     nod.push_back(main_src);     while (!q.empty()) {       int src = q.front();       q.pop_front();       for (int i = 0; i < graph[src].size(); i++) {         int adj = graph[src][i];         if (dis[adj] == -1) {           dis[adj] = dis[src] + 1;           q.push_back(adj);           nod.push_back(adj);         }       }     }     int maxi_dis = -1;     int maxi_nod;     for (int i = 0; i < nod.size(); i++) {       if (dis[nod[i]] > maxi_dis) {         maxi_dis = dis[nod[i]];         maxi_nod = nod[i];       }       dis[nod[i]] = -1;     }     dis[maxi_nod] = 0;     q.push_back(maxi_nod);     nod.push_back(maxi_nod);     while (!q.empty()) {       int src = q.front();       q.pop_front();       for (int i = 0; i < graph[src].size(); i++) {         int adj = graph[src][i];         if (dis[adj] == -1) {           dis[adj] = dis[src] + 1;           q.push_back(adj);         }       }     }     maxi_dis = -1;     for (int i = 0; i < nod.size(); i++) {       if (dis[nod[i]] > maxi_dis) {         maxi_dis = dis[nod[i]];       }     }     dia[main_src] = maxi_dis;   }   void making_dia() {     for (int i = 1; i <= n; i++) {       if (par[i] == i) {         bfs(i);       }     }   }   int main() {     scanf( %d , &n);     scanf( %d , &m);     scanf( %d , &q);     cle_par();     in_edges();     making_dia();     for (int i = 1; i <= q; i++) {       int type;       scanf( %d , &type);       if (type == 1) {         int x;         scanf( %d , &x);         int u = find_pr(x);         printf( %d n , dia[u]);       } else if (type == 2) {         int x, y;         scanf( %d , &x);         scanf( %d , &y);         int u = find_pr(x);         int v = find_pr(y);         if (u == v) {           continue;         } else {           double first = (double)dia[u];           first /= 2.00;           first -= 0.0000000001;           first = ceil(first);           double second = (double)dia[v];           second /= 2.00;           second -= 0.0000000001;           second = ceil(second);           int uuu = (int)first;           int vvv = (int)second;           int tot_dia = uuu + vvv + 1;           dia[v] = max(dia[u], max(dia[v], tot_dia));           par[u] = v;         }       }     }     return 0;   }