#include using namespace std; int INF = 2000000000; vector> child(vector> E, int r){ int N = E.size(); vector> c(N); queue Q; Q.push(r); while (!Q.empty()){ int v = Q.front(); Q.pop(); for (int w : E[v]){ if (c[w].empty()){ c[v].push_back(w); Q.push(w); } } } return c; } void dfs_c(vector &C, vector> &c, int v){ for (int w : c[v]){ C[w] = max(C[v], C[w]); dfs_c(C, c, w); } } void dfs2(vector &ET, vector &pos, vector> &c, int v){ pos[v] = ET.size(); ET.push_back(v); for (int w : c[v]){ dfs2(ET, pos, c, w); ET.push_back(v); } } vector segtree_min(vector &A){ int N = 1; while (N < A.size()){ N = N * 2; } vector ST(N * 2 - 1); for (int i = 0; i < A.size(); i++){ ST[i + N - 1] = A[i]; } for (int i = A.size() + N - 1; i < N * 2 - 1; i++){ ST[i] = INF; } for (int i = N - 2; i >= 0; i--){ ST[i] = min(ST[i * 2 + 1], ST[i * 2 + 2]); } return ST; } void segtree_min_update(vector &ST, int i, int x){ int N = (ST.size() + 1) / 2; i = i + N - 1; ST[i] = x; while (i > 0){ i = (i - 1) / 2; ST[i] = min(ST[i * 2 + 1], ST[i * 2 + 2]); } return; } int segtree_min_query(vector &ST, int x, int y, int i, int L, int R){ if (y <= L || R <= x){ return INF; } else if (x <= L && R <= y){ return ST[i]; } else { int M = (L + R) / 2; int A = segtree_min_query(ST, x, y, i * 2 + 1, L, M); int B = segtree_min_query(ST, x, y, i * 2 + 2, M, R); return min(A, B); } } vector segtree_max(vector &A){ int N = 1; while (N < A.size()){ N = N * 2; } vector ST(N * 2 - 1); for (int i = 0; i < A.size(); i++){ ST[i + N - 1] = A[i]; } for (int i = A.size() + N - 1; i < N * 2 - 1; i++){ ST[i] = 0; } for (int i = N - 2; i >= 0; i--){ ST[i] = max(ST[i * 2 + 1], ST[i * 2 + 2]); } return ST; } void segtree_max_update(vector &ST, int i, int x){ int N = (ST.size() + 1) / 2; i = i + N - 1; ST[i] = x; while (i > 0){ i = (i - 1) / 2; ST[i] = max(ST[i * 2 + 1], ST[i * 2 + 2]); } return; } int segtree_max_query(vector &ST, int x, int y, int i, int L, int R){ if (y <= L || R <= x){ return 0; } else if (x <= L && R <= y){ return ST[i]; } else { int M = (L + R) / 2; int A = segtree_max_query(ST, x, y, i * 2 + 1, L, M); int B = segtree_max_query(ST, x, y, i * 2 + 2, M, R); return max(A, B); } } int main(){ int N, K, Q; cin >> N >> K >> Q; vector C(N); for (int i = 0; i < N; i++){ cin >> C[i]; } vector A(K); for (int i = 0; i < K; i++){ cin >> A[i]; A[i]--; } vector> E(N); for (int i = 0; i < N - 1; i++){ int e, f; cin >> e >> f; e--; f--; E[e].push_back(f); E[f].push_back(e); } vector> c = child(E, 0); dfs_c(C, c, 0); vector ET; vector pos(N); dfs2(ET, pos, c, 0); /* for (int i : ET){ cout << i << ' '; } cout << endl; for (int i = 0; i < N; i++){ cout << pos[i] << ' '; } cout << endl; */ for (int i = 0; i < K; i++){ A[i] = pos[A[i]]; //cout << A[i] << ' '; } //cout << endl; vector ST1 = segtree_min(ET); int x = (ST1.size() + 1) / 2; vector ST2 = segtree_min(A); vector ST3 = segtree_max(A); int y = (ST2.size() + 1) / 2; for (int i = 0; i < Q; i++){ int T; cin >> T; if (T == 1){ int X, Y; cin >> X >> Y; X--; Y--; segtree_min_update(ST2, X, pos[Y]); segtree_max_update(ST3, X, pos[Y]); /* for (int j = 0; j < K; j++){ cout << A[j] << ' '; } cout << endl; */ } if (T == 2){ int L, R; cin >> L >> R; L--; int left = segtree_min_query(ST2, L, R, 0, 0, y); int right = segtree_max_query(ST3, L, R, 0, 0, y); //cout << "left = " << left << ", right = " << right << endl; cout << C[segtree_min_query(ST1, left, right + 1, 0, 0, x)] << endl; } /* cout << "ST2" << endl; for (int j : ST2){ cout << j << ' '; } cout << endl; cout << "ST3" << endl; for (int j : ST2){ cout << j << ' '; } cout << endl; */ } }