#ifndef ONLINE_JUDGE #define _GLIBCXX_DEBUG #endif #include using namespace std; #define pass (void)0 #define INF (1<<30)-1 #define INFLL (1LL<<60)-1 #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define repr(i, n) for (int i = (int)(n) - 1; i >= 0; i--) #define rep2(i, a, b) for (int i = (int)(a); i < (int)(b); i++) #define repr2(i, a, b) for (int i = (int)(b) - 1; i >= (int)(a); i--) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define sz(x) ((int)(x).size()) #define YesNo(cond) cout << ((cond) ? "Yes\n" : "No\n") #define YESNO(cond) cout << ((cond) ? "YES\n" : "NO\n") using ll = long long; using pii = pair; using pll = pair; using vi = vector; using vl = vector; using vvi = vector; using vvl = vector; template void print(const T& value) { cout << value << "\n"; } template void print(const vector& vec) { for (auto& v : vec) cout << v << " "; cout << "\n"; } template void input(vector& vec) { for (auto& v : vec) cin >> v; }; template bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; } return false; } template bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } return false; } #include using namespace atcoder; using mint = modint998244353; using vm = vector; template struct UnionFindValue { int n; vector parent_size; // 負ならサイズ、正なら親 vector A; // 各リーダーが持つ値 UnionFindValue(int n, const vector& A_) : n(n), parent_size(n, -1), A(A_) {} int leader(int a) { if (parent_size[a] < 0) return a; return parent_size[a] = leader(parent_size[a]); } void merge(int a, int b) { a = leader(a); b = leader(b); if (a == b) return; T c = A[a]; // union by size if (-parent_size[a] < -parent_size[b]) swap(a, b); // a が大きい側 parent_size[a] += parent_size[b]; parent_size[b] = a; A[a] = c; } // A[x] を取得 T operator[](int x) { return A[leader(x)]; } // 値を上書き void update(int x, T v) { A[leader(x)] = v; } bool same(int a, int b) { return leader(a) == leader(b); } int size(int x) { return -parent_size[leader(x)]; } vector> groups() { vector> res(n); for (int i = 0; i < n; i++) { res[leader(i)].push_back(i); } vector> ans; for (auto &g : res) { if (!g.empty()) ans.push_back(g); } return ans; } }; vvi G; vl IN, OUT; vl order; ll dfs(ll n, ll p, ll time) { IN[n] = time; order.push_back(n); for (auto v : G[n]) { if (v == p) continue; time = dfs(v, n, time+1); } OUT[n] = time; return time; } vl C; struct LCA { int V; int LOG; vector> parent; vector depth; LCA(const vector>& G, int root = 0) { V = (int)G.size(); LOG = 1; while ((1 << LOG) < V) LOG++; parent.assign(LOG, vector(V, -1)); depth.assign(V, -1); bfs(G, root); for (int i = 0; i + 1 < LOG; i++) { for (int v = 0; v < V; v++) { if (parent[i][v] != -1) { parent[i + 1][v] = parent[i][ parent[i][v] ]; } } } } void bfs(const vector>& G, int root) { queue q; depth[root] = 0; q.push(root); while (!q.empty()) { int u = q.front(); q.pop(); for (int v : G[u]) { if (depth[v] == -1) { depth[v] = depth[u] + 1; parent[0][v] = u; q.push(v); } } } } int lca(int a, int b) const { if (depth[a] < depth[b]) swap(a, b); int diff = depth[a] - depth[b]; for (int i = 0; i < LOG; i++) { if (diff & (1 << i)) { a = parent[i][a]; } } if (a == b) return a; for (int i = LOG - 1; i >= 0; i--) { if (parent[i][a] != parent[i][b]) { a = parent[i][a]; b = parent[i][b]; } } return parent[0][a]; } int solve(int n, int x) { if (x == 1) return n; repr (i, LOG) { if (parent[i][n] != -1 && C[parent[i][n]] < x) { n = parent[i][n]; } } if (parent[0][n] != -1) { return parent[0][n]; } else { return -1; } } int dist(int a, int b) const { int c = lca(a, b); return depth[a] + depth[b] - 2 * depth[c]; } bool is_ancestor(int u, int v) const { return lca(u, v) == u; } int kth_ancestor(int v, int k) const { for (int i = 0; i < LOG; i++) { if (k & (1 << i)) { v = parent[i][v]; if (v == -1) break; } } return v; } int jump(int u, int v) const { if (u == v) return u; int c = lca(u, v); if (c == u) { return kth_ancestor(v, dist(u, v) - 1); } else { return parent[0][u]; } } int jump_k(int u, int v, int k) const { int d = dist(u, v); if (d <= k) return v; int c = lca(u, v); int du = depth[u] - depth[c]; if (k <= du) { return kth_ancestor(u, k); } else { return kth_ancestor(v, d - k); } } bool on_path(int u, int v, int x) const { return dist(u, x) + dist(x, v) == dist(u, v); } pair create_path(int u, int v, int x) const { if (on_path(u, v, x)) return {u, v}; if (on_path(u, x, v)) return {u, x}; if (on_path(v, x, u)) return {v, x}; return {-1, -1}; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(10); ll N, M, Q; cin >> N >> M >> Q; vl A(N); input(A); vector> edge; rep (_, M) { ll u, v, w; cin >> u >> v >> w; u --; v --; edge.push_back({w, u, v}); } vector query; rep (_, Q) { ll s, c; cin >> s >> c; s --; query.push_back({s, c}); } sort(all(edge)); vector def(N); rep (i, N) def[i] = i; UnionFindValue UF(N, def); ll cnt = N; G.assign(N*2-1, vi()); vl D(N, 0); for (auto [w, u, v] : edge) { if (UF.same(u, v)) continue; auto a = UF[u]; auto b = UF[v]; G[a].push_back(cnt); G[cnt].push_back(a); G[b].push_back(cnt); G[cnt].push_back(b); D.push_back(w); UF.merge(u, v); UF.update(u, cnt); cnt++; } IN.assign(N*2-1, -1); OUT.assign(N*2-1, -1); dfs(N*2-2, -1, 0); rep (i, N) A[i]--; rep (_, N-1) A.push_back(N); vl IDX(N+1, -1); vector> interval; rep (i, N*2-1) { interval.push_back({OUT[i], IN[i], i}); } sort(all(interval)); C.assign(N*2-1, -1); fenwick_tree B(N*2-1); ll idx = 0; rep (i, N*2-1) { auto now = A[order[i]]; if (IDX[now] != -1) { B.add(IDX[now], -1); } IDX[now] = i; B.add(i, 1); while (idx < N*2-1 && get<0>(interval[idx]) == i) { auto [r, l, qidx] = interval[idx]; C[qidx] = B.sum(l, r+1); if (N <= qidx) C[qidx]--; idx++; } } LCA lca(G, N*2-2); for (auto [s, c] : query) { auto idx = lca.solve(s, c); if (idx != -1) { print(D[idx]); } else { print(-1); } } }