#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// Fast IO
struct FastIO {
FastIO() {
ios::sync_with_stdio(false);
cin.tie(NULL);
}
};
// Segment Tree with Lazy Propagation
struct SegmentTree {
int n;
vector<long long> tree;
vector<int> lazy;
SegmentTree(int size) {
n = size;
tree.assign(4*n, 0);
lazy.assign(4*n, 0);
}
// Build the segment tree
void build(vector<int> &A, int idx, int l, int r) {
if(l == r){
tree[idx] = A[l];
return;
}
int mid = (l + r) / 2;
build(A, 2*idx, l, mid);
build(A, 2*idx+1, mid+1, r);
tree[idx] = tree[2*idx] + tree[2*idx+1];
}
// Push down the lazy updates
void push(int idx, int l, int r){
if(lazy[idx]){
// Toggle operation: flip the bits in this segment
tree[idx] = (r - l + 1) - tree[idx];
if(l != r){
lazy[2*idx] ^= 1;
lazy[2*idx+1] ^= 1;
}
lazy[idx] = 0;
}
}
// Update range [ql, qr]
void update(int idx, int l, int r, int ql, int qr){
push(idx, l, r);
if(r < ql || l > qr) return;
if(ql <= l && r <= qr){
lazy[idx] ^= 1;
push(idx, l, r);
return;
}
int mid = (l + r) / 2;
update(2*idx, l, mid, ql, qr);
update(2*idx+1, mid+1, r, ql, qr);
tree[idx] = tree[2*idx] + tree[2*idx+1];
}
// Query range [ql, qr]
long long query(int idx, int l, int r, int ql, int qr){
push(idx, l, r);
if(r < ql || l > qr) return 0;
if(ql <= l && r <= qr){
return tree[idx];
}
int mid = (l + r) / 2;
return query(2*idx, l, mid, ql, qr) + query(2*idx+1, mid+1, r, ql, qr);
}
};
// Euler Tour to flatten the tree
struct EulerTour {
int n;
vector<vector<int>> adj;
vector<int> in_time;
vector<int> out_time;
int timer;
EulerTour(int size) {
n = size;
adj.assign(n+1, vector<int>());
in_time.assign(n+1, 0);
out_time.assign(n+1, 0);
timer = 1;
}
void add_edge(int u, int v){
adj[u].push_back(v);
adj[v].push_back(u);
}
void dfs(int node, int parent){
in_time[node] = timer;
timer++;
for(auto &child: adj[node]){
if(child != parent){
dfs(child, node);
}
}
out_time[node] = timer -1;
}
};
int main(){
FastIO fio;
int N;
cin >> N;
// 1-based indexing
vector<int> A(N+1, 0);
for(int i=1; i<=N; ++i){
cin >> A[i];
}
EulerTour et(N);
for(int i=0; i<N-1; ++i){
int U, V;
cin >> U >> V;
et.add_edge(U, V);
}
// Perform Euler Tour
et.dfs(1, -1);
// Prepare array for segment tree based on Euler Tour
// Map the original A to the Euler Tour order
// We need to create an array where pos[in_time[node]] = A[node]
vector<int> tour(N+1, 0); // 1-based
for(int node=1; node<=N; ++node){
tour[et.in_time[node]] = A[node];
}
// Initialize and build the segment tree
SegmentTree st(N);
st.build(tour, 1, 1, N);
int Q;
cin >> Q;
while(Q--){
int type, K;
cin >> type >> K;
if(type == 1){
// Toggle operation
st.update(1, 1, N, et.in_time[K], et.out_time[K]);
}
else if(type == 2){
// Query operation
long long res = st.query(1, 1, N, et.in_time[K], et.out_time[K]);
cout << res << "\n";
}
}
return 0;
}