#include<bits/stdc++.h>
using namespace std;
int pos[30010],dep[30010],tid[30010],son[30010],top[30010],siz[30010],fa[30010];
int k=0,head[30010],tim=0;
long long be[30010];
struct point{
int to,nxt;
}ed[120040];
struct tree{
int L,R,imax;
long long sum;
}tr[120040];
void add(int x,int y){
ed[++k].nxt=head[x];
ed[k].to=y;
head[x]=k;
}
void dfs1(int u,int fat,int de){
fa[u]=fat;
dep[u]=de;
siz[u]=1;
for(int i=head[u];i;i=ed[i].nxt){
int v=ed[i].to;
if(v!=fat){
dfs1(v,u,de+1);
siz[u]+=siz[v];
if(son[u]==0||siz[v]>siz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int tp){
top[u]=tp;
tid[u]=++tim;
pos[tid[u]]=u;
if(son[u]==0) return;
dfs2(son[u],tp);
for(int i=head[u];i;i=ed[i].nxt){
int v=ed[i].to;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
void build(int x,int l,int r){
tr[x].L=l;
tr[x].R=r;
if(l==r){
tr[x].imax=(int)be[pos[l]];
tr[x].sum=be[pos[l]];
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;
tr[x].imax=max(tr[x<<1].imax,tr[x<<1|1].imax);
}
void update(int x,int l,int r,int w){
if(tr[x].L>r||tr[x].R<l) return;
if(tr[x].L==tr[x].R){
tr[x].sum=w;
tr[x].imax=w;
return;
}
update(x<<1,l,r,w);
update(x<<1|1,l,r,w);
tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;
tr[x].imax=max(tr[x<<1].imax,tr[x<<1|1].imax);
}
long long finds(int x,int l,int r){
if(tr[x].L>r||tr[x].R<l) return 0ll;
if(tr[x].L>=l&&tr[x].R<=r) return tr[x].sum;
return finds(x<<1,l,r)+finds(x<<1|1,l,r);
}
int findm(int x,int l,int r){
int ans=-1e9;
if(tr[x].L>r||tr[x].R<l) return -1e9;
if(tr[x].L>=l&&tr[x].R<=r) return tr[x].imax;
return max(findm(x<<1,l,r),findm(x<<1|1,l,r));
}
long long find(int x,int y){
long long sum=0;
int fx,fy;
fx=top[x];
fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy]){
swap(fx,fy);
swap(x,y);
}
sum=sum+finds(1,tid[fx],tid[x]);
x=fa[x];
fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
return sum+finds(1,tid[x],tid[y]);
}
int getm(int x,int y){
int fx,fy;
fx=top[x];
fy=top[y];
int ans=-1e9;
while(fx!=fy){
if(dep[fx]<dep[fy]){
swap(fx,fy);
swap(x,y);
}
ans=max(ans,findm(1,tid[fx],tid[x]));
x=fa[x];
fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
return max(ans,findm(1,tid[x],tid[y]));
}
int main(){
int n,m,r;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++){
scanf("%lld",&be[i]);
}
scanf("%d",&m);
dfs1(1,0,1);
dfs2(1,1);
build(1,1,tim);
int x,y;
string sh;
for(int i=1;i<=m;i++){
cin>>sh;
if(sh=="QSUM"){
scanf("%d%d",&x,&y);
printf("%lld\n",find(x,y));
}
else if(sh=="QMAX"){
scanf("%d%d",&x,&y);
printf("%d\n",getm(x,y));
}
else if(sh=="CHANGE"){
scanf("%d%d",&x,&y);
update(1,tid[x],tid[x],y);
}
}
return 0;
}
悬2关