#include<bits/stdc++.h>
#define int long long
#define mi(...) <%__VA_ARGS__%>
using namespace std;
namespace Faster {
inline bool _u(char ch) { return ch >= '0' && ch <= '9'; }
inline void write(int num) {static int sta[39], top = 0;if (num < 0)putchar('-'), num *= -1;do sta[++top] = num % 10, num /= 10;while (num);while (top) putchar(sta[top--] | 48);return;}
}using namespace Faster;;
inline int read(){
int x;
#if defined(int)
scanf("%lld",&x);
#else
scanf("%d",&x);
#endif
return x;
}
const int N=3e4+10;
int w[N];
struct edge{
struct node{int to,nxt;}e[N<<2];
int head[N],tot;
inline void add(int u,int v){e[++tot]=mi(v,head[u]),head[u]=tot;}
inline node operator[](int x){return e[x];}
inline int operator()(int x){return head[x];}
}e;
int hev[N],sz[N],fa[N],dep[N];
inline int dfs1(int u){
sz[u]=1,hev[u]=0;dep[u]=fa[u]+1;
for(int i(e(u)),to;i;i=e[i].nxt)
((to=e[i].to)!=fa[u])&&(fa[to]=u,sz[u]+=dfs1(to),hev[u]=(!hev[u]||sz[to]>sz[hev[u]])?to:hev[u]);
return sz[u];
}
int dfn[N],a[N],top[N],tot;
inline void dfs2(int u,int tp){
dfn[u]=++tot,top[u]=tp,a[dfn[u]]=w[u];
hev[u]&&(dfs2(hev[u],tp),1);
for(int i(e(u)),to;i;i=e[i].nxt)
((to=e[i].to)!=fa[u])&&(to!=hev[u])&&(dfs2(to,to),1);
return;
}
struct ffffyn{
#define ls (now<<1)
#define rs (now<<1|1)
#define MID(l,r) (((r-l)>>1)+l)
int b[N<<2],mx[N<<2];
inline void pushup(int now){
b[now]=b[ls]+b[rs];
mx[now]=max(mx[ls],mx[rs]);
return;
}
inline void build(int l,int r,int now){
if(l==r) return b[now]=mx[now]=a[l],void();
int mid(MID(l,r));
build(l,mid,ls),build(mid+1,r,rs);
pushup(now);
}
inline int query_mx(int l,int r,int nl,int nr,int now){
if(l<=nl && nr<=r)return mx[now];
int mid(MID(nl,nr));
return max((l<=mid?query_mx(l,r,nl,mid,ls):-1e18),(mid<r?query_mx(l,r,mid+1,nr,rs):-1e18));
}
inline int query(int l,int r,int nl,int nr,int now){
if(l<=nl && nr<=r)return b[now];
int mid(MID(nl,nr));
return ((l<=mid?query(l,r,nl,mid,ls):0)+(mid<r?query(l,r,mid+1,nr,rs):0));
}
inline void update(int l,int nl,int nr,int now,int x){
if(nl==nr) return b[now]=mx[now]=x,void();
int mid(MID(nl,nr));
l<=mid?update(l,nl,mid,ls,x):update(l,mid+1,nr,rs,x);
pushup(now);
return;
}
}tre;
inline int querymx(int u,int v){
int ans=-1e18;
for(;top[u]!=top[v];)
dep[top[u]]<dep[top[v]]&&(swap(u,v),1),ans=max(ans,tre.query_mx(dfn[top[u]],dfn[u],1,tot,1)),u=fa[top[u]];
return dep[u]>dep[v]&&(swap(u,v),1),ans=max(ans,tre.query_mx(dfn[u],dfn[v],1,tot,1));
}
inline int query(int u,int v){
int ans=0;
for(;top[u]!=top[v];)
dep[top[u]]<dep[top[v]]&&(swap(u,v),1),ans+=tre.query(dfn[top[u]],dfn[u],1,tot,1),u=fa[top[u]];
return dep[u]>dep[v]&&(swap(u,v),1),ans+=tre.query(dfn[u],dfn[v],1,tot,1);
}
int n,q,x,y;
char op[111];
signed main(){
n=read();
for(int i=1,u,v;i<n;++i) e.add(u=read(),v=read()),e.add(v,u);
for(int i=1;i<=n;++i)w[i]=read();
dfs1(1),dfs2(1,1),tre.build(1,tot,1),q=read();
while(q--){
switch(scanf("%s",op),x=read(),y=read(),op[1]){
case 'H': tre.update(dfn[x],1,tot,1,y);break;
case 'M': write(querymx(x,y)),puts("");break;
default: write(query(x,y)),puts("");break;
}
}
return(0-0);
}