1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long LL;
4
5 const int MAXV = 100010;
6 const int MAXE = 1000010;
7
8 #define foreach(iter, v) for(__typeof(v.begin()) iter = v.begin(); iter != v.end(); ++iter)
9 #define FOR(i, n) for(int i = 0; i < n; ++i)
10
11 inline int readint() {
12 char c = getchar();
13 while(!isdigit(c)) c = getchar();
14 int res = 0;
15 while(isdigit(c)) res = res * 10 + c - ‘0‘, c = getchar();
16 return res;
17 }
18
19 struct DSU {
20 int fa[MAXV];
21
22 void init(int n) {
23 for(int i = 1; i <= n; ++i)
24 fa[i] = i;
25 }
26
27 int find_set(int x) {
28 return fa[x] == x ? x : fa[x] = find_set(fa[x]);
29 }
30
31 void merge(int x, int y) {
32 fa[find_set(x)] = find_set(y);
33 }
34 } dsu;
35
36 struct Edge {
37 int u, v, cost;
38 bool del, use;
39
40 Edge() {}
41 Edge(int u, int v):
42 u(u), v(v) {}
43
44 int getv(int x) {
45 return x != u ? u : v;
46 }
47
48 void read() {
49 u = readint(), v = readint(), cost = readint();
50 if(u > v) swap(u, v);
51 del = use = false;
52 }
53
54 bool operator < (const Edge &rhs) const {
55 return cost < rhs.cost;
56 }
57 } edge[MAXE];
58
59 bool cmp_uv(const Edge &a, const Edge &b) {
60 if(a.u != b.u) return a.u < b.u;
61 return a.v < b.v;
62 }
63
64 struct Operator {
65 int k, a, b, mid;
66 void read() {
67 k = readint(), a = readint(), b = readint();
68 if(a > b) swap(a, b);
69 }
70 } oper[MAXV];
71
72 void kruskal(int n, int m) {
73 sort(edge, edge + m);
74 dsu.init(n);
75 for(int i = 0; i < m; ++i) if(!edge[i].del) {
76 if(dsu.find_set(edge[i].u) != dsu.find_set(edge[i].v)) {
77 edge[i].use = true;
78 dsu.merge(edge[i].u, edge[i].v);
79 }
80 }
81 }
82
83 struct Node {
84 Node *ch[2], *fa;
85 int id, ans;
86 bool rev, rt;
87 } statePool[MAXV + MAXE], *nil;
88 int ncnt;
89
90 vector<int> adj[MAXV];
91 Node *ptr[MAXV];
92
93 void init() {
94 ptr[0] = nil = statePool;
95 nil->ans = -1;
96 ncnt = 1;
97 }
98
99 Node* new_node(int i, Node *f) {
100 Node *x = statePool + ncnt++;
101 x->ch[0] = x->ch[1] = nil; x->fa = f;
102 x->id = x->ans = i;
103 x->rev = false; x->rt = true;
104 return x;
105 }
106
107 void dfs(int u, int fa, Node *f) {
108 ptr[u] = new_node(-1, f);
109 foreach(it, adj[u]) {
110 int v = edge[*it].getv(u);
111 if(v == fa) continue;
112 dfs(v, u, new_node(*it, ptr[u]));
113 }
114 }
115
116 int max_id(int a, int b) {
117 if(a > b) swap(a, b);
118 if(a == -1) return b;
119 return edge[a].cost > edge[b].cost ? a : b;
120 }
121
122 void update(Node *x) {
123 x->ans = x->id;
124 FOR(k, 2) x->ans = max_id(x->ans, x->ch[k]->ans);
125 }
126
127 void rotate(Node *x) {
128 Node *y = x->fa;
129 int t = (y->ch[1] == x);
130
131 if(y->rt) y->rt = false, x->rt = true;
132 else y->fa->ch[y->fa->ch[1] == y] = x;
133 x->fa = y->fa;
134
135 (y->ch[t] = x->ch[t ^ 1])->fa = y;
136 (x->ch[t ^ 1] = y)->fa = x;
137 update(y);
138 }
139
140 void modify_rev(Node *x) {
141 if(x == nil) return ;
142 x->rev = !x->rev;
143 swap(x->ch[0], x->ch[1]);
144 }
145
146 void pushdown(Node *x) {
147 if(x->rev) {
148 FOR(k, 2) modify_rev(x->ch[k]);
149 x->rev = false;
150 }
151 }
152
153 void push(Node *x) {
154 if(!x->rt) push(x->fa);
155 pushdown(x);
156 }
157
158 void splay(Node *x) {
159 push(x);
160 while(!x->rt) {
161 Node *f = x->fa, *ff = f->fa;
162 if(!f->rt) rotate((ff->ch[1] == f) == (f->ch[1] == x) ? f : x);
163 rotate(x);
164 }
165 update(x);
166 }
167
168 Node *access(Node *x) {
169 Node *y = nil;
170 while(x != nil) {
171 splay(x);
172 x->ch[1]->rt = true;
173 (x->ch[1] = y)->rt = false;
174 update(x);
175 y = x; x = x->fa;
176 }
177 return y;
178 }
179
180 void be_root(Node *x) {
181 access(x);
182 splay(x);
183 modify_rev(x);
184 }
185
186 void link(Node *x, Node *y) {
187 be_root(x);
188 x->fa = y;
189 }
190
191 void cut(Node *x, Node *y) {
192 be_root(x);
193 splay(y);
194 y->ch[0]->fa = y->fa;
195 y->ch[0]->rt = true;
196 y->fa = y->ch[0] = nil;
197 update(y);
198 }
199
200 int query(Node *x, Node *y) {
201 be_root(x);
202 return access(y)->ans;
203 }
204
205 int n, m, q;
206
207 int main() {
208 n = readint(), m = readint(), q = readint();
209 for(int i = 0; i < m; ++i) edge[i].read();
210 for(int i = 0; i < q; ++i) oper[i].read();
211
212 sort(edge, edge + m, cmp_uv);
213 for(int i = 0; i < q; ++i) if(oper[i].k == 2) {
214 oper[i].mid = lower_bound(edge, edge + m, Edge(oper[i].a, oper[i].b), cmp_uv) - edge;
215 edge[oper[i].mid].del = true;
216 }
217 kruskal(n, m);
218 sort(edge, edge + m, cmp_uv);
219
220 init();
221 for(int i = 0; i < m; ++i) if(edge[i].use)
222 adj[edge[i].u].push_back(i), adj[edge[i].v].push_back(i);
223 dfs(1, 0, nil);
224
225 vector<int> ans;
226 for(int i = q - 1; i >= 0; --i) {
227 int t = query(ptr[oper[i].a], ptr[oper[i].b]);
228 if(oper[i].k == 1) {
229 ans.push_back(edge[t].cost);
230 } else if(edge[t].cost > edge[oper[i].mid].cost) {
231 cut(ptr[edge[t].u], ptr[edge[t].v]);
232 Node *x = new_node(oper[i].mid, nil);
233 link(x, ptr[oper[i].a]);
234 link(x, ptr[oper[i].b]);
235 }
236 }
237
238 for(vector<int>::reverse_iterator it = ans.rbegin(); it != ans.rend(); ++it)
239 printf("%d\n", *it);
240 }