RT
#include<bits/stdc++.h>
using namespace std;
int n,m,root=1,u,v,a[300005];
int dep[300005],son[300005],size[300005],f[300005];
int p[300005],sum[300005],top[300005],cnt;
vector<int>ve[300005];
struct Segment_Tree {
int s,Max;
} tree[300005<<2|1];
void dfs1(int now,int fa,int deep) {
dep[now]=deep;
f[now]=fa;
size[now]=1;
int maxsize=-1;
for(int i=0; i<ve[now].size(); i++) {
int y=ve[now][i];
if(y==fa)continue;
dfs1(y,now,deep+1);
size[now]+=size[y];
if(size[y]>maxsize)maxsize=size[y],son[now]=y;
}
return;
}
void dfs2(int now,int _top) {
p[now]=++cnt;
top[now]=_top;
sum[cnt]=a[now];
if(!son[now])return;
dfs2(son[now],_top);
for(int i=0; i<ve[now].size(); i++) {
int y=ve[now][i];
if(y==f[now]||y==son[now])continue;
dfs2(y,y);
}
return;
}
inline void push_up(int p) {
int ls=p<<1,rs=p<<1|1;
tree[p].s=tree[ls].s+tree[rs].s;
tree[p].Max=max(tree[ls].Max,tree[rs].Max);
return;
}
void change(int now,int l,int r,int p,int k) {
if(l==r&&r==now) {
tree[p].s=tree[p].Max=k;
return;
}
int mid=(l+r)>>1;
if(mid>=now)change(now,l,mid,p<<1,k);
else change(now,mid+1,r,p<<1|1,k);
push_up(p);
return;
}
int query1(int l1,int r1,int l,int r,int p) {
if(l>=l1&&r<=r1)return tree[p].s;
int mid=(l+r)>>1,ans=0;
if(mid>=l1)ans+=query1(l1,r1,l,mid,p<<1);
if(mid<r1)ans+=query1(l1,r1,mid+1,r,p<<1|1);
return ans;
}
int query2(int l1,int r1,int l,int r,int p) {
if(l>=l1&&r<=r1)return tree[p].Max;
int mid=(l+r)>>1,ans=-1e9;
if(mid>=l1)ans=max(ans,query2(l1,r1,l,mid,p<<1));
if(mid<r1)ans=max(ans,query2(l1,r1,mid+1,r,p<<1|1));
return ans;
}
int _query1(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query1(p[top[x]],p[x],1,n,1);
x=f[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans+=query1(p[x],p[y],1,n,1);
return ans;
}
int _query2(int x,int y){
int ans=-1e9;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query2(p[top[x]],p[x],1,n,1));
x=f[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans=max(ans,query2(p[x],p[y],1,n,1));
return ans;
}
void build(int l,int r,int p) {
if(l==r) {
tree[p].s=tree[p].Max=sum[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
push_up(p);
}
int main() {
scanf("%d",&n);
for(int i=1; i<n; i++) {
scanf("%d%d",&u,&v);
ve[u].push_back(v);
ve[v].push_back(u);
}
for(int i=1; i<=n; i++)scanf("%d",&a[i]);
dfs1(root,0,1);
dfs2(root,root);
build(1,n,1);
scanf("%d",&m);
string opt;
while(m--) {
cin>>opt>>u>>v;
if(opt=="CHANGE")change(u,1,n,1,v);
if(opt=="QSUM")printf("%d\n",_query1(u,v));
if(opt=="QMAX")printf("%d\n",_query2(u,v));
}
}