#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct my{
int u,v,next;
};
const int maxn=100000+5;
int cnt;
int nil=1000000000;
my tu[maxn];
int n;
int head[maxn];
int w[maxn*4];
int size[maxn],d[maxn],fa[maxn],woson[maxn],tpos[maxn],pre[maxn],top[maxn];
char f[10];
int sumv[maxn*4],maxv[maxn*4];
int tot;
void myinsert(int u,int v){
tu[++tot].u=u;
tu[tot].v=v;
tu[tot].next=head[u];
head[u]=tot;
}
int read()
{
int p,data=0;
char ch=0;
while ((ch!='-') && ch<'0' || ch>'9') ch=getchar();
if (ch=='-')
{
p=-1;
ch=getchar();
} else p=1;
while (ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
return data*p;
}
void dfs1(int u,int f){
size[u]=1;
for (int i=head[u];i;i=tu[i].next){
int v=tu[i].v;
if(v==f) continue;
d[v]=d[u]+1;fa[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[woson[u]]) woson[u]=v;
}
}
void dfs2(int u,int frist){
tpos[u]=++cnt;
pre[cnt]=u;
top[u]=frist;
if(woson[u]) dfs2(woson[u],frist);
for (int i=head[u];i;i=tu[i].next){
int v=tu[i].v;
if(v==fa[u]||v==woson[u]) continue;
dfs2(v,v);
}
}
void pushup(int x){
sumv[x]=sumv[x<<1]+sumv[x<<1|1];
maxv[x]=max(maxv[x<<1],maxv[x<<1|1]);
}
void build(int st,int l,int r){
if(l==r){
sumv[st]=maxv[st]=w[pre[l]];
return ;
}
int mid=(l+r)>>1;
build(st<<1,l,mid);
build(st<<1|1,mid+1,r);
pushup(st);
}
void update(int st,int l,int r,int pos,int c){
if(l==r){
sumv[st]=maxv[st]=c;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) update(st<<1,l,mid,pos,c);
else update(st<<1|1,mid+1,r,pos,c);
pushup(st);
}
int querysum(int st,int l,int r,int L,int R){
if(L<=l&&r<=R){
return sumv[st];
}
int mid=(l+r)>>1;
int ans=0;
if(L<=mid) ans+=querysum(st<<1,l,mid,L,R);
if(R>mid) ans+=querysum(st<<1|1,mid+1,r,L,R);
return ans;
}
int qsum(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
ans+=querysum(1,1,n,tpos[top[u]],tpos[u]);
u=fa[top[u]];
}
if(d[u]<d[v]) swap(u,v);
ans+=querysum(1,1,n,tpos[v],tpos[u]);
return ans;
}
int querymax(int st,int l,int r,int L,int R){
if(L<=l&&r<=R){
return maxv[st];
}
int ans=-nil;
int mid=(l+r)>>1;
if(L<=mid) ans=max(ans,querymax(st<<1,l,mid,L,R));
if(R>mid) ans=max(ans,querymax(st<<1|1,mid+1,r,L,R));
return ans;
}
int qmax(int u,int v){
int ans=-nil;
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]) swap(u,v);
ans=max(ans,querymax(1,1,n,tpos[top[u]],tpos[u]));
u=fa[top[u]];
}
if(d[u]<d[v]) swap(u,v);
ans=max(ans,querymax(1,1,n,tpos[v],tpos[u]));
return ans;
}
int main(){
//freopen("cout.out","w",stdout);
n=read();
int u,v;
for (int i=1;i<n;i++){
u=read();
v=read();
myinsert(u,v);
myinsert(v,u);
}
for (int i=1;i<=n;i++) w[i]=read();
int q;
q=read();
d[1]=1;fa[1]=1;
dfs1(1,-1);
dfs2(1,1);
build(1,1,n);
while(q--){
int x,y;
scanf("%s",f);
x=read();
y=read();
if(f[1]=='H') update(1,1,n,tpos[x],y);
if(f[1]=='M') printf("%d
",qmax(x,y));
if(f[1]=='S') printf("%d
",qsum(x,y));
}
return 0;
}