#include<bits/stdc++.h> #define maxn 100005 #define int long long using namespace std; namespace IO{ inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*f; } inline void write(int x){ if(x<0){ putchar('-'); x=-x; } if(x>=10)write(x/10); putchar(x%10+'0'); return; } } using namespace IO; int n,m,Q,dfcnt,low[maxn],dfn[maxn],belong[maxn],cnt; bool instk[maxn];int stk[maxn],top,sscval[maxn],siz[maxn]; vector<int>grath[maxn]; int head[maxn],recnt=1;bool vis[maxn]; struct EDGE{int v,nxt;bool bridge;}edge[4000040]; inline void addedge(int u,int v){ edge[++recnt]={v,head[u],0}; head[u]=recnt; } void Tarjan(int rt,int fa){ dfn[rt]=low[rt]=++dfcnt; stk[++top]=rt; for(int j=head[rt];j;j=edge[j].nxt){ int i=edge[j].v; if(i==fa)continue; if(!dfn[i]){ Tarjan(i,rt); low[rt]=min(low[rt],low[i]); if(low[i]>dfn[rt]) edge[j].bridge=edge[j^1].bridge=1; } else low[rt]=min(low[rt],low[i]); } return; } void dfs(int rt,int Fa){ vis[rt]=1;siz[cnt]=1;belong[rt]=cnt; for(int i=head[rt];i;i=edge[i].nxt){ if(edge[i].bridge)continue; int v=edge[i].v; if(v==Fa||vis[v])continue; dfs(v,rt); } return; } map<pair<int,int>,bool>mp; priority_queue<int>Tree[maxn*8]; int son[maxn],DFN[maxn],DFCNT,dep[maxn],Top[maxn],fa[maxn]; inline void dfs1(int rt,int Fa){ for(auto v:grath[rt]){ if(v==Fa)continue; dep[v]=dep[rt]+1; fa[v]=rt; dfs1(v,rt); if(siz[v]>siz[son[rt]])son[rt]=v; siz[rt]+=siz[v]; } return; } inline void dfs2(int rt,int tp,int Fa){ DFN[rt]=++DFCNT;Top[rt]=tp;fa[son[rt]]=rt; if(son[rt])dfs2(son[rt],tp,rt); for(auto v:grath[rt]){ if(v==Fa)continue; if(v==son[rt])continue; dfs2(v,v,rt); } return; } inline void build(int id,int l,int r){ Tree[id].push(-1); int mid=(l+r)>>1; if(l==r)return; build(id<<1,l,mid); build(id<<1|1,mid+1,r); return; } int MX,awmc; inline void query(int id,int l,int r,int tol,int tor){ if(l>tor||r<tol)return; if(l==r&&tol<=l&&r<=tor){ if(Tree[id].top()>MX){ MX=Tree[id].top(); awmc=l; } return; } int mid=(l+r)>>1; if(!(mid<tol)) query(id<<1,l,mid,tol,tor); if(!(mid+1>tor)) query(id<<1|1,mid+1,r,tol,tor); } inline void AWMC(int id,int l,int r,int dlx){ Tree[id].pop(); if(l==r)return;int mid=(l+r)>>1; if(dlx<=mid)AWMC(id<<1,l,mid,dlx); else AWMC(id<<1|1,mid+1,r,dlx); } inline void update(int id,int l,int r,int place,int val){ Tree[id].push(val); if(l==r)return; int mid=(l+r)>>1; if(place<=mid)update(id<<1,l,mid,place,val); else update(id<<1|1,mid+1,r,place,val); return; } inline int QUERY(int u,int v){ MX=-1;awmc=0; while(u!=v){ if(DFN[Top[v]]>DFN[Top[u]])swap(u,v); query(1,1,n,min(DFN[Top[u]],DFN[u]),max(DFN[Top[u]],DFN[u])); u=fa[Top[u]]; } query(1,1,n,min(DFN[u],DFN[v]),max(DFN[u],DFN[v])); if(awmc!=0)AWMC(1,1,n,awmc); return MX; } signed main(){ n=read();m=read();Q=read();siz[0]=-114514; for(int i=1;i<=m;++i){ int u=read(),v=read(); addedge(u,v);addedge(v,u); } for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(i,0); for(int i=1;i<=n;++i)if(!vis[i])cnt++,dfs(i,0); for(int i=1;i<=n;++i){ for(int czs=head[i];czs;czs=edge[czs].nxt){ int j=edge[czs].v; if(belong[i]!=belong[j]){ int u=belong[i],v=belong[j]; if(!mp.count(make_pair(u,v)) && !mp.count(make_pair(v,u))){ mp[make_pair(u,v)]=mp[make_pair(v,u)]=1; grath[u].push_back(v); grath[v].push_back(u); } } } } dfs1(1,0);dfs2(1,1,0);build(1,1,n); for(int i=1;i<=Q;++i){ int op=read(); if(op==1){ int u=read(),w=read(); u=belong[u]; update(1,1,n,DFN[u],w); } else{ int u=read(),v=read(); u=belong[u];v=belong[v]; MX=-1;awmc=0; int AAANS=QUERY(u,v); write(AAANS);putchar('\n'); } } return 0; }