#include <stdio.h>
#include <string.h>
const int maxn1 = 201000, maxn2 = 2001000;
struct p{int x, y, k, t;}a[maxn1];
struct point{int x, y, t, can;}b[maxn2];
struct node{int typec, rever, k, max, pos; node *ch[2], *f;} tree[maxn1 * 2], *g[maxn1 * 2];
int i, n, q, m, num, j, first[maxn1 * 2], first1[maxn1], next[maxn2 * 2], next1[maxn1], e[maxn2 * 2], e1[maxn1], bh[maxn2], bj[maxn1 * 2], c[maxn2], bh1[maxn1 * 2], cost[maxn2];
void link(int u, int v, int cost = 0)
{
e[++num] = v, next[num] = first[u], first[u] = num, bh[num] = i, c[num] = cost;
e[++num] = u, next[num] = first[v], first[v] = num, bh[num] = i, c[num] = cost;
}
void link1(int u, int v)
{
e1[++num] = v, next1[num] = first1[u], first1[u] = num, bh1[num] = i;
e1[++num] = u, next1[num] = first1[v], first1[v] = num, bh1[num] = i;
}
void qsort(int l, int r)
{
int ii = l, jj = r, kk = b[ii + jj >> 1].t;
while (ii <= jj)
{
while (b[ii].t < kk) ++ii; while (b[jj].t > kk) --jj;
if (ii <= jj) {point mid = b[ii]; b[ii++] = b[jj], b[jj--] = mid;}
}
if (ii < r) qsort(ii, r);
if (jj > l) qsort(l, jj);
}
int getfa(int v)
{
if (e1[v] != v) return getfa(e1[v]);
return e1[v];
}
void mst()
{
qsort(1, m);
memset(first, 0, sizeof(first));
for (i = 1; i <= n; ++i) e1[i] = i;
for (i = 1, num = 0; i <= m; ++i)
if (b[i].can)
{
int f1 = getfa(b[i].x), f2 = getfa(b[i].y);
if (f1 != f2)
{
e1[f1] = f2;
link(b[i].x, b[i].y, b[i].t);
}
}
memset(bj, 0, sizeof(bj));
for (i = 0; i <= n *2 + q; ++i) g[i] = &tree[i];
for (i = 1, num = n; i <= n; ++i)
if (!bj[i])
{
g[i]->typec = 2, g[i]->f = NULL, bj[i] = 1;
g[i]->ch[0] = g[i]->ch[1] = g[0];
int l, r;
for (e1[l = r = bj[i] = 1] = i; l <= r; ++l)
for (int p = first[j = e1[l]]; p; p = next[p])
if (!bj[e[p]])
{
bj[e[p]] = 1, g[e[p]]->f = g[++num], g[num]->k = g[num]->max = c[p];
g[e[p]]->ch[0] = g[e[p]]->ch[1] = g[num]->ch[0] = g[num]->ch[1] = g[0];
g[e[p]]->typec = g[num]->typec = 2, g[num]->f = g[j];
g[e[p]]->pos = e[p], g[j]->pos = j, g[num]->pos = num;
e1[++r] = e[p];
}
}
}
void rev(node *x)
{
if ((x == NULL) || (x == g[0])) return ;
node *mid = x->ch[0];
x->ch[0] = x->ch[1], x->ch[1] = mid;
x->ch[0]->typec = 0, x->ch[1]->typec = 1;
x->rever = !x->rever;
}
void pushdown(node *x)
{
if ((x == NULL) || (x == g[0])) return;
if (x->rever) rev(x->ch[0]), rev(x->ch[1]), x->rever = 0;
}
void updata(node *x)
{
x->max = x->k, x->pos = x - g[0];
if (x->ch[0]->max >= x->max)
x->max = x->ch[0]->max, x->pos = x->ch[0]->pos;
if (x->ch[1]->max >= x->max)
x->max = x->ch[1]->max, x->pos = x->ch[1]->pos;
}
void rotata(node *x, int p)
{
node *y = x->f, *z = x->f->f;
int q = y->typec;
pushdown(y), pushdown(x);
if (z != NULL && q != 2) z->ch[q] = x;
x->f = z;
x->typec = q;
y->ch[p] = x->ch[!p];
if (y->ch[p] != g[0]) y->ch[p]->f = y, y->ch[p]->typec = p;
x->ch[!p] = y, y->f = x, y->typec = !p;
updata(y);
}
void splay(node *x)
{
node *u;
pushdown(x);
for (int p, q; 1;)
{
if ((p = x->typec) == 2) break;
u = x->f, q = u->typec;
if (p == q) rotata(u, p); else rotata(x, p);
if (q == 2) break;
rotata(x, q);
} updata(x);
}
node *access(int x)
{
node *u = g[x], *v = g[0];
for (; u != NULL; )
{
splay(u);
if (u->ch[1] != g[0]) u->ch[1]->typec = 2;
u->ch[1] = v, updata(u);
if (v != g[0]) v->f = u, v->typec = 1;
v = u, u = u->f;
}
return v;
}
node *ask(int x, int y)
{
node *v = access(x);
v = access(y);
splay(v);
if (g[x] != v)
{
splay(g[x]);
if (v->ch[1]->max < g[x]->max)
return g[g[x]->pos];
}
return g[v->ch[1]->pos];
}
void add(int x, int y)
{
node *u = ask(x, y), *v;
if (a[i].t > u->k) return;
v = access(u - g[0]);
splay(u);
u->ch[0]->f = NULL;
u->ch[0]->typec = 2, u->ch[0] = g[0];
u->k = 0, updata(u);
v = access(x);
splay(g[x]);
rev(g[x]);
g[++num]->f = g[y];
g[num]->ch[0] = g[num]->ch[1] = g[0];
g[g[num]->pos = num]->typec = 2;
g[num]->k = g[num]->max = a[i].t;
g[x]->f = g[num], g[x]->typec = 2;
}
int getint()
{
char ch = getchar();
for ( ; ch > '9' || ch < '0'; ch = getchar());
int tmp = 0;
for ( ; '0' <= ch && ch <= '9'; ch = getchar())
tmp = tmp * 10 + int(ch) - 48;
return tmp;
}
int main()
{
freopen("tube.in", "r", stdin);
freopen("tube.out", "w", stdout);
n = getint();
m = getint();
q = getint();
for (i = 1; i <= m; ++i)
{
b[i].x = getint();
b[i].y = getint();
b[i].t = getint();
link(b[i].x, b[i].y, b[i].t);
b[i].can = 1;
}
for (i = 1, num = 0; i <= q; ++i)
{
a[i].k = getint();
a[i].x = getint();
a[i].y = getint();
if (a[i].k == 2) link1(a[i].x, a[i].y);
}
for (i = 1; i <= n; ++i)
{
for (int p = first1[i]; p; p = next1[p]) bj[e1[p]] = i;
for (int p = first[i]; p; p = next[p]) if (bj[e[p]] == i) b[bh[p]].can = 0, cost[e[p]] = c[p];
for (int p = first1[i]; p; p = next1[p]) a[bh1[p]].t = cost[e1[p]];
}
for (mst(), i = q; i >= 1; --i)
if (a[i].k == 1) e[i] = ask(a[i].x, a[i].y)->max;
else add(a[i].x, a[i].y);
for (i = 1; i <= q; ++i)
if (a[i].k == 1) printf("%d\n", e[i]);
return 0;
}
#include <string.h>
const int maxn1 = 201000, maxn2 = 2001000;
struct p{int x, y, k, t;}a[maxn1];
struct point{int x, y, t, can;}b[maxn2];
struct node{int typec, rever, k, max, pos; node *ch[2], *f;} tree[maxn1 * 2], *g[maxn1 * 2];
int i, n, q, m, num, j, first[maxn1 * 2], first1[maxn1], next[maxn2 * 2], next1[maxn1], e[maxn2 * 2], e1[maxn1], bh[maxn2], bj[maxn1 * 2], c[maxn2], bh1[maxn1 * 2], cost[maxn2];
void link(int u, int v, int cost = 0)
{
e[++num] = v, next[num] = first[u], first[u] = num, bh[num] = i, c[num] = cost;
e[++num] = u, next[num] = first[v], first[v] = num, bh[num] = i, c[num] = cost;
}
void link1(int u, int v)
{
e1[++num] = v, next1[num] = first1[u], first1[u] = num, bh1[num] = i;
e1[++num] = u, next1[num] = first1[v], first1[v] = num, bh1[num] = i;
}
void qsort(int l, int r)
{
int ii = l, jj = r, kk = b[ii + jj >> 1].t;
while (ii <= jj)
{
while (b[ii].t < kk) ++ii; while (b[jj].t > kk) --jj;
if (ii <= jj) {point mid = b[ii]; b[ii++] = b[jj], b[jj--] = mid;}
}
if (ii < r) qsort(ii, r);
if (jj > l) qsort(l, jj);
}
int getfa(int v)
{
if (e1[v] != v) return getfa(e1[v]);
return e1[v];
}
void mst()
{
qsort(1, m);
memset(first, 0, sizeof(first));
for (i = 1; i <= n; ++i) e1[i] = i;
for (i = 1, num = 0; i <= m; ++i)
if (b[i].can)
{
int f1 = getfa(b[i].x), f2 = getfa(b[i].y);
if (f1 != f2)
{
e1[f1] = f2;
link(b[i].x, b[i].y, b[i].t);
}
}
memset(bj, 0, sizeof(bj));
for (i = 0; i <= n *2 + q; ++i) g[i] = &tree[i];
for (i = 1, num = n; i <= n; ++i)
if (!bj[i])
{
g[i]->typec = 2, g[i]->f = NULL, bj[i] = 1;
g[i]->ch[0] = g[i]->ch[1] = g[0];
int l, r;
for (e1[l = r = bj[i] = 1] = i; l <= r; ++l)
for (int p = first[j = e1[l]]; p; p = next[p])
if (!bj[e[p]])
{
bj[e[p]] = 1, g[e[p]]->f = g[++num], g[num]->k = g[num]->max = c[p];
g[e[p]]->ch[0] = g[e[p]]->ch[1] = g[num]->ch[0] = g[num]->ch[1] = g[0];
g[e[p]]->typec = g[num]->typec = 2, g[num]->f = g[j];
g[e[p]]->pos = e[p], g[j]->pos = j, g[num]->pos = num;
e1[++r] = e[p];
}
}
}
void rev(node *x)
{
if ((x == NULL) || (x == g[0])) return ;
node *mid = x->ch[0];
x->ch[0] = x->ch[1], x->ch[1] = mid;
x->ch[0]->typec = 0, x->ch[1]->typec = 1;
x->rever = !x->rever;
}
void pushdown(node *x)
{
if ((x == NULL) || (x == g[0])) return;
if (x->rever) rev(x->ch[0]), rev(x->ch[1]), x->rever = 0;
}
void updata(node *x)
{
x->max = x->k, x->pos = x - g[0];
if (x->ch[0]->max >= x->max)
x->max = x->ch[0]->max, x->pos = x->ch[0]->pos;
if (x->ch[1]->max >= x->max)
x->max = x->ch[1]->max, x->pos = x->ch[1]->pos;
}
void rotata(node *x, int p)
{
node *y = x->f, *z = x->f->f;
int q = y->typec;
pushdown(y), pushdown(x);
if (z != NULL && q != 2) z->ch[q] = x;
x->f = z;
x->typec = q;
y->ch[p] = x->ch[!p];
if (y->ch[p] != g[0]) y->ch[p]->f = y, y->ch[p]->typec = p;
x->ch[!p] = y, y->f = x, y->typec = !p;
updata(y);
}
void splay(node *x)
{
node *u;
pushdown(x);
for (int p, q; 1;)
{
if ((p = x->typec) == 2) break;
u = x->f, q = u->typec;
if (p == q) rotata(u, p); else rotata(x, p);
if (q == 2) break;
rotata(x, q);
} updata(x);
}
node *access(int x)
{
node *u = g[x], *v = g[0];
for (; u != NULL; )
{
splay(u);
if (u->ch[1] != g[0]) u->ch[1]->typec = 2;
u->ch[1] = v, updata(u);
if (v != g[0]) v->f = u, v->typec = 1;
v = u, u = u->f;
}
return v;
}
node *ask(int x, int y)
{
node *v = access(x);
v = access(y);
splay(v);
if (g[x] != v)
{
splay(g[x]);
if (v->ch[1]->max < g[x]->max)
return g[g[x]->pos];
}
return g[v->ch[1]->pos];
}
void add(int x, int y)
{
node *u = ask(x, y), *v;
if (a[i].t > u->k) return;
v = access(u - g[0]);
splay(u);
u->ch[0]->f = NULL;
u->ch[0]->typec = 2, u->ch[0] = g[0];
u->k = 0, updata(u);
v = access(x);
splay(g[x]);
rev(g[x]);
g[++num]->f = g[y];
g[num]->ch[0] = g[num]->ch[1] = g[0];
g[g[num]->pos = num]->typec = 2;
g[num]->k = g[num]->max = a[i].t;
g[x]->f = g[num], g[x]->typec = 2;
}
int getint()
{
char ch = getchar();
for ( ; ch > '9' || ch < '0'; ch = getchar());
int tmp = 0;
for ( ; '0' <= ch && ch <= '9'; ch = getchar())
tmp = tmp * 10 + int(ch) - 48;
return tmp;
}
int main()
{
freopen("tube.in", "r", stdin);
freopen("tube.out", "w", stdout);
n = getint();
m = getint();
q = getint();
for (i = 1; i <= m; ++i)
{
b[i].x = getint();
b[i].y = getint();
b[i].t = getint();
link(b[i].x, b[i].y, b[i].t);
b[i].can = 1;
}
for (i = 1, num = 0; i <= q; ++i)
{
a[i].k = getint();
a[i].x = getint();
a[i].y = getint();
if (a[i].k == 2) link1(a[i].x, a[i].y);
}
for (i = 1; i <= n; ++i)
{
for (int p = first1[i]; p; p = next1[p]) bj[e1[p]] = i;
for (int p = first[i]; p; p = next[p]) if (bj[e[p]] == i) b[bh[p]].can = 0, cost[e[p]] = c[p];
for (int p = first1[i]; p; p = next1[p]) a[bh1[p]].t = cost[e1[p]];
}
for (mst(), i = q; i >= 1; --i)
if (a[i].k == 1) e[i] = ask(a[i].x, a[i].y)->max;
else add(a[i].x, a[i].y);
for (i = 1; i <= q; ++i)
if (a[i].k == 1) printf("%d\n", e[i]);
return 0;
}