#include <bits/stdc++.h>   using namespace std;   long long MOD = 1e9 + 7;   long long powmod(long long a, long long l, long long md) {     long long res = 1;     while (l) {       if (l & 1) res = res * a % md;       l /= 2;       a = a * a % md;     }     return res;   }   long long binpow(long long a, long long l) {     long long res = 1;     while (l) {       if (l & 1) res = res * a;       l /= 2;       a = a * a;     }     return res;   }   long long __set(long long b, long long i) { return b | (1 << i); }   long long __unset(long long b, long long i) { return b & (~(1UL << i)); }   long long __check(long long b, long long i) { return b & (1 << i); }   long long mulmod(long long a, long long b, long long md) {     return ((a % md) * (b % md)) % md;   }   long long addmod(long long a, long long b, long long md) {     return (a + b) % md;   }   long long submod(long long a, long long b, long long md) {     return (((a - b) % md) + md) % md;   }   long long divmod(long long a, long long b, long long md) {     return mulmod(a, powmod(b, md - 2, md), md);   }   const long long inf = 0xFFFFFFFFFFFFFFFL;   priority_queue<long long, vector<long long>, greater<long long> > pq;   clock_t time_p = clock();   void time() {     time_p = clock() - time_p;     cerr <<  Time Taken :   << (float)(time_p) / CLOCKS_PER_SEC <<   n ;   }   class UnionFind {    private:     vector<long long> p, rank, setCount;     long long NumSets;       public:     UnionFind(long long N) {       NumSets = N;       rank.assign(N, 0);       setCount.assign(N, 1);       p.assign(N, 0);       for (long long i = 0; i < N; i++) p[i] = i;     }     long long findSet(long long i) {       return (p[i] == i) ? i : (p[i] = findSet(p[i]));     }     bool isSameSet(long long i, long long j) { return findSet(i) == findSet(j); }     void unionSet(long long i, long long j) {       if (!isSameSet(i, j)) {         long long x = findSet(i), y = findSet(j);         NumSets--;         if (rank[x] > rank[y]) {           p[y] = x;           setCount[x] += setCount[y];         } else {           p[x] = y;           setCount[y] += setCount[x];           if (rank[x] == rank[y]) rank[y]++;         }       }     }     long long SizeOfSet(long long i) { return setCount[findSet(i)]; }     long long NumDisjointSets() { return NumSets; }   };   vector<vector<long long> > g(300010);   vector<long long> vis(300010, 0);   void dfs(long long u, long long dp, vector<pair<long long, long long> >& dis) {     dis.push_back({dp, u});     vis[u] = 1;     for (long long i = 0; i < (long long)(g[u].size()); i++) {       long long v = g[u][i];       if (!vis[v]) {         dfs(v, dp + 1, dis);       }     }   }   void dfs1(long long u, long long dp, vector<pair<long long, long long> >& dis) {     dis.push_back({dp, u});     vis[u] = 1;     for (long long i = 0; i < (long long)(g[u].size()); i++) {       long long v = g[u][i];       if (!vis[v]) {         dfs(v, dp + 1, dis);       }     }   }   signed main(void) {     ios::sync_with_stdio(0);     cin.tie(0);     cout.tie(0);     ;     long long n, m;     cin >> n >> m;     long long q;     cin >> q;     vector<long long> d(n, 0);     UnionFind uf(n);     for (long long i = 0; i < m; i++) {       long long u, v;       cin >> u >> v;       u--;       v--;       g[u].push_back(v);       g[v].push_back(u);       uf.unionSet(u, v);     }     for (long long i = 0; i < n; i++) {       if (!vis[i]) {         vector<pair<long long, long long> > dis;         dfs(i, 0, dis);         sort((dis).begin(), (dis).end());         long long u = dis[(long long)(dis.size()) - 1].second;         for (long long j = 0; j < (long long)(dis.size()); j++)           vis[dis[j].second] = 0;         dis.clear();         dfs1(u, 0, dis);         sort((dis).begin(), (dis).end());         d[uf.findSet(i)] = dis[(long long)(dis.size()) - 1].first;       }     }     for (long long i = 0; i < q; i++) {       long long ty;       cin >> ty;       if (ty == 1) {         long long x;         cin >> x;         x--;         cout << d[uf.findSet(x)] << endl;         continue;       }       long long u, v;       cin >> u >> v;       u--;       v--;       if (uf.isSameSet(u, v)) continue;       long long dd1 = d[uf.findSet(u)], dd2 = d[uf.findSet(v)];       long long dd = max({dd1, dd2, dd1 / 2 + dd2 / 2 + dd1 % 2 + dd2 % 2 + 1});       uf.unionSet(u, v);       d[uf.findSet(u)] = dd;     }     time();     return 0;   }