#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int mxsz=200;
vector<int> tr[60005];
vector<int> tr0[60005];
int tp;
int v[60005];
int b[60005];
struct block{
int vs[200],vp;
vector<int>ss;
int id;
block(){
vp=0;
}
void insert(int w);
void change(int a,int b);
int getans(int m);
};
bool isr[60005];
block bs[10005];
int bp=2;
void block::insert(int w){
if(vp<mxsz){
vs[vp++]=v[w];
sort(vs,vs+vp);
b[w]=id;
isr[w]=(vp==1?1:0);
}else{
ss.push_back(bp);
bs[bp++].insert(w);
isr[w]=1;
}
}
void block::change(int a,int b){
for(int i=0;i<vp;i++){
if(vs[i]==a){
vs[i]=b;
break;
}
}
sort(vs,vs+vp);
}
int block::getans(int m){
int ans=vp-(upper_bound(vs,vs+vp,m)-vs);
for(int i=ss.size()-1;i>=0;i--)ans+=bs[ss[i]].getans(m);
return ans;
}
int dfs(int m,int w){
if(isr[w])return bs[b[w]].getans(m);
int ans=0;
if(v[w]>m)ans++;
for(int i=tr[w].size()-1;i>=0;i--)ans+=dfs(m,tr[w][i]);
return ans;
}
void build(int w,int pa){
if(pa==-1)bs[1].insert(w);
else bs[b[pa]].insert(w);
for(int i=tr0[w].size()-1;i>=0;i--){
int u=tr0[w][i];
if(u!=pa)tr[w].push_back(u);
else continue;
build(u,w);
}
}
int n,m,op,p1,p2,la=0;
int main(){
for(int i=0;i<10005;i++)bs[i].id=i;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&p1,&p2);
tr0[p1].push_back(p2);
tr0[p2].push_back(p1);
}
for(int i=1;i<=n;i++){
scanf("%d",&p1);
v[i]=p1;
}
build(1,-1);
tp=n+1;
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&op,&p1,&p2);
p1^=la;p2^=la;
if(op==0){
printf("%d\n",la=dfs(p2,p1));
}else if(op==1){
bs[b[p1]].change(v[p1],p2);
v[p1]=p2;
}else{
tr[p1].push_back(tp);
v[tp]=p2;
bs[b[p1]].insert(tp);
tp++;
}
}
return 0;
}