#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
#define eps 1e-7
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
const int MAXN=1e6+10;
struct edge{
int x,y,v,is,id;
}a[MAXN];
struct opera{
int op,x,y,id,ans;
}q[MAXN];
struct tree{
int son[2],mx,fa,v,tag;
}T[1500010];
int n,m,Q,f[1500010],tot,p[1500010],top,opp;
inline bool cmp1(edge n,edge m){
return n.v<m.v;
}
inline bool cmp2(edge n,edge m){
return n.x<m.x||(n.x==m.x&&n.y<m.y);
}
inline bool cmp3(edge n,edge m){
return n.id<m.id;
}
inline int check(int x,int y){
int l=1;int r=m;
while(l<=r){
int mid=(l+r)>>1;
if(a[mid].x<x||(a[mid].x==x&&a[mid].y<y)) l=mid+1;
else if(a[mid].x==x&&a[mid].y==y) return mid;
else r=mid-1;
}
}
inline int find(int x){
return x==f[x]?x:f[x]=find(f[x]);
}
inline int isroot(int x){
return x!=T[T[x].fa].son[0]&&x!=T[T[x].fa].son[1];
}
inline int getson(int x){
return x==T[T[x].fa].son[1];
}
inline void update(int x){
T[x].mx=x;
int l=T[x].son[0];int r=T[x].son[1];
if(l){
if(T[T[x].mx].v<T[T[l].mx].v) T[x].mx=T[l].mx;
}
if(r){
if(T[T[x].mx].v<T[T[r].mx].v) T[x].mx=T[r].mx;
}
}
inline void downit(int x){
if(T[x].tag){
T[T[x].son[0]].tag^=1;
T[T[x].son[1]].tag^=1;
swap(T[x].son[0],T[x].son[1]);
T[x].tag=0;
}
}
inline void rotate(int x){
int old=T[x].fa;int oldf=T[old].fa;int which=getson(x);
if(!isroot(old)) T[oldf].son[getson(old)]=x;
T[old].son[which]=T[x].son[which^1];T[T[old].son[which]].fa=old;
T[x].son[which^1]=old;T[old].fa=x;T[x].fa=oldf;
update(old);update(x);
}
inline void splay(int x){
//if(opp) cout<<opp<<endl;
top=0;p[++top]=x;
for(int i=x;!isroot(i);i=T[i].fa){
p[++top]=T[i].fa;
}
for(int i=top;i;i--){
downit(p[i]);
}
//if(opp) cout<<x<<‘ ‘<<T[x].fa<<‘ ‘;
while(!isroot(x)){
int old=T[x].fa;
if(!isroot(old)){
if(getson(old)==getson(x)) rotate(old);
else rotate(x);
}
rotate(x);
}
//if(opp) cout<<x<<‘ ‘<<T[x].fa<<endl;
}
inline void access(int x){
int t=0;
while(x){//cout<<x<<‘ ‘<<T[x].fa<<‘ ‘<<opp<<endl;
splay(x);T[x].son[1]=t;update(x);t=x;x=T[x].fa;
}
}
inline void Reverse(int x){
access(x);splay(x);T[x].tag^=1;
}
inline void linkk(int x,int y){
Reverse(x);T[x].fa=y;
}
inline void cut(int x,int y){
Reverse(x);access(y);splay(y);T[y].son[0]=T[x].fa=0;update(y);
}
inline int getmax(int x,int y){
Reverse(x);access(y);splay(y);
return T[y].mx;
}
/*inline void print(){
for(int i=1;i<=m+n;i++){
printf("%d ",T[i].fa);
}
printf("\n");
}*/
int main(){
//freopen("All.in","r",stdin);
//freopen("zh.out","w",stdout);
n=read();m=read();Q=read();
for(int i=1;i<=m;i++){
a[i].x=read();a[i].y=read();a[i].v=read();
if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
}
sort(a+1,a+m+1,cmp1);
for(int i=1;i<=m;i++){
T[i+n].v=a[i].v;
T[i+n].mx=n+i;
a[i].id=i;
}
sort(a+1,a+m+1,cmp2);
for(int i=1;i<=Q;i++){
q[i].op=read();q[i].x=read();q[i].y=read();
if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
if(q[i].op==2){
int t=check(q[i].x,q[i].y);q[i].id=a[t].id;
a[t].is=1;
}
}
sort(a+1,a+m+1,cmp3);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++){
if(a[i].is) continue;
int x=find(a[i].x);int y=find(a[i].y);
if(x!=y) linkk(a[i].x,i+n),linkk(a[i].y,i+n),f[x]=y,tot++;
if(tot==n-1) break;
}
for(int i=Q;i>=1;i--){
opp=i;
if(q[i].op==1){
q[i].ans=T[getmax(q[i].x,q[i].y)].v;
}
else{
int k=getmax(q[i].x,q[i].y);
//printf("%d\n",k);
if(T[k].v<=a[q[i].id].v) continue;
//printf("%d %d %d %d %d %d\n",a[k-n].x,a[k-n].y,k,q[i].x,q[i].y,q[i].id+n);
cut(a[k-n].x,k);cut(a[k-n].y,k);
linkk(q[i].x,q[i].id+n);linkk(q[i].y,q[i].id+n);
}
}
for(int i=1;i<=Q;i++){
if(q[i].op==1){
printf("%d\n",q[i].ans);
}
}
return 0;
}