#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[200005];
int a[100005],f[100005],h[100005],rank[100005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        int y=e[i].to;
        if(y!=prt)dfs(y,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
    for(from=1;from<=n;++from)
    {
        if(f[from])continue;
        ans=0;dfs(from,0,1);
        ans=0;dfs(point,0,1);
        a[x]=ans;
    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[300005];
int a[300005],f[300005],h[300005],rank[300005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        if(e[i].to!=prt)dfs(e[i].to,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
	for(from=1;from<=n;++from)
    {
        if(!f[from])
        {
        	ans=-1;dfs(from,0,0);
        	ans=-1;dfs(point,0,0);
		}
        a[from]=ans;
    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[200005];
int a[100005],f[100005],h[100005],rank[100005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        int y=e[i].to;
        if(y!=prt)dfs(y,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
	for(from=1;from<=n;++from)
    {
        if(f[from])continue;
        ans=-1;dfs(from,0,0);
        ans=-1;dfs(point,0,0);
        a[from]=ans;
    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[300005];
int a[300005],f[300005],h[300005],rank[300005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        int y=e[i].to;
        if(y!=prt)dfs(y,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
	for(from=1;from<=n;++from)
    {
        if(!f[from])
        {
        	ans=-1;dfs(from,0,0);
        	ans=-1;dfs(point,0,0);
		}
        a[from]=ans;
    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[200005];
int a[100005],f[100005],h[100005],rank[100005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        int y=e[i].to;
        if(y!=prt)dfs(y,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
	for(from=1;from<=n;++from)
    {
        if(!f[from])
        {
        	ans=-1;dfs(from,0,0);
        	ans=-1;dfs(point,0,0);
		}
        a[from]=ans;
    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[200005];
int a[100005],f[100005],h[100005],rank[100005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        int y=e[i].to;
        if(y!=prt)dfs(y,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
    for(from=1;from<=n;++from)
    {
        if(f[from])continue;
        ans=0;dfs(from,0,0);
        ans=0;dfs(point,0,0);
        a[from]=ans;
    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rank Rank
using namespace std;
struct Node
{
    int to,next;
}e[200005];
int a[100005],f[100005],h[100005],rank[100005];
int ans,point,from,cnt=0;
inline void Addedge(int x,int y)
{
    e[++cnt]=(Node){y,h[x]};h[x]=cnt;return;
}
inline int GetFather(int x)
{
    if(f[x]==x)return x;
    else return f[x]=GetFather(f[x]);
}
inline void Merge(int x,int y)
{
    x=GetFather(x);
    y=GetFather(y);
    if(x==y)return;
    if(rank[x]<rank[y])
    {
        f[x]=y;
        a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    else
    {
        f[y]=x;
        a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    }
    return;
}
inline void dfs(int x,int prt,int dep)
{
    f[x]=from;
    if(dep>ans){ans=dep;point=x;}
    for(int i=h[x];i;i=e[i].next)
    {
        int y=e[i].to;
        if(y!=prt)dfs(y,x,dep+1);
    }
    return;
}
int main(void)
{
    int i,n,m,q,op,x,y;
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        Addedge(x,y);Addedge(y,x);
    }
    if(m)
		for(from=1;from<=n;++from)
	    {
	        if(f[from])continue;
	        ans=-1;dfs(from,0,0);
	        ans=-1;dfs(point,0,0);
	        a[from]=ans;
	    }
    for(i=1;i<=q;++i)
    {
        scanf("%d%d",&op,&x);
        if(op==2)
        {
            scanf("%d",&y);
            Merge(x,y);
        }
        else printf("%d\n",a[GetFather(x)]);
    }
    return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		if(!d[fin(i)])
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);
			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[fin(i)]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			int tmp=max(d[x],d[y]);
			x=d[x],y=d[y];

			if(x%2)x++;x/=2;
			if(y%2)y++;y/=2;

			mg(u,v);
			d[fin(u)]=max(x+y+1,tmp);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q,ans,ed;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
		fa[x]=y;
}

void dfs(int u,int fa,int dis)
{
	if(g[u].size()==1&&g[u][0]==fa)
	{
		if(dis>ans)
		{
			ans=dis;
			ed=u;
		}
		return;
	}
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		dfs(v,u,dis+1);
	}
}

void clean(int u,int fa)
{
	dp[u]=-1;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		clean(v,u);
	}
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(!d[u]&&g[i].size()>0)
		{
			int x;
			ans=0;
			dfs(i,0,0);
			ans=0;
			dfs(ed,0,0);

			d[u]=ans;

		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		if(!d[fin(i)])
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);
			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[fin(i)]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
		fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(g[i].size()>0)
		{
			memset(dp,-1,sizeof(dp));
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);

			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[u]=max(x,d[u]);
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;
int cnt[maxn];

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
	{
		if(cnt[x]>cnt[y])
		{
			fa[y]=x;
			cnt[x]++;
		}
		else if(cnt[x]<cnt[y])
		{
			fa[x]=y;
			cnt[y]++;
		}
		else
		{
			if(g[x].size()>g[y].size())
			{
				fa[y]=x;
				cnt[x]++;
			}
			else
			{
				fa[x]=y;
				cnt[y]++;
			}
		}
	}
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(!d[u])
		{
			int x;

			dfs(u,0);
			sort(g[u].begin(),g[u].end(),cmp);

			if(g[u].size()<=1)
				x=dp[u];
			else
				x=dp[g[u][0]]+dp[g[u][1]]+2;

			d[u]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
		fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

void clean(int u,int fa)
{
	dp[u]=-1;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		dfs(v,u);
	}
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));
	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(g[i].size()>0)
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);

			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[u]=max(x,d[u]);

			clean(i,0);
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q,ans,ed;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
		fa[x]=y;
}

void dfs(int u,int fa,int dis)
{
	if(g[u].size()==1&&g[u][0]==fa)
	{
		if(dis>ans)
		{
			ans=dis;
			ed=u;
		}
		return;
	}
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		dfs(v,u,dis+1);
	}
}

void clean(int u,int fa)
{
	dp[u]=-1;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		clean(v,u);
	}
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(!d[u]&&g[i].size()>0)
		{
			int x;
			ans=0;
			dfs(i,0,0);
			ans=0;
			dfs(ed,0,0);

			d[u]=ed;

		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		if(!d[fin(i)])
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);
			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[fin(i)]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			d[y]=max(d[y],d[x]);
			x=d[x],y=d[y];

			if(x%2)x++;x/=2;
			if(y%2)y++;y/=2;

			mg(u,v);
			d[fin(u)]=max(x+y+1,d[fin(u)]);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;
int cnt[maxn];

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
	{
		fa[x]=y;
		cnt[y]+=cnt[x];
	}
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
		cnt[i]=1;
	}
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(!d[u]&&!(g[i].size()==1&&cnt[u]>2))
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);

			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[u]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
		fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

void clean(int u,int fa)
{
	dp[u]=-1;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		clean(v,u);
	}
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(g[i].size()>0)
		{
			int x;

			dfs(i,0);

			sort(g[i].begin(),g[i].end(),cmp);

			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[u]=max(x,d[u]);

			clean(i,0);
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		if(!d[fin(i)])
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);
			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[fin(i)]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			if(x%2)x++;x/=2;
			if(y%2)y++;y/=2;

			mg(u,v);
			d[fin(u)]=x+y+1;
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
		fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

void clean(int u,int fa)
{
	dp[u]=-1;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		dfs(v,u);
	}
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(g[i].size()>0)
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);

			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[u]=max(x,d[u]);
			clean(i,0);
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;
int cnt[maxn];

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
	{
		fa[x]=y;
		cnt[y]++;
	}
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
		cnt[i]=1;
	}
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		int u=fin(i);
		if(!d[u]&&!(g[i].size()==1&&cnt[u]>2))
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);

			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[u]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)
	{
		if(g[x].size()>g[y].size())
			fa[y]=x;
		else fa[x]=y;
	}
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		if(!d[fin(i)])
		{
			int x;
			int u=fin(i);
			dfs(u,0);
			sort(g[u].begin(),g[u].end(),cmp);
			if(g[u].size()<=1)
				x=dp[u];
			else
				x=dp[g[u][0]]+dp[g[u][1]]+2;

			d[u]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			mg(u,v);
			d[fin(u)]=max(max(x,y),(x+1)/2+(y+1)/2+1);
		}
	}
}


#include<bits/stdc++.h>
#define pb push_back
#define maxn 300005

using namespace std;
vector<int>g[maxn];
int fa[maxn],dp[maxn],d[maxn],n,m,q;

int fin(int u)
{
	return fa[u]==u?u:fa[u]=fin(fa[u]);
}

void mg(int u,int v)
{
	int x=fin(u),y=fin(v);
	if(x!=y)fa[x]=y;
}

int dfs(int u,int fa)
{
	int &ans=dp[u];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v==fa)continue;
		ans=max(ans,dfs(v,u)+1);
	}
	return ans;
}

bool cmp(int u,int v)
{
	return dp[u]>dp[v];
}

int main()
{

	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	memset(dp,-1,sizeof(dp));

	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(v);
		g[v].pb(u);
		mg(u,v);
	}

	for(int i=1;i<=n;i++)
	{
		if(!d[fin(i)])
		{
			int x;
			dfs(i,0);
			sort(g[i].begin(),g[i].end(),cmp);
			if(g[i].size()<=1)
				x=dp[i];
			else
				x=dp[g[i][0]]+dp[g[i][1]]+2;

			d[fin(i)]=x;
		}
	}

	while(q--)
	{
		int x,u,v;
		scanf("%d",&x);
		if(x==1)
		{
			scanf("%d",&u);
			printf("%d\n",d[fin(u)]);
		}
		else
		{
			scanf("%d%d",&u,&v);
			int x=fin(u),y=fin(v);
			if(x==y)continue;
			x=d[x],y=d[y];

			if(x%2)x++;x/=2;
			if(y%2)y++;y/=2;

			mg(u,v);
			d[fin(u)]=max(x+y+1,d[fin(u)]);
		}
	}
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

vector<int> adjList[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
int far,dist;
void dfs(int u,int prev,int& comp,int tot){
	vis[u] = true;
	p[u] = comp;
	if(tot >= dist){
		far = u;
		dist = tot;
	}
	for(int i=0;i<adjList[u].size();i++) if(adjList[u][i] != prev) dfs(adjList[u][i],u,comp,tot+1);
}
int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		far = i;dist = 0;
		dfs(i,-1,i,0);
		dist = 0;
		dfs(far,-1,i,0);
		l[i] = dist;
		h[i] = (dist+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = min(hx+1,hy+1);
}
bool vis[300010];
pair<int,int> dfs(int u,int prev,vector< vector<int> >&adjList){
	vis[u] = true;
	if( (adjList[u].size() == 1 && adjList[u][0] == prev) || adjList[u].size() == 0){
		return make_pair(0,u);
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		pair<int,int> x = dfs(v,u,adjList);
		if(x.first >= ret.first) ret = x;
	}
	ret.first += 1;
	return ret;
}
int main(){
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
		mergeS(x,y);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		pair<int,int> x = dfs(i,-1,adjList);
		x = dfs(x.second,-1,adjList);
		int y = getS(i);
		l[y] = x.first;
		h[y] = (x.first+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int p[300010];
int r[300010];
int m[300010];

pair<int,int> dfs(int pa,int u,vector< vector<int> >& adjList){
	pair<int,int> far = make_pair(0,u);
	for(int i=0;i<adjList[u].size();i++){
		if(u == pa) continue;
		int v = adjList[u][i];
		pair<int,int> ret = dfs(u,v,adjList);
		if(ret.first+1 > far.first){
			far = ret;
			far.first += 1;
		}
	}
	return far;
}

int findS(int x){
	if(p[x] != x) p[x] = findS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = findS(x);
	int py = findS(y);
	if(px == py) return;
	if(r[px] >= r[py]){
		m[px] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[py] = px;
	}else{
		m[py] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[px] = py;
	}
	if(r[px] == r[py]) r[px] += 1;
}

int getMax(int u,vector< vector<int> > & adjList){
	pair<int,int> far = dfs(-1,u,adjList);
	return dfs(-1,far.second,adjList).first;
}

int main(){
	int N,M,Q;cin>>N>>M>>Q;
	vector< vector<int> > adjList(N);

	for(int i=0;i<N;i++){
		p[i] = i;
		m[i] = -1;
	}

	for(int i=0;i<M;i++){
		int a,b;cin>>a>>b;
		a--;b--;
		adjList[a].push_back(b);
		adjList[b].push_back(a);
		mergeS(a,b);
	}

	for(int i=0;i<N;i++){
		int p = findS(i);
		if(m[p] == -1) continue;
		else m[p] = getMax(i,adjList);
	}

	for(int i=0;i<Q;i++){
		int q;cin>>q;
		if(q == 1){
			int x;cin>>x;x--;
			cout<<m[findS(x)]<<endl;
		}else{
			int u,v;cin>>u>>v;
			u--;v--;
			mergeS(u,v);
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
int far,dist;
void dfs(int u,int prev,vector< vector<int> >&adjList,int& comp,int tot){
	vis[u] = true;
	p[u] = comp;
	if(tot >= dist){
		far = u;
		dist = tot;
	}
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		dfs(v,u,adjList,comp,tot+1);
	}
}
int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		far = i;dist = 0;
		dfs(i,-1,adjList,i,0);
		dist = 0;
		dfs(far,-1,adjList,i,0);
		l[i] = dist;
		h[i] = (dist+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int p[300010];
int r[300010];
int m[300010];

pair<int,int> dfs(int pa,int u,vector< vector<int> >& adjList){
	pair<int,int> far = make_pair(0,u);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == pa) continue;
		pair<int,int> ret = dfs(u,v,adjList);
		if(ret.first+1 > far.first){
			far = ret;
			far.first += 1;
		}
	}
	return far;
}

int findS(int x){
	if(p[x] != x) p[x] = findS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = findS(x);
	int py = findS(y);
	if(px == py) return;
	if(r[px] > r[py]){
		m[px] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[py] = px;
	}else{
		m[py] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[px] = py;
	}
	if(r[px] == r[py]) r[py] += 1;
}

int getMax(int u,vector< vector<int> > & adjList){
	pair<int,int> far = dfs(-1,u,adjList);
	return dfs(-1,far.second,adjList).first;
}

int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	vector< vector<int> > adjList(N);

	for(int i=0;i<N;i++) p[i] = i;

	for(int i=0;i<M;i++){
		int a,b;cin>>a>>b;
		a--;b--;
		adjList[a].push_back(b);
		adjList[b].push_back(a);
		mergeS(a,b);
	}

	for(int i=0;i<N;i++) m[i] = -1;

	for(int i=0;i<N;i++){
		int p = findS(i);
		if(m[p] != -1) continue;
		else m[p] = getMax(i,adjList);
	}

	for(int i=0;i<Q;i++){
		int q;cin>>q;
		if(q == 1){
			int x;cin>>x;x--;
			cout<<m[findS(x)]<<endl;
		}else{
			int u,v;cin>>u>>v;
			u--;v--;
			mergeS(u,v);
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int p[300010];
int r[300010];
int m[300010];

pair<int,int> dfs(int pa,int u,vector< vector<int> >& adjList){
	pair<int,int> far = make_pair(0,u);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == pa) continue;
		pair<int,int> ret = dfs(u,v,adjList);
		if(ret.first+1 > far.first){
			far = ret;
			far.first += 1;
		}
	}
	return far;
}

int findS(int x){
	if(p[x] != x) p[x] = findS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = findS(x);
	int py = findS(y);
	if(px == py) return;
	if(r[px] >= r[py]){
		m[px] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[py] = px;
	}else{
		m[py] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[px] = py;
	}
	if(r[px] == r[py]) r[px] += 1;
}

int getMax(int u,vector< vector<int> > & adjList){
	pair<int,int> far = dfs(-1,u,adjList);
	return dfs(-1,far.second,adjList).first;
}

int main(){
	int N,M,Q;cin>>N>>M>>Q;
	vector< vector<int> > adjList(N);

	for(int i=0;i<N;i++) p[i] = i;

	for(int i=0;i<M;i++){
		int a,b;cin>>a>>b;
		a--;b--;
		adjList[a].push_back(b);
		adjList[b].push_back(a);
		mergeS(a,b);
	}

	for(int i=0;i<N;i++) m[i] = -1;

	for(int i=0;i<N;i++){
		int p = findS(i);
		if(m[p] != -1) continue;
		else m[p] = getMax(i,adjList);
	}

	for(int i=0;i<Q;i++){
		int q;cin>>q;
		if(q == 1){
			int x;cin>>x;x--;
			cout<<m[findS(x)]<<endl;
		}else{
			int u,v;cin>>u>>v;
			u--;v--;
			mergeS(u,v);
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = min(hx+1,hy+1);
}

int main(){
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
	}
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		mergeS(x,y);
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
pair<int,int> dfs(int u,int prev,vector< vector<int> >&adjList){
	vis[u] = true;
	if( (adjList[u].size() == 1 && adjList[u][0] == prev) || adjList[u].size() == 0){
		return make_pair(0,u);
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		pair<int,int> x = dfs(v,u,adjList);
		if(x.first >= ret.first) ret = x;
	}
	ret.first += 1;
	return ret;
}
int main(){
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
		mergeS(x,y);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		pair<int,int> x = dfs(i,-1,adjList);
		x = dfs(x.second,-1,adjList);
		int y = getS(i);
		l[y] = x.first;
		h[y] = (x.first+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int p[300010];
int r[300010];
int m[300010];

pair<int,int> dfs(int pa,int u,vector< vector<int> >& adjList){
	pair<int,int> far = make_pair(0,u);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == pa) continue;
		pair<int,int> ret = dfs(u,v,adjList);
		if(ret.first+1 > far.first){
			far = ret;
			far.first += 1;
		}
	}
	return far;
}

int findS(int x){
	if(p[x] != x) p[x] = findS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = findS(x);
	int py = findS(y);
	if(px == py) return;
	if(r[px] >= r[py]){
		m[px] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[py] = px;
	}else{
		m[py] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[px] = py;
	}
	if(r[px] == r[py]) r[px] += 1;
}

int getMax(int u,vector< vector<int> > & adjList){
	pair<int,int> far = dfs(-1,u,adjList);
	return dfs(-1,far.second,adjList).first;
}

int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	vector< vector<int> > adjList(N);

	for(int i=0;i<N;i++) p[i] = i;

	for(int i=0;i<M;i++){
		int a,b;cin>>a>>b;
		a--;b--;
		adjList[a].push_back(b);
		adjList[b].push_back(a);
		mergeS(a,b);
	}

	for(int i=0;i<N;i++) m[i] = -1;

	for(int i=0;i<N;i++){
		int p = findS(i);
		if(m[p] != -1) continue;
		else m[p] = getMax(i,adjList);
	}

	for(int i=0;i<Q;i++){
		int q;cin>>q;
		if(q == 1){
			int x;cin>>x;x--;
			cout<<m[findS(x)]<<endl;
		}else{
			int u,v;cin>>u>>v;
			u--;v--;
			mergeS(u,v);
		}
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

vector<int> adjList[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
int far,dist;
void dfs(int u,int prev,int& comp,int tot){
	vis[u] = true;
	p[u] = comp;
	if(tot >= dist){
		far = u;
		dist = tot;
	}
	for(int i=0;i<adjList[u].size();i++) if(adjList[u][i] != prev) dfs(adjList[u][i],u,comp,tot+1);
}
int main(){
	int N,M,Q;scanf("%d %d %d",&N,&M,&Q);
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	for(int i=0;i<M;i++){
		int x,y;scanf("%d %d",&x,&y);
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		far = i;dist = 0;
		dfs(i,-1,i,0);
		dist = 0;
		dfs(far,-1,i,0);
		l[i] = dist;
		h[i] = (dist+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;scanf("%d",&x);x--;
			x = getS(x);
			printf("%d\n",l[x]);
		}else{
			int x,y;
			scanf("%d %d",&x,&y);
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
pair<int,int> dfs(int u,int prev,vector< vector<int> >&adjList,int comp){
	vis[u] = true;
	p[u] = comp;
	if( (adjList[u].size() == 1 && adjList[u][0] == prev) || adjList[u].size() == 0){
		return make_pair(0,u);
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		pair<int,int> x = dfs(v,u,adjList,comp);
		if(x.first >= ret.first) ret = x;
	}
	ret.first += 1;
	return ret;
}
int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
		//mergeS(x,y);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	int comp = 0;
	for(int i=0;i<N;i++) if(vis[i] == false){
		pair<int,int> x = dfs(i,-1,adjList,i);
		x = dfs(x.second,-1,adjList,i);
		int y = getS(i);
		l[y] = x.first;
		h[y] = (x.first+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
pair<int,int> dfs(int u,int prev,vector< vector<int> >&adjList){
	vis[u] = true;
	if( (adjList[u].size() == 1 && adjList[u][0] == prev) || adjList[u].size() == 0){
		return make_pair(0,u);
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		pair<int,int> x = dfs(v,u,adjList);
		if(x.first >= ret.first) ret = x;
	}
	ret.first += 1;
	return ret;
}
int main(){
ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
		mergeS(x,y);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		pair<int,int> x = dfs(i,-1,adjList);
		x = dfs(x.second,-1,adjList);
		int y = getS(i);
		l[y] = x.first;
		h[y] = (x.first+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = min(hx+1,hy+1);
}
bool vis[300010];
pair<int,int> dfs(int u,int prev,vector< vector<int> >&adjList){
	vis[u] = true;
	if(adjList[u].size() == 1 && adjList[u][0] == prev){
		return make_pair(0,u);
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		pair<int,int> x = dfs(v,u,adjList);
		if(x.first > ret.first) ret = x;
	}
	ret.first += 1;
	return ret;
}
int main(){
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
		mergeS(x,y);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		pair<int,int> x = dfs(i,-1,adjList);
		x = dfs(x.second,-1,adjList);
		int y = getS(i);
		l[y] = x.first;
		h[y] = (x.first+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
int far,dist;
void dfs(int u,int prev,vector< vector<int> >&adjList,int& comp,int tot){
	vis[u] = true;
	p[u] = comp;
	if( (adjList[u].size() == 1 && adjList[u][0] == prev) || adjList[u].size() == 0){
		if(tot >= far){
			far = u;
			dist = tot;
		}
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		dfs(v,u,adjList,comp,tot+1);
	}
}
int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		far = i;dist = 0;
		dfs(i,-1,adjList,i,0);
		dfs(far,-1,adjList,i,0);
		l[i] = dist;
		h[i] = (dist+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MX=300100;
int n,m,q,x,y,t,best,w,a[MX],p[MX],r[MX];
vector<int> g[MX];
int fs(int x) {
  if (x!=p[x]) p[x]=fs(p[x]);
  return p[x];
}
void un(int x, int y) {
  if (x==y) return;
  if (r[x]<r[y]) {
    p[x]=y;
    a[y]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
  } else {
    p[y]=x;
    a[x]=max(max(a[x],a[y]),(a[x]+1)/2+(a[y]+1)/2+1);
    if (r[x]==r[y]) r[x]++;
  }
}
void dfs(int i, int prev, int d) {
  p[i]=x;
  if (d>best) { best=d; w=i; }
  for (int j=0; j<g[i].size(); j++) if (g[i][j]!=prev) dfs(g[i][j],i,d+1);
}
int main() {
  scanf("%d%d%d",&n,&m,&q);
  while (m--) {
    scanf("%d%d",&x,&y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (x=1; x<=n; x++) if (!p[x]) {
    best=-1; dfs(x,0,0);
    best=-1; dfs(w,0,0);
    a[x]=best;
  }
  while (q--) {
    scanf("%d%d",&t,&x);
    if (t==2) {
      scanf("%d",&y);
      un(fs(x),fs(y));
    } else printf("%d\n",a[fs(x)]);
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

int r[300010];
int p[300010];
//Longest path
int l[300010];
//Head length
int h[300010];

int getS(int x){
	if(p[x] != x) p[x] = getS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = getS(x),py = getS(y);
	if(px == py) return;
	int hx = h[px],hy = h[py];
	int lx = l[px],ly = l[py];
	if(r[px] > r[py]) p[py] = px;
	else p[px] = py;
	if(r[px] == r[py]) r[py] += 1;
	int pn = p[px];
	l[pn] = max(1+hx+hy,max(lx,ly));
	h[pn] = (l[pn]+1)/2;
}
bool vis[300010];
int far,dist;
void dfs(int u,int prev,vector< vector<int> >&adjList,int& comp,int tot){
	vis[u] = true;
	p[u] = comp;
	if( (adjList[u].size() == 1 && adjList[u][0] == prev) || adjList[u].size() == 0){
		if(tot >= dist){
			far = u;
			dist = tot;
		}
	}
	pair<int,int> ret = make_pair(-1,-1);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == prev) continue;
		dfs(v,u,adjList,comp,tot+1);
	}
}
int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	for(int i=0;i<N;i++){
		r[i] = 0;
		p[i] = i;
		h[i] = l[i] = 0;
	}
	vector< vector<int> > adjList(N);
	for(int i=0;i<M;i++){
		int x,y;cin>>x>>y;
		x--;y--;
		adjList[x].push_back(y);
		adjList[y].push_back(x);
	}
	for(int i=0;i<N;i++) vis[i] = false;
	for(int i=0;i<N;i++) if(vis[i] == false){
		far = i;dist = 0;
		dfs(i,-1,adjList,i,0);
		dist = 0;
		dfs(far,-1,adjList,i,0);
		l[i] = dist;
		h[i] = (dist+1)/2;
	}
	for(int i=0;i<Q;i++){
		int opr;cin>>opr;
		if(opr == 1){
			int x;cin>>x;x--;
			x = getS(x);
			cout<<l[x]<<endl;
		}else{
			int x,y;cin>>x>>y;
			x--;y--;
			mergeS(x,y);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int p[300010];
int r[300010];
int m[300010];

pair<int,int> dfs(int pa,int u,vector< vector<int> >& adjList){
	pair<int,int> far = make_pair(0,u);
	for(int i=0;i<adjList[u].size();i++){
		int v = adjList[u][i];
		if(v == pa) continue;
		pair<int,int> ret = dfs(u,v,adjList);
		if(ret.first+1 > far.first){
			far = ret;
			far.first += 1;
		}
	}
	return far;
}

int findS(int x){
	if(p[x] != x) p[x] = findS(p[x]);
	return p[x];
}

void mergeS(int x,int y){
	int px = findS(x);
	int py = findS(y);
	if(px == py) return;
	if(r[px] > r[py]){
		m[px] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[py] = px;
	}else{
		m[py] = max(max(m[px],m[py]),1 + (m[px]>>1) + (m[px]&1) + (m[py]>>1) + (m[py]&1));
		p[px] = py;
	}
	if(r[px] == r[py]) r[py] += 1;
}

int getMax(int u,vector< vector<int> > & adjList){
	pair<int,int> far = dfs(-1,u,adjList);
	return dfs(-1,far.second,adjList).first;
}

int main(){
	ios_base::sync_with_stdio(false);
	int N,M,Q;cin>>N>>M>>Q;
	vector< vector<int> > adjList(N);

	for(int i=0;i<N;i++) p[i] = i;

	for(int i=0;i<M;i++){
		int a,b;cin>>a>>b;
		a--;b--;
		adjList[a].push_back(b);
		adjList[b].push_back(a);
		mergeS(a,b);
	}

	for(int i=0;i<N;i++) m[i] = -1;

	for(int i=0;i<N;i++){
		int p = findS(i);
		if(m[p] != -1) continue;
		else m[p] = getMax(i,adjList);
	}
	stringstream p;
	for(int i=0;i<Q;i++){
		int q;cin>>q;
		if(q == 1){
			int x;cin>>x;x--;
			p<<m[findS(x)]<<endl;
		}else{
			int u,v;cin>>u>>v;
			u--;v--;
			mergeS(u,v);
		}
	}
	cout<<p.str();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,m,k,cnt,head[320000],depth[320000],dis[320000],vis[320000],fa[320000];
struct node {int next,to;} sxd[640000];
inline int read() {
	int X=0,w=0;
	char ch=0;
	while(!isdigit(ch)) {
		w|=ch=='-';
		ch=getchar();
	}
	while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void write(int x) {
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
void add(int u,int v) {
	sxd[++cnt].next=head[u];
	sxd[cnt].to=v;
	head[u]=cnt;
}
int find(int x) {
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
int mx,mxat=0;
void dfs(int at,int fa) {
	// cout<<"DFS "<<at<<" "<<fa<<" "<<mx<<" "<<mxat<<'\n';
	for(int i=head[at];i;i=sxd[i].next) {
		if(sxd[i].to==fa) continue;
		depth[sxd[i].to]=depth[at]+1;
		if(depth[sxd[i].to]>mx) {
			mx=depth[sxd[i].to];
			mxat=sxd[i].to;
		}
		dfs(sxd[i].to,at);
	}
}
signed main() {
	n=read();
	m=read();
	k=read();
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++) {
		int x=read(),y=read();
		add(x,y);
		add(y,x);
		int xx=find(x);
		int yy=find(y);
		fa[xx]=yy;
	}
	for(int i=1;i<=n;i++) {
		int w=find(i);
		// cout<<"find["<<i<<"]="<<w<<'\n';
		if(!vis[w]) {
			vis[w]=true;
			mx=mxat=0;
			dfs(w,0);
			int qq=mxat;
			mx=0;
			memset(depth,0,sizeof depth);
			dfs(qq,0);
			dis[w]=mx;
		}
	}
	for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	puts("");
	for(int i=1;i<=k;i++) {
		int mcl=read();
		if(mcl==1) {
			int x=read();
			int xx=find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx=read(),yy=read();
			int x=find(xx);
			int y=find(yy);
			fa[x]=y;
			dis[y]=max(max(dis[x],dis[y]),(dis[x]+1)/2+(dis[y]+1)/2+1);
			dis[x]=0;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,m,k,cnt,head[320000],depth[320000],dis[320000],vis[320000],fa[320000];
struct node {int next,to;} sxd[640000];
inline int read() {
	int X=0,w=0;
	char ch=0;
	while(!isdigit(ch)) {
		w|=ch=='-';
		ch=getchar();
	}
	while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void write(int x) {
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
void add(int u,int v) {
	sxd[++cnt].next=head[u];
	sxd[cnt].to=v;
	head[u]=cnt;
}
int find(int x) {
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
int mx,mxat=0;
void dfs(int at,int fa) {
	for(int i=head[at];i;i=sxd[i].next) {
		if(sxd[i].to==fa) continue;
		depth[sxd[i].to]=depth[at]+1;
		if(depth[sxd[i].to]>mx) {
			mx=depth[sxd[i].to];
			mxat=sxd[i].to;
		}
		dfs(sxd[i].to,at);
	}
}
signed main() {
	n=read();
	m=read();
	k=read();
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++) {
		int x=read(),y=read();
		add(x,y);
		add(y,x);
		int xx=find(x);
		int yy=find(y);
		fa[xx]=yy;
	}
	for(int i=1;i<=n;i++) {
		int w=find(i);
		if(!vis[w]) {
			vis[w]=true;
			mx=mxat=0;
			dfs(1,0);
			int qq=mxat;
			mx=0;
			dfs(qq,0);
			dis[w]=mx;
		}
	}
	for(int i=1;i<=k;i++) {
		int mcl=read();
		if(mcl==1) {
			int x=read();
			int xx=find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx=read(),yy=read();
			int x=find(xx);
			int y=find(yy);
			fa[x]=y;
			dis[y]=max(max(dis[x],dis[y]),(dis[x]+1)/2+(dis[y]+1)/2+1);
			dis[x]=0;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, k, cnt, head[320000], depth[320000], dis[320000], vis[320000], fa[320000];
struct node {int next, to;} sxd[640000];
inline int read() {
	int X = 0, w = 0;
	char ch = 0;
	while (!isdigit(ch)) {
		w |= ch == '-';
		ch = getchar();
	}
	while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
	return w ? -X : X;
}
inline void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
void add(int u, int v) {
	sxd[++cnt].next = head[u];
	sxd[cnt].to = v;
	head[u] = cnt;
}
int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
int mx, mxat = 0;
void dfs(int at, int fa) {
	// cout<<"DFS "<<at<<" "<<fa<<" "<<mx<<" "<<mxat<<'\n';
	for (int i = head[at]; i; i = sxd[i].next) {
		if (sxd[i].to == fa) continue;
		depth[sxd[i].to] = depth[at] + 1;
		if (depth[sxd[i].to] > mx) {
			mx = depth[sxd[i].to];
			mxat = sxd[i].to;
		}
		dfs(sxd[i].to, at);
	}
}
signed main() {
	n = read();
	m = read();
	k = read();
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();
		add(x, y);
		add(y, x);
		int xx = find(x);
		int yy = find(y);
		fa[xx] = yy;
	}
	for (int i = 1; i <= n; i++) {
		int w = find(i);
		// cout<<"find["<<i<<"]="<<w<<'\n';
		if (!vis[w]) {
			vis[w] = true;
			mx = mxat = 0;
			dfs(w, 0);
			int qq = mxat;
			mx = 0;
			memset(depth, 0, sizeof depth);
			dfs(qq, 0);
			dis[w] = mx;
		}
	}
	// for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	// puts("");
	for (int i = 1; i <= k; i++) {
		int mcl = read();
		if (mcl == 1) {
			int x = read();
			int xx = find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx = read(), yy = read();
			int x = find(xx);
			int y = find(yy);
			if (x != y) {
				fa[x] = y;
				dis[y] = max(max(dis[x], dis[y]), (dis[x] + 1) / 2 + (dis[y] + 1) / 2 + 1);
				dis[x] = 0;
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,m,k,cnt,head[320000],depth[320000],dis[320000],vis[320000],fa[320000];
struct node {int next,to;} sxd[640000];
inline int read() {
	int X=0,w=0;
	char ch=0;
	while(!isdigit(ch)) {
		w|=ch=='-';
		ch=getchar();
	}
	while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void write(int x) {
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
void add(int u,int v) {
	sxd[++cnt].next=head[u];
	sxd[cnt].to=v;
	head[u]=cnt;
}
int find(int x) {
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
int mx,mxat=0;
void dfs(int at,int fa) {
	// cout<<"DFS "<<at<<" "<<fa<<" "<<mx<<" "<<mxat<<'\n';
	for(int i=head[at];i;i=sxd[i].next) {
		if(sxd[i].to==fa) continue;
		depth[sxd[i].to]=depth[at]+1;
		if(depth[sxd[i].to]>mx) {
			mx=depth[sxd[i].to];
			mxat=sxd[i].to;
		}
		dfs(sxd[i].to,at);
	}
}
signed main() {
	n=read();
	m=read();
	k=read();
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++) {
		int x=read(),y=read();
		add(x,y);
		add(y,x);
		int xx=find(x);
		int yy=find(y);
		fa[xx]=yy;
	}
	for(int i=1;i<=n;i++) {
		int w=find(i);
		// cout<<"find["<<i<<"]="<<w<<'\n';
		if(!vis[w]) {
			vis[w]=true;
			mx=mxat=0;
			dfs(w,0);
			int qq=mxat;
			mx=0;
			memset(depth,0,sizeof depth);
			dfs(qq,0);
			dis[w]=mx;
		}
	}
	// for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	// puts("");
	for(int i=1;i<=k;i++) {
		int mcl=read();
		if(mcl==1) {
			int x=read();
			int xx=find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx=read(),yy=read();
			int x=find(xx);
			int y=find(yy);
			fa[x]=y;
			dis[y]=max(max(dis[x],dis[y]),(dis[x]+1)/2+(dis[y]+1)/2+1);
			dis[x]=0;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, k, cnt, head[320000], depth[320000], dis[320000], vis[320000], fa[320000];
struct node {int next, to;} sxd[640000];
inline int read() {
	int X = 0, w = 0;
	char ch = 0;
	while (!isdigit(ch)) {
		w |= ch == '-';
		ch = getchar();
	}
	while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
	return w ? -X : X;
}
inline void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
void add(int u, int v) {
	sxd[++cnt].next = head[u];
	sxd[cnt].to = v;
	head[u] = cnt;
}
int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
int mx, mxat = 0;
void dfs(int at, int fa) {
	// cout<<"DFS "<<at<<" "<<fa<<" "<<mx<<" "<<mxat<<'\n';
	for (int i = head[at]; i; i = sxd[i].next) {
		if (sxd[i].to == fa) continue;
		depth[sxd[i].to] = depth[at] + 1;
		if (depth[sxd[i].to] > mx) {
			mx = depth[sxd[i].to];
			mxat = sxd[i].to;
		}
		dfs(sxd[i].to, at);
	}
}
signed main() {
	n = read();
	m = read();
	k = read();
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();
		add(x, y);
		add(y, x);
		int xx = find(x);
		int yy = find(y);
		if(xx!=yy) fa[xx] = yy;
	}
	for (int i = 1; i <= n; i++) {
		int w = find(i);
		// cout<<"find["<<i<<"]="<<w<<'\n';
		if (!vis[w]) {
			vis[w] = true;
			mx = mxat = 0;
			dfs(w, 0);
			int qq = mxat;
			mx = 0;
			dis[qq]=0;
			// memset(depth, 0, sizeof depth);
			dfs(qq, 0);
			dis[w] = mx;
		}
	}
	// for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	// puts("");
	for (int i = 1; i <= k; i++) {
		int mcl = read();
		if (mcl == 1) {
			int x = read();
			int xx = find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx = read(), yy = read();
			int x = find(xx);
			int y = find(yy);
			if (x != y) {
				fa[x] = y;
				dis[y] = max(max(dis[x], dis[y]), (dis[x] + 1) / 2 + (dis[y] + 1) / 2 + 1);
				dis[x] = 0;
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, k, cnt, head[320000], depth[320000], dis[320000], vis[320000], fa[320000];
struct node {int next, to;} sxd[640000];
inline int read() {
	int X = 0, w = 0;
	char ch = 0;
	while (!isdigit(ch)) {
		w |= ch == '-';
		ch = getchar();
	}
	while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
	return w ? -X : X;
}
inline void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
void add(int u, int v) {
	sxd[++cnt].next = head[u];
	sxd[cnt].to = v;
	head[u] = cnt;
}
int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
int mx, mxat = 0;
void dfs(int at, int fa) {
	// cout<<"DFS "<<at<<" "<<fa<<" "<<mx<<" "<<mxat<<'\n';
	for (int i = head[at]; i; i = sxd[i].next) {
		if (sxd[i].to == fa) continue;
		depth[sxd[i].to] = depth[at] + 1;
		if (depth[sxd[i].to] > mx) {
			mx = depth[sxd[i].to];
			mxat = sxd[i].to;
		}
		dfs(sxd[i].to, at);
	}
}
signed main() {
	n = read();
	m = read();
	k = read();
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();
		add(x, y);
		add(y, x);
		int xx = find(x);
		int yy = find(y);
		if(xx!=yy) fa[xx] = yy;
	}
	for (int i = 1; i <= n; i++) {
		int w = find(i);
		// cout<<"find["<<i<<"]="<<w<<'\n';
		if (!vis[w]) {
			vis[w] = true;
			mx = mxat = 0;
			depth[w]=0;
			dfs(w, 0);
			int qq = mxat;
			mx = 0;
			depth[qq]=0;
			// memset(depth, 0, sizeof depth);
			dfs(qq, 0);
			dis[w] = mx;
		}
	}
	// for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	// puts("");
	for (int i = 1; i <= k; i++) {
		int mcl = read();
		if (mcl == 1) {
			int x = read();
			int xx = find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx = read(), yy = read();
			int x = find(xx);
			int y = find(yy);
			if (x != y) {
				fa[x] = y;
				dis[y] = max(max(dis[x], dis[y]), (dis[x] + 1) / 2 + (dis[y] + 1) / 2 + 1);
				dis[x] = 0;
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, m, k, cnt, head[320000], depth[320000], dis[320000], vis[320000], fa[320000];
struct node {int next, to;} sxd[640000];
inline int read() {
	int X = 0, w = 0;
	char ch = 0;
	while (!isdigit(ch)) {
		w |= ch == '-';
		ch = getchar();
	}
	while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
	return w ? -X : X;
}
inline void write(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
void add(int u, int v) {
	sxd[++cnt].next = head[u];
	sxd[cnt].to = v;
	head[u] = cnt;
}
int find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
int mx, mxat = 0;
void dfs(int at, int fa) {
	for (int i = head[at]; i; i = sxd[i].next) {
		if (sxd[i].to == fa) continue;
		depth[sxd[i].to] = depth[at] + 1;
		if (depth[sxd[i].to] > mx) {
			mx = depth[sxd[i].to];
			mxat = sxd[i].to;
		}
		dfs(sxd[i].to, at);
	}
}
signed main() {
	n = read();
	m = read();
	k = read();
	for (int i = 1; i <= n; i++) fa[i] = i;
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read();
		add(x, y);
		add(y, x);
		int xx = find(x);
		int yy = find(y);
		if(xx!=yy) fa[xx] = yy;
	}
	for (int i = 1; i <= n; i++) {
		int w = find(i);
		if (!vis[w]) {
			vis[w] = true;
			mx = mxat = 0;
			depth[w]=0;
			dfs(w, 0);
			int qq = mxat;
			mx = 0;
			depth[qq]=0;
			dfs(qq, 0);
			dis[w] = mx;
		}
	}
	for (int i = 1; i <= k; i++) {
		int mcl = read();
		if (mcl == 1) {
			int x = read();
			int xx = find(x);
			write(dis[xx]);
			puts("");
		} else {
			int xx = read(), yy = read();
			int x = find(xx);
			int y = find(yy);
			if (x != y) {
				fa[x] = y;
				dis[y] = max(max(dis[x], dis[y]), (dis[x] + 1) / 2 + (dis[y] + 1) / 2 + 1);
				dis[x] = 0;
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;

struct UniFind {
  int p[N];
  int r[N];

  UniFind() {}
  UniFind(int n) {
    for (int i = 1; i <= n; ++i) p[i] = i;
    fill(r, r+1 + n, 0);
  }

  int par(int v) {
    if (p[v] != v) {
      p[v] = par(p[v]);
    }
    return p[v];
  }

  void uni(int a, int b) {
    a = par(a), b = par(b);
    if (a == b) {
      return;
    }
    if (r[a] > r[b]) swap(a, b);
    p[a] = b;
    if (r[a] == r[b]) ++r[a];
  }
};

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  pair<int, int> ret = {0, 0};
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);
    if (ret.first < p.first) ret.first = p.first;
    if (ret.second < p.second + 1) ret.second = p.second + 1;
  }
  if (ret.first < ret.second) ret.first = ret.second;
  len[v] = ret.first;
  return ret;
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  UniFind UF(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    UF.uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = UF.par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = UF.par(x);
      cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = UF.par(x), y = UF.par(y);
      UF.uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = UF.par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (a == b) {
    return;
  }
  if (r[a] > r[b]) swap(a, b);
  p[a] = b;
  if (r[a] == r[b]) ++r[b];
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  //cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;
  fill(r, r+1 + n, 0);

  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    //cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      printf("%d\n", len[x]);
      //cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;

struct UniFind {
  int p[N];
  int r[N];

  UniFind() {}
  UniFind(int n) {
    for (int i = 1; i <= n; ++i) p[i] = i;
    fill(r, r+1 + n, 0);
  }

  int par(int v) {
    if (p[v] != v) {
      p[v] = par(p[v]);
    }
    return p[v];
  }

  void uni(int a, int b) {
    a = par(a), b = par(b);
    if (a == b) {
      return;
    }
    if (r[a] > r[b]) swap(a, b);
    p[a] = b;
    if (r[a] == r[b]) ++r[a];
  }
};

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);
    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  UniFind UF(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    UF.uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = UF.par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  stringstream ss;
  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = UF.par(x);
      ss << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = UF.par(x), y = UF.par(y);
      if (x == y) {
        continue;
      }
      UF.uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = UF.par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
  cout << ss.str() << '\n';
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (a == b) {
    return;
  }
  if (r[a] > r[b]) swap(a, b);
  p[a] = b;
  if (r[a] == r[b]) ++r[a];
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);
    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  //cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;
  fill(r, r+1 + n, 0);

  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    //cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      printf("%d\n", len[x]);
      //cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;

struct UniFind {
  int p[N];
  int r[N];

  UniFind() {}
  UniFind(int n) {
    for (int i = 1; i <= n; ++i) p[i] = i;
    fill(r, r+1 + n, 0);
  }

  int par(int v) {
    if (p[v] != v) {
      p[v] = par(p[v]);
    }
    return p[v];
  }

  void uni(int a, int b) {
    a = par(a), b = par(b);
    if (a == b) {
      return;
    }
    if (r[a] > r[b]) swap(a, b);
    p[a] = b;
    if (r[a] == r[b]) ++r[a];
  }
};

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  pair<int, int> ret = {0, 0};
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);
    if (p.first > ret.first) ret.first = p.first;
    if (p.second+1 > ret.second+1) ret.second = p.second+1;
  }
  if (ret.first < ret.second) ret.first = ret.second;
  len[v] = ret.first;
  return ret;
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  UniFind UF(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    UF.uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = UF.par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = UF.par(x);
      cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = UF.par(x), y = UF.par(y);
      UF.uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = UF.par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (a == b) {
    return;
  }
  if (r[a] > r[b]) swap(a, b);
  p[a] = b;
  if (r[a] == r[b]) ++r[a];
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;

  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (r[a] < r[b]) {
    p[a] = b;
  } else if (r[b] < r[a]) {
    p[b] = a;
  } else if (a != b) {
    p[a] = b;
    ++r[b];
  }
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  //scanf("%d %d %d", &n, &m, &q);
  cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;

  for (int i = 0; i < m; ++i) {
    int x, y;
    //scanf("%d %d", &x, &y);
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    //scanf("%d", &t);
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      //printf("%d\n", len[x]);
      cout << len[x] << '\n';
    } else {
      //scanf("%d %d", &x, &y);
      cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (r[a] < r[b]) {
    p[a] = b;
  } else if (r[b] < r[a]) {
    p[b] = a;
  } else if (a != b) {
    p[a] = b;
    ++r[b];
  }
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  //cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;
  fill(r, r+1 + n, 0);

  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    //cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      printf("%d\n", len[x]);
      //cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;

struct UniFind {
  int p[N];
  int r[N];

  UniFind() {}
  UniFind(int n) {
    for (int i = 1; i <= n; ++i) p[i] = i;
    fill(r, r+1 + n, 0);
  }

  int par(int v) {
    if (p[v] != v) {
      p[v] = par(p[v]);
    }
    return p[v];
  }

  void uni(int a, int b) {
    a = par(a), b = par(b);
    if (a == b) {
      return;
    }
    if (r[a] > r[b]) swap(a, b);
    p[a] = b;
    if (r[a] == r[b]) ++r[a];
  }
};

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);
    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  //cin >> n >> m >> q;
  UniFind UF(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    //cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    UF.uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = UF.par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = UF.par(x);
      printf("%d\n", len[x]);
      //cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = UF.par(x), y = UF.par(y);
      if (x == y) {
        continue;
      }
      UF.uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = UF.par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

struct UniFind {
  int p[N];
  int r[N];

  UniFind() {}
  UniFind(int n) {
    for (int i = 1; i <= n; ++i) p[i] = i;
    fill(r+1, r+1 + n, 0);
  }

  int par(int v) {
    if (p[v] != v) {
      p[v] = par(p[v]);
    }
    return p[v];
  }

  void uni(int a, int b) {
    a = par(a), b = par(b);
    if (a == b) {
      return;
    }
    if (r[a] > r[b]) swap(a, b);
    p[a] = b;
    if (r[a] == r[b]) ++r[a];
    return;
  }
};

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  UniFind UF(n);

  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    UF.uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = UF.par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = UF.par(x);
      cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = UF.par(x), y = UF.par(y);
      if (x == y) {
        continue;
      }
      UF.uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = UF.par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (r[a] < r[b]) {
    p[a] = b;
  } else if (r[b] < r[a]) {
    p[b] = a;
  } else if (a != b) {
    p[a] = b;
    ++r[b];
  }
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  //cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;

  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    //cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    scanf("%d", &t);
    //cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      printf("%d\n", len[x]);
      //cout << len[x] << '\n';
    } else {
      scanf("%d %d", &x, &y);
      //cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 100;

int p[N];
int r[N];

int par(int v) {
  if (p[v] != v) {
    p[v] = par(p[v]);
  }
  return p[v];
}

void uni(int a, int b) {
  a = par(a), b = par(b);
  if (a == b) {
    return;
  }
  if (r[a] > r[b]) swap(a, b);
  p[a] = b;
  if (r[a] == r[b]) ++r[a];
}

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);

    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  //ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  //cin >> n >> m >> q;

  for (int i = 1; i <= n; ++i) p[i] = i;
  fill(r, r+1 + n, 0);

  for (int i = 0; i < m; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    //cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = par(x);
      printf("%d\n", len[x]);
      //cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = par(x), y = par(y);
      if (x == y) {
        continue;
      }
      uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;

struct UniFind {
  int p[N];
  int r[N];

  UniFind() {}
  UniFind(int n) {
    for (int i = 1; i <= n; ++i) p[i] = i;
    fill(r, r+1 + n, 0);
  }

  int par(int v) {
    if (p[v] != v) {
      p[v] = par(p[v]);
    }
    return p[v];
  }

  void uni(int a, int b) {
    a = par(a), b = par(b);
    if (a == b) {
      return;
    }
    if (r[a] > r[b]) swap(a, b);
    p[a] = b;
    if (r[a] == r[b]) ++r[a];
  }
};

vector<int> es[N];
bool vis[N];
int len[N];

pair<int, int> dfs(int v) {
  vis[v] = true;
  int big = 0;
  int to1 = 0, to2 = 0;
  for (auto u : es[v]) {
    if (vis[u]) continue;
    pair<int, int> p = dfs(u);
    if (big < p.first) big = p.first;

    if (to1 < p.second + 1) to2 = to1, to1 = p.second + 1;
    else if (to2 < p.second + 1) to2 = p.second + 1;
  }
  int through = to1 + to2;
  if (through > big) big = through;
  len[v] = big;
  return {big, to1};
}

int main()
{
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  UniFind UF(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    es[x].push_back(y);
    es[y].push_back(x);
    UF.uni(x, y);
  }

  for (int i = 1; i <= n; ++i) {
    int v = UF.par(i);
    if (!vis[v]) {
      dfs(v);
    }
  }

  while (q--) {
    int t, x, y;
    cin >> t;
    if (t == 1) {
      cin >> x;
      x = UF.par(x);
      cout << len[x] << '\n';
    } else {
      cin >> x >> y;
      x = UF.par(x), y = UF.par(y);
      if (x == y) {
        continue;
      }
      UF.uni(x, y);
      int bigger = max(len[x], len[y]);
      int smaller = min(len[x], len[y]);
      int v = UF.par(x);
      len[v] = max(bigger, (smaller+1)/2 + (bigger+1)/2 + 1);
    }
  }
}
// g++ -W -Wall -Wextra -pedantic -std=c++0x -o p main.cpp


#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int par[N];
int ans[N];
bool mark[N];
int n,m,q;
int d[N];
bool gmark[N];
vector <int> v[N];
void clear()
{
	for (int i =0 ; i < N; ++i) d[i] = -1, mark[i] = false;
}
void dfs (int s, int head, int dd)
{
	par[s] = head;
	mark[s] = true;
	gmark[s] = true;
	d[s] = dd;
	for (int i = 0 ; i < v[s].size(); ++i)
		if (!mark[v[s][i]]) dfs(v[s][i], head, dd+1);
}
int parent (int x)
{
	if(x == par[x])
		return x;
	par[x] = parent (par[x]);
	return par[x];
}
int main()
{
	cin >> n >> m >> q;
	int x,y;
	for (int i = 0 ;i < m; ++i)
	{
		cin >> x >> y;
		x--, y--;
		v[x].push_back (y);
		v[y].push_back (x);
	}
	int help, id;
	for (int i = 0 ;i < n; ++i)
		if (!gmark[i])
		{
	//		cout << endl << " I : "<< i <<  "    max d[i] : " ;
			help = i;
			clear();
			dfs (i, i, 0);
			help = -1;
			for (int j = 0 ;j < N; ++j)
				if ((d[j] != -1) and (help < d[j]))
				{
					help = d[j];
					id = j;
				}
		//	cout << help << "  id : " << id << endl;
			clear();
			dfs (id, i, 0);
			help  = -1;
			for (int j = 0 ;j < N; ++j)
				help = max (help, d[j]);
			ans[i] = help;
		//	cout << endl << " I : " << i << "  ans[i] : " << ans[i] << endl;
		}
	for (int i = 0;i < q; ++i)
	{
		cin >> help >> x ;
		x --;
		if (help == 2)
		{

			cin >> y;y--;
			parent (x);
			parent (y);
			if (par[x] == par[y]) continue;
	//		cout << endl << "  x : " << x << " y : "<< y << "  par[x] : " << par[x] << "   par[y] : "<< par[y] << "old ans[par[y]] : " << ans[par[y]] << "   old ans[par[x]] : " << ans[par[x]] << "  new : " ;
			ans[par[x]] = max (max (ans[par[y]], ans[par[x]]),(((ans[par[y]]+1)/2) + ((ans[par[x]]+1)/2))+1); //cout << ans[par[x]] << endl;
			par[par[y]] = par[x];
			continue;
		}
		parent(x);
	//	cout << endl << " X : " << x << " parent[x] : " << par[x] << "  ans : " ;
		cout << ans[par[x]] << endl;
	}

}


#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int par[N];
int ans[N];
bool mark[N];
int n,m,q;
int d[N];
bool gmark[N];
vector <int> v[N];
vector <int> bad;
void clear()
{
	for (int i = 0 ;i < bad.size(); ++i) mark[bad[i]] = false, d[bad[i]] = -1;
	bad.clear();
}
void dfs (int s, int head, int dd)
{
	par[s] = head;
	mark[s] = true;
	gmark[s] = true;
	bad.push_back(s);
	d[s] = dd;
	for (int i = 0 ; i < v[s].size(); ++i)
		if (!mark[v[s][i]]) dfs(v[s][i], head, dd+1);
}
int parent (int x)
{
	if(x == par[x])
		return x;
	par[x] = parent (par[x]);
	return par[x];
}
int main()
{
	scanf ("%d%d%d" , &n , &m, &q);
	int x,y;
	for (int i = 0 ;i < m; ++i)
	{
		scanf ("%d%d", &x, &y);
		x--, y--;
		v[x].push_back (y);
		v[y].push_back (x);
	}
	int help, id;
	for (int i = 0 ;i < n; ++i)
		if (!gmark[i])
		{
			help = i;
			clear();
			dfs (i, i, 0);
			help = -1;
			for (int j = 0 ;j < N; ++j)
				if ((d[j] != -1) and (help < d[j]))
				{
					help = d[j];
					id = j;
				}
			clear();
			dfs (id, i, 0);
			help  = -1;
			for (int j = 0 ;j < N; ++j)
				help = max (help, d[j]);
			ans[i] = help;
		}
	for (int i = 0;i < q; ++i)
	{
		scanf ("%d%d", &help, &x);
		x --;
		if (help == 2)
		{

			scanf ("%d", &y);y--;
			parent (x);
			parent (y);
			if (par[x] == par[y]) continue;
			ans[par[x]] = max (max (ans[par[y]], ans[par[x]]),(((ans[par[y]]+1)/2) + ((ans[par[x]]+1)/2))+1); //cout << ans[par[x]] << endl;
			par[par[y]] = par[x];
			continue;
		}
		parent(x);
		printf ("%d\n", ans[par[x]]);
	}

}


#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int par[N];
int ans[N];
bool mark[N];
int n,m,q;
int d[N];
vector <int> v[N];
void clear()
{
	for (int i =0 ; i < N; ++i) d[i] = -1;
}
void dfs (int s, int head, int dd)
{
	par[s] = head;
	mark[s] = true;
	d[s] = dd;
	for (int i = 0 ; i < v[s].size(); ++i)
		if (!mark[i]) dfs(v[s][i], head, dd+1);
}
int parent (int x)
{
	if(x == par[x])
		return x;
	par[x] = parent (par[x]);
	return par[x];
}
int main()
{
	cin >> n >> m >> q;
	int x,y;
	for (int i = 0 ;i < m; ++i)
	{
		cin >> x >> y;
		x--, y--;
		v[x].push_back (y);
		v[y].push_back (x);
	}
	int help, id;
	for (int i = 0 ;i < n; ++i)
		if (!mark[i])
		{
			help = i;
			clear();
			dfs (i, i, 0);
			help = -1;
			for (int j = 0 ;j < N; ++j)
				if ((d[j] != -1) and (help < d[j]))
				{
					help = d[j];
					id = j;
				}
			dfs (id, i, 0);
			help  = -1;
			for (int j = 0 ;j < N; ++j)
				help = max (help, d[j]);
			ans[i] = help;
		}
	for (int i = 0;i < q; ++i)
	{
		cin >> help >> x ;
		x --;
		if (help == 2)
		{

			cin >> y;y--;
			par[x] = parent (x);
			par[y] = parent (y);
			ans[par[x]] = (ans[par[y]]+1)/2 + (ans[par[x]]+1)/2; ans[par[x]] ++;
			par[par[y]] = par[x];
			continue;
		}
		par[x] = parent(x);
		cout << ans[par[x]] << endl;
	}

}


#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int par[N];
int ans[N];
bool mark[N];
int n,m,q;
int d[N];
bool gmark[N];
vector <int> v[N];
void clear()
{
	for (int i =0 ; i < N; ++i) d[i] = -1, mark[i] = false;
}
void dfs (int s, int head, int dd)
{
	par[s] = head;
	mark[s] = true;
	gmark[s] = true;
	d[s] = dd;
	for (int i = 0 ; i < v[s].size(); ++i)
		if (!mark[v[s][i]]) dfs(v[s][i], head, dd+1);
}
int parent (int x)
{
	if(x == par[x])
		return x;
	par[x] = parent (par[x]);
	return par[x];
}
int main()
{
	cin >> n >> m >> q;
	int x,y;
	for (int i = 0 ;i < m; ++i)
	{
		scanf ("%d%d", &x, &y);
		x--, y--;
		v[x].push_back (y);
		v[y].push_back (x);
	}
	int help, id;
	for (int i = 0 ;i < n; ++i)
		if (!gmark[i])
		{
			help = i;
			clear();
			dfs (i, i, 0);
			help = -1;
			for (int j = 0 ;j < N; ++j)
				if ((d[j] != -1) and (help < d[j]))
				{
					help = d[j];
					id = j;
				}
			clear();
			dfs (id, i, 0);
			help  = -1;
			for (int j = 0 ;j < N; ++j)
				help = max (help, d[j]);
			ans[i] = help;
		}
	for (int i = 0;i < q; ++i)
	{
		scanf ("%d%d", &help, &x);
		x --;
		if (help == 2)
		{

			scanf ("%d", &y);y--;
			parent (x);
			parent (y);
			if (par[x] == par[y]) continue;
			ans[par[x]] = max (max (ans[par[y]], ans[par[x]]),(((ans[par[y]]+1)/2) + ((ans[par[x]]+1)/2))+1); //cout << ans[par[x]] << endl;
			par[par[y]] = par[x];
			continue;
		}
		parent(x);
		printf ("%d\n", ans[par[x]]);
	}

}


#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int par[N];
int ans[N];
bool mark[N];
int n,m,q;
int d[N];
bool gmark[N];
vector <int> v[N];
void clear()
{
	for (int i =0 ; i < N; ++i) d[i] = -1, mark[i] = false;
}
void dfs (int s, int head, int dd)
{
	par[s] = head;
	mark[s] = true;
	gmark[s] = true;
	d[s] = dd;
	for (int i = 0 ; i < v[s].size(); ++i)
		if (!mark[v[s][i]]) dfs(v[s][i], head, dd+1);
}
int parent (int x)
{
	if(x == par[x])
		return x;
	par[x] = parent (par[x]);
	return par[x];
}
int main()
{
	cin >> n >> m >> q;
	int x,y;
	for (int i = 0 ;i < m; ++i)
	{
		scanf ("%d%d", &x, &y);
		x--, y--;
		v[x].push_back (y);
		v[y].push_back (x);
	}
	int help, id;
	for (int i = 0 ;i < n; ++i)
		if (!gmark[i])
		{
			help = i;
			clear();
			dfs (i, i, 0);
			help = -1;
			for (int j = 0 ;j < N; ++j)
				if ((d[j] != -1) and (help < d[j]))
				{
					help = d[j];
					id = j;
				}
			clear();
			dfs (id, i, 0);
			help  = -1;
			for (int j = 0 ;j < N; ++j)
				help = max (help, d[j]);
			ans[i] = help;
		}
	for (int i = 0;i < q; ++i)
	{
		scanf ("%d%d", &help, &x);
		x --;
		if (help == 2)
		{

			scanf ("%d", &y);y--;
			parent (x);
			parent (y);
			if (par[x] == par[y]) continue;
			ans[par[x]] = max (max (ans[par[y]], ans[par[x]]),(((ans[par[y]]+1)/2) + ((ans[par[x]]+1)/2))+1); //cout << ans[par[x]] << endl;
			par[par[y]] = par[x];
			continue;
		}
		parent(x);
		printf ("%d", ans[par[x]]);
	}

}