#include<bits/stdc++.h>
#define Max(x,y) (x>y?x:y)
#define Min(x,y) (x<y?x:y)
using namespace std;
const int N=30010,M=300010,INF=0x3f3f3f3f;
int head[N],ver[M],Next[M],tot;
int size[N],son[N],f[N],d[N],w[N],pre[N],id[N],top[N],num;
int n,m;
void add(int x,int y){
ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
}
struct SegmentTree{
int l,r;
int mx,sum;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define mx(x) tree[x].mx
#define sum(x) tree[x].sum
}tree[N<<2];
void Pushup(int x){
sum(x)=sum(x<<1)+sum(x<<1|1);
mx(x)=Max(mx(x<<1),mx(x<<1|1));
}
void Build(int x,int l,int r){
l(x)=l,r(x)=r;
if(l==r){sum(x)=mx(x)=pre[l];return;}
int mid=(l+r)>>1;
Build(x<<1,l,mid);
Build(x<<1|1,mid+1,r);
Pushup(x);
}
void Change(int x,int q,int d){
int l=l(x),r=r(x);
if(l==r){sum(x)=mx(x)=d;return;}
int mid=(l+r)>>1;
if(q<=mid)Change(x<<1,q,d);
if(q>mid)Change(x<<1|1,q,d);
Pushup(x);
}
int QueryMax(int x,int L,int R){
int l=l(x),r=r(x);
if(L<=l&&r<=R)return mx(x);
int mid=(l+r)>>1;
int val=-INF;
if(L<=mid)val=Max(val,QueryMax(x<<1,L,R));
if(R>mid)val=Max(val,QueryMax(x<<1|1,L,R));
return val;
}
int QuerySum(int x,int L,int R){
int l=l(x),r=r(x);
if(L<=l&&r<=R)return sum(x);
int mid=(l+r)>>1;
int val=0;
if(L<=mid)val+=QuerySum(x<<1,L,R);
if(R>mid)val+=QuerySum(x<<1|1,L,R);
return val;
}
void dfs1(int x,int fa){
int t=-1;
f[x]=fa;size[x]=1;
d[x]=d[fa]+1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
dfs1(y,x);
size[x]+=size[y];
if(size[y]>t){
t=size[y];
son[x]=y;
}
}
}
void dfs2(int x,int fa){
top[x]=fa;
id[x]=++num;
if(w[x])pre[id[x]]=w[x];
if(!son[x])return;
dfs2(son[x],fa);
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==son[x]||y==f[x])continue;
dfs2(y,y);
}
}
int QueryPathMax(int x,int y){
int res=-INF;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
res=Max(res,QueryMax(1,id[top[x]],id[x]));
x=f[top[x]];
}
if(d[x]>d[y])swap(x,y);
res=Max(res,QueryMax(1,id[x],id[y]));
return res;
}
int QueryPathSum(int x,int y){
int res=0;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
res+=QuerySum(1,id[top[x]],id[x]);
x=f[top[x]];
}
if(d[x]>d[y])swap(x,y);
res+=QuerySum(1,id[x],id[y]);
return res;
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
dfs1(1,0);
dfs2(1,1);
Build(1,1,n);
scanf("%d",&m);
while(m--){
int x,y;
string ques;
cin>>ques;
scanf("%d%d",&x,&y);
if(ques=="CHANGE")Change(1,id[x],y);
else if(ques=="QMAX")printf("%d\n",QueryPathMax(x,y));
else if(ques=="QSUM")printf("%d\n",QueryPathSum(x,y));
}
return 0;
}