#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=3e4+4;
int fa[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn],dfn[maxn],rnk[maxn];
int cnt=0,a[maxn],n,q;
vector<int> g[maxn];
void dfs1(int cur){
son[cur]=-1,siz[cur]=1;
for(auto v:g[cur]){
if(dep[v]) continue;
fa[v]=cur,dep[v]=dep[cur]+1;
dfs1(v);
siz[cur]+=siz[v];
if(son[cur]==-1||siz[son[cur]]<siz[v]) son[cur]=v;
}
}
void dfs2(int cur,int t){
top[cur]=t;
dfn[cur]=++cnt,rnk[cnt]=cur;
if(son[cur]==-1) return;
dfs2(son[cur],t);
for(auto v:g[cur])
if(v!=fa[cur]&&v!=son[cur]) dfs2(v,v);
}
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
struct tree{
int val1,val2,tag;
}t[maxn*4];
void pushup(int o){
t[o].val1=t[lc(o)].val1+t[rc(o)].val1;
t[o].val2=max(t[lc(o)].val2,t[rc(o)].val2);
}
void build(int o,int l,int r){
if(l==r){t[o].val1=t[o].val2=a[rnk[l]];return;}
int mid=(l+r)>>1;
build(lc(o),l,mid),build(rc(o),mid+1,r);
pushup(o);
}
void pushdown(int o,int l,int r){
int mid=(l+r)>>1;
t[lc(o)].val1+=t[o].tag*(mid-l+1);
t[rc(o)].val1+=t[o].tag*(r-mid);
t[lc(o)].tag=t[rc(o)].tag=t[o].tag,t[o].tag=0;
}
void update(int o,int l,int r,int L,int R,int k1,int k2){
if(l>=L&&r<=R){
t[o].val1+=k1*(r-l+1),t[o].tag+=k1;
t[o].val2=max(t[o].val2,k2);return;
}
pushdown(o,l,r);
int mid=(l+r)>>1;
if(mid>=L) update(lc(o),l,mid,L,R,k1,k2);
if(mid<R) update(rc(o),mid+1,r,L,R,k1,k2);
pushup(o);
}
int query1(int o,int l,int r,int L,int R){
if(l>=L&&r<=R) return t[o].val1;
pushdown(o,l,r);
int mid=(l+r)>>1,s=0;
if(mid>=L) s+=query1(lc(o),l,mid,L,R);
if(mid<R) s+=query1(rc(o),mid+1,r,L,R);
return s;
}
int query2(int o,int l,int r,int L,int R){
if(l>=L&&r<=R) return t[o].val2;
int mid=(l+r)>>1,mx=0;
if(mid>=L) mx=max(mx,query2(lc(o),l,mid,L,R));
if(mid<R) mx=max(mx,query2(rc(o),mid+1,r,L,R));
return mx;
}
int Query1(int u,int v){
int s=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
s+=query2(1,1,n,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
s+=query1(1,1,n,dfn[u],dfn[v]);
return s;
}
int Query2(int u,int v){
int mx=0,to=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
mx=max(mx,query2(1,1,n,dfn[top[u]],dfn[u]));
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
mx=max(mx,query2(1,1,n,dfn[u],dfn[v]));
return mx;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<n;i++){
int u,v;scanf("%lld%lld",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=1;i<=n;i++) scanf("%lld",a+i);
dep[1]=1;
dfs1(1);
dfs2(1,1);
build(1,1,n);
scanf("%lld",&q);
while(q--){
char opt[5];
int u,v;
scanf("%s%lld%lld",opt,&u,&v);
if(opt[1]=='H') update(1,1,n,dfn[u],dfn[u],v-a[u],v);
if(opt[1]=='M') printf("%lld\n",Query2(u,v));
if(opt[1]=='S') printf("%lld\n",Query1(u,v));
}
return 0;
}