1 #include<cstdio>
2 #include<iostream>
3 #include<math.h>
4 #include<algorithm>
5 using namespace std;
6 const int maxn=100033;
7 const int maxm=1000033;
8 int treec[maxm+maxn][2],treefa[maxm+maxn],treemax[maxm+maxn],treepos[maxm+maxn],treeval[maxm+maxn];
9 bool treerev[maxm+maxn];
10 struct zs{
11 int id,k,x,y,val;
12 }ask[maxn];
13 struct edge{
14 int id,from,too,val;
15 bool broken;
16 }e[maxm],e1[maxm];
17 int stack[maxm+maxn],ans[maxn];
18 int i,j,n,m,q;
19
20 inline int read()
21 {
22 int x=0,f=1;char ch=getchar();
23 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
24 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
25 return x*f;
26 }
27 inline bool isroot(int x){return treec[treefa[x]][0]!=x&&treec[treefa[x]][1]!=x;
28 }
29 inline void update(int x){
30 int l=treec[x][0],r=treec[x][1];
31 treemax[x]=treeval[x];treepos[x]=x;
32 if(treemax[l]>treemax[x])treemax[x]=treemax[l],treepos[x]=treepos[l];
33 if(treemax[r]>treemax[x])treemax[x]=treemax[r],treepos[x]=treepos[r];
34 }
35 inline void pushdown(int x){
36 if(!treerev[x])return;
37 int l=treec[x][0],r=treec[x][1];
38 if(l)treerev[l]^=1;if(r)treerev[r]^=1;
39 treerev[x]^=1;swap(treec[x][0],treec[x][1]);
40 }
41 inline void rotate(int x){
42 int fa=treefa[x],gfa=treefa[fa];
43 if(!isroot(fa))treec[gfa][treec[gfa][1]==fa]=x;
44 int l=treec[fa][1]==x,r=l^1;
45 treec[fa][l]=treec[x][r];treec[x][r]=fa;
46 treefa[x]=gfa;treefa[fa]=x;treefa[treec[fa][l]]=fa;
47 update(fa);update(x);
48 }
49 inline void splay(int x){
50 int top=0,tmp=x;stack[++top]=x;
51 while(!isroot(tmp))stack[++top]=treefa[tmp],tmp=treefa[tmp];
52 while(top)pushdown(stack[top]),top--;
53 int fa,gfa;
54 while(!isroot(x)){
55 fa=treefa[x];gfa=treefa[fa];
56 if(!isroot(fa))
57 if((treec[gfa][0]==fa)^(treec[fa][0]==x))rotate(x);
58 else rotate(fa);
59 rotate(x);
60 }
61 }
62 inline void access(int x){
63 int son=0;
64 while(x){
65 splay(x);treec[x][1]=son;update(x);
66 son=x;x=treefa[x];
67 }
68 }
69 inline void makeroot(int x){
70 access(x);splay(x);treerev[x]^=1;
71 }
72 inline void link(int x,int y){
73 makeroot(x);treefa[x]=y;
74 }
75 inline void cut(int x,int y){
76 makeroot(x);access(y);splay(y);treec[y][0]=treefa[x]=0;update(y);
77 }
78 inline int getfa(int x){
79 access(x);splay(x);
80 while(treec[x][0])x=treec[x][0],pushdown(x);
81 return x;
82 }
83 inline int half(int x,int y){
84 int l=0,r=m,mid;
85 while(l<r){
86 mid=l+r>>1;
87 if((e[mid].from<x)||(e[mid].from==x&&e[mid].too<y))l=mid+1;
88 else r=mid;
89 }
90 return l;
91 }
92 bool cmp(edge a,edge b){
93 return ((a.from<b.from)||(a.from==b.from&&a.too<b.too));
94 }
95 bool cmp1(edge a,edge b){
96 return a.val<b.val;
97 }
98 inline int getpos(int x,int y){
99 makeroot(x);access(y);splay(y);return treepos[y];
100 }
101 int main(){
102 n=read();m=read();q=read();
103 for(i=1;i<=m;i++){
104 e[i].from=read();e[i].too=read();e[i].val=read();
105 if(e[i].from>e[i].too)swap(e[i].from,e[i].too);
106 }
107 sort(e+1,e+1+m,cmp);
108 for(i=1;i<=m;i++)e[i].id=i,treeval[i+n]=treemax[i+n]=e[i].val,treepos[i+n]=i+n;
109 for(i=1;i<=q;i++){
110 ask[i].k=read();ask[i].x=read();ask[i].y=read();
111 if(ask[i].k==2)if(ask[i].x>ask[i].y)swap(ask[i].x,ask[i].y);
112 if(ask[i].k==2)ask[i].id=half(ask[i].x,ask[i].y),e[ask[i].id].broken=1,ask[i].val=e[ask[i].id].val;
113 }
114 sort(e+1,e+1+m,cmp1);
115 for(i=1;i<=m;i++)e1[e[i].id]=e[i];
116 int tot=0;
117 for(i=1;i<=m;i++)
118 if(!e[i].broken){
119 int x=e[i].from,y=e[i].too;
120 if(getfa(x)!=getfa(y))link(x,e[i].id+n),link(e[i].id+n,y),tot++;
121 if(tot==n-1)break;
122 }
123 for(i=q;i;i--){
124 if(ask[i].k==1)ans[i]=treeval[getpos(ask[i].x,ask[i].y)];
125 else if(ask[i].k==2){
126 int x=ask[i].x,y=ask[i].y,pos=getpos(x,y);
127 if(treeval[pos]>ask[i].val){
128 cut(e1[pos-n].from,pos);cut(pos,e1[pos-n].too);
129 link(x,ask[i].id+n);link(ask[i].id+n,y);
130 }
131 }
132 }
133 for(i=1;i<=q;i++)if(ask[i].k==1)printf("%d\n",ans[i]);
134 return 0;
135 }