#include<bits/stdc++.h>
using namespace std;
namespace IO{
char ibuf[1<<14],*iS,*iT;
#if ONLINE_JUDGE
#define gh() (iS==iT?iT=(iS=ibuf)+fread(ibuf,1,1<<14,stdin),(iS==iT?EOF:*iS++):*iS++)
#else
#define gh() getchar()
#endif
inline int read(){
char ch=gh();
int x=0,f=0;
while(!isdigit(ch)) f|=(ch=='-'),ch=gh();
while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=gh();
return f?-x:x;
}
inline void Write(int x){
if(x>=10) Write(x/10);
putchar(x%10+48);
}
inline void write(int x,char ch=0){
if(x<0) putchar('-'),x=-x;
Write(x);
if(ch!=0) putchar(ch);
}
}
using IO::read;
using IO::write;
vector<int>e[100005];
int a[30005],fa[30005],dep[30005],siz[30005],wc[30005],top[30005],dfn[30005],rdfn[30005],cnt,n,q,root;
int ans[120005],mx[120005],mod;
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
void push_up(int x){ans[x]=ans[ls(x)]+ans[rs(x)],mx[x]=max(mx[ls(x)],mx[rs(x)]);}
void get_tree(int p,int l,int r){
if(l==r){
ans[p]=mx[p]=a[rdfn[l]];
return;
}
int mid=(l+r)>>1;
get_tree(ls(p),l,mid);
get_tree(rs(p),mid+1,r);
push_up(p);
}
void change(int p,int re,int l,int r,int val){
if(l==r){
ans[p]=mx[p]=val;
return;
}else{
int mid=(l+r)>>1;
if(mid>=re) change(ls(p),re,l,mid,val);
else change(rs(p),re,mid+1,r,val);
push_up(p);
}
}
int query_sum(int p,int re_l,int re_r,int l,int r){
if(l>=re_l&&r<=re_r){
return ans[p];
}else if(!(l>re_r||r<re_l)){
int cnt=0;
int mid=(l+r)>>1;
return query_sum(ls(p),re_l,re_r,l,mid)+query_sum(rs(p),re_l,re_r,mid+1,r);
}else return 0;
}
int query_max(int p,int re_l,int re_r,int l,int r){
if(l>=re_l&&r<=re_r){
return mx[p];
}else if(!(l>re_r||r<re_l)){
int cnt=-0x3f3f3f3f;
int mid=(l+r)>>1;
return max(query_max(ls(p),re_l,re_r,l,mid),query_max(rs(p),re_l,re_r,mid+1,r));
}else return 0;
}
void dfs1(int now,int f){
fa[now]=f;
siz[now]=1;
dep[now]=dep[f]+1;
for(int i=0;i<e[now].size();i++){
int son=e[now][i];
if(son!=f){
dfs1(son,now);
if(siz[son]>siz[wc[now]]) wc[now]=son;
siz[now]+=siz[son];
}
}
}
void dfs2(int now,int Top){
dfn[now]=++cnt;
rdfn[cnt]=now;
top[now]=Top;
if(wc[now]!=0){
dfs2(wc[now],Top);
for(int i=0;i<e[now].size();i++){
int son=e[now][i];
if(son!=fa[now]&&son!=wc[now]){
dfs2(son,son);
}
}
}
}
int qry_sum(int x,int y){
int cnt=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
cnt+=query_sum(1,dfn[top[x]],dfn[x],1,n);
x=fa[top[x]];
}
return cnt+query_sum(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,n);
}
int qry_max(int x,int y){
int cnt=-0x3f3f3f3f;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
cnt=max(cnt,query_max(1,dfn[top[x]],dfn[x],1,n));
x=fa[top[x]];
}
return max(cnt,query_max(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,n));
}
int main(){
n=read(),root=1;
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;i++) a[i]=read();
dfs1(root,0);
dfs2(root,0);
get_tree(1,1,n);
q=read();
int x,y;
for(int i=1;i<=q;i++){
char opt[10];
x=read(),y=read();
scanf("%s",opt);
if(opt[1]=='H') change(1,dfn[x],1,n,y);
else if(opt[1]=='M') write(qry_max(x,y),'\n');
else write(qry_sum(x,y),'\n');
}
}