
#include <iostream>
#include<string>
#include<vector>
using namespace std;

int cnt[100001];//色の有無を表す配列
int C[100001];
bool check[100001];
vector<vector<int> > E(100001);

void dfs(int n, int bef){
    if(cnt[C[n]]==0){
        check[n]=true;
    }
    cnt[C[n]]++;
    for(int i=0; i<E[n].size(); i++){
        if(E[n][i] != bef){
            dfs(E[n][i], n);
        }
    }
    cnt[C[n]]--;//ここ凄い大事、これがないと反対方向の色がカウントされっぱなしになる。
}
    

int main(){
    int N;
    cin>>N;
    int a, b;
    for(int i=0; i<N; i++){
        cin>>C[i];
    }
    for(int i=0; i<N-1; i++){
        cin>>a>>b;
        E[a-1].push_back(b-1);
        E[b-1].push_back(a-1);
    }
    dfs(0, -1);
    for(int i=0; i<N; i++){
        if(check[i]==true){
            cout<<i+1<<endl;
        }
    }
    return 0;
}
#pragma GCC optimize("Ofast", "unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;

constexpr ll INF = (1LL << 60);

struct func{
	ll base, m, M;
	func() : base(0), m(-INF), M(INF) {}
	ll value(ll x){
		ll tmp = x + base;
		tmp = max(m, tmp);
		tmp = min(M, tmp);
		return tmp;
	}
};

void merge(func& f, int type, ll a){
	if (type == 1){
		f.base += a;
		f.m += a;
		f.M += a;
	}
	else if (type == 2){
		if (f.M <= a){
			f.base = 0;
			f.m = a;
			f.M = a;
			return;
		}
		f.m = max(f.m, a);
	}
	else{
		if (f.m >= a){
			f.base = 0;
			f.m = a;
			f.M = a;
			return;
		}
		f.M = min(f.M, a);
	}
}

int main(void){
	int N; cin >> N;
	func f;
	for (int i = 0; i < N; ++i){
		int t; ll a;
		cin >> a >> t;
		merge(f, t, a);
	}
	int Q; cin >> Q;
	while(Q--){
		ll x; cin >> x;
		cout << f.value(x) << endl;
	}
	return 0;
}