// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=100050;
int gi()
{
int x=0,flag=1;
char ch=getchar();
while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) flag=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
return x*flag;
}
struct Block{
int a[210],size;
void insert(int x){
size++;int i;
for(i=size;i>1&&a[i-1]>x;i--) a[i]=a[i-1];
a[i]=x;
}
void update(int x,int y){
int pl=lower_bound(a+1,a+1+size,x)-a;
for(;pl<size&&a[pl+1]<y;pl++) a[pl]=a[pl+1];
for(;pl>1&&a[pl-1]>y;pl--) a[pl]=a[pl-1];
a[pl]=y;
}
int query(int x){
int pl=upper_bound(a+1,a+1+size,x)-a;
return size-pl+1;
}
}block[N];
int cnt,w[N],head[N],to[N],nxt[N],n,m,pos[N],tot,sz,ans,f[N];
vector<int>p[N];
void lnk(int x,int y){
to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
to[++cnt]=x,nxt[cnt]=head[y],head[y]=cnt;
}
void build(int x,int fa){
f[x]=fa;
if(block[pos[fa]].size==sz){
tot++;block[tot].insert(w[x]);
pos[x]=tot;p[pos[fa]].push_back(tot);
}
else block[pos[fa]].insert(w[x]),pos[x]=pos[fa];
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y!=fa) build(y,x);
}
}
void dfs_block(int x,int val){
ans+=block[x].query(val);
for(int i=0;i<p[x].size();i++) dfs_block(p[x][i],val);
}
void dfs(int x,int val){
if(w[x]>val) ans++;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y!=f[x]){
if(pos[y]==pos[x]) dfs(y,val);
else dfs_block(pos[y],val);
}
}
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
n=gi();
for(int i=1;i<n;i++){
int x=gi(),y=gi();lnk(x,y);
}
for(int i=1;i<=n;i++) w[i]=gi();
sz=sqrt(n)+1;build(1,0);
m=gi();ans=0;
for(int i=1;i<=m;i++){
int flag=gi(),u=gi(),v=gi();
u^=ans,v^=ans;
if(flag==0){
ans=0;dfs(u,v);
printf("%d\n",ans);
}
if(flag==1){
block[pos[u]].update(w[u],v);
w[u]=v;
}
if(flag==2){
n++;w[n]=v;f[n]=u;lnk(u,n);
if(block[pos[u]].size==sz){
tot++;block[tot].insert(w[n]);
pos[n]=tot;p[pos[u]].push_back(tot);
}
else block[pos[u]].insert(w[n]),pos[n]=pos[u];
}
}
return 0;
}