#include #include #include #include #include #include #include struct HLD { using Tree = std::vector>; const Tree &tree; std::vector parent; std::vector head; std::vector vid; HLD(const Tree &tree) : tree(tree) { const int n = tree.size(); const int root = 0; std::stack> stack; stack.emplace(root, 0); parent.assign(n, -1); head.assign(n, -1); vid.assign(n, -1); std::vector heavy(n, -1); std::vector size(n, 1); while (!stack.empty()) { const int u = stack.top().first; const int i = stack.top().second; if (i < tree[u].size()) { stack.top().second++; const int v = tree[u][i]; if (v != parent[u]) { parent[v] = u; stack.emplace(v, 0); } } else { stack.pop(); int max = 0; for (int v : tree[u]) { if (v != parent[u]) { size[u] += size[v]; if (max < size[v]) { max = size[v]; heavy[u] = v; } } } } } std::queue queue; queue.push(0); int now = 0; while (!queue.empty()) { const int h = queue.front(); queue.pop(); for (int i = h; i != -1; i = heavy[i]) { head[i] = h; vid[i] = now++; for (int j : tree[i]) { if (j != parent[i] && j != heavy[i]) { queue.push(j); } } } } } template void foreach(int u, int v, T func) { while (true) { if (vid[u] > vid[v]) { std::swap(u, v); } if (head[u] != head[v]) { func(vid[head[v]], vid[v]); v = parent[head[v]]; } else { func(vid[u], vid[v]); break; } } } int lca(int u, int v) { while (true) { if (vid[u] > vid[v]) { std::swap(u, v); } if (head[u] != head[v]) { v = parent[head[v]]; } else { return u; } } } }; std::vector TECC(const std::vector> &g) { const int n = g.size(); std::vector ord(n, -1); std::vector low(n); std::vector cid(n); std::vector s; int k = 0; int c = 0; std::function dfs = [&](int u, int p) { low[u] = ord[u] = k++; s.push_back(u); for (int v : g[u]) { if (ord[v] == -1) { dfs(v, u); low[u] = std::min(low[u], low[v]); } else if (v != p) { low[u] = std::min(low[u], ord[v]); } } if (p == -1 || ord[p] < low[u]) { while (true) { int v = s.back(); s.pop_back(); cid[v] = c; if (v == u) { break; } } c++; } }; for (int i = 0; i < n; i++) { if (ord[i] == -1) { dfs(i, -1); } } return cid; } int main() { int n, m, q; std::cin >> n >> m >> q; std::vector> g(n); for (int i = 0; i < m; i++) { int u, v; scanf("%d %d", &u, &v); u--; v--; g[u].push_back(v); g[v].push_back(u); } auto tecc = TECC(g); int nn = *max_element(tecc.begin(), tecc.end()) + 1; std::vector> gg(nn); for (int i = 0; i < n; i++) { for (int j : g[i]) { if (tecc[i] != tecc[j]) { gg[tecc[i]].push_back(tecc[j]); } } } HLD hld(gg); int N = 1; while (N < nn) { N *= 2; } std::vector> rmq(N * 2, std::make_pair(-1, 0)); auto setval = [&](int k, int v, int index) { rmq[k + N] = { v, index }; k += N; while (k > 1) { k /= 2; rmq[k] = std::max(rmq[k * 2], rmq[k * 2 + 1]); } }; auto getval = [&](int l, int r) { l += N; r += N; std::pair ret(-1, 0); while (l < r) { if (l & 1) { ret = std::max(ret, rmq[l++]); } if (r & 1) { ret = std::max(ret, rmq[--r]); } l /= 2; r /= 2; } return ret; }; std::vector> qs(nn); while (q--) { int t; scanf("%d", &t); if (t == 1) { int u, w; scanf("%d %d", &u, &w); u = tecc[u - 1]; if (qs[u].empty() || qs[u].top() < w) { setval(hld.vid[u], w, u); } qs[u].push(w); } else { int s, t; scanf("%d %d", &s, &t); s = tecc[s - 1]; t = tecc[t - 1]; std::pair ans(-1, 0); hld.foreach(s, t, [&](int l, int r) { ans = std::max(ans, getval(l, r + 1)); }); if (ans.first != -1) { qs[ans.second].pop(); if (qs[ans.second].empty()) { setval(hld.vid[ans.second], -1, ans.second); } else { setval(hld.vid[ans.second], qs[ans.second].top(), ans.second); } } printf("ans:%d\n", ans.first); } } }