#include <bits/stdc++.h>
#define int long long
const int SZ=3e5+10;
char op[11];
int n,m,head[SZ],hhh,siz[SZ],son[SZ],dep[SZ],faz[SZ],dfn[SZ],top[SZ],rk[SZ],cnt,a[SZ];
struct edge
{
int nxt,to;
} g[SZ*2];
struct node
{
int l,r,maxx,sum;
} t[SZ*4];
void pushup(int p)
{
t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
t[p].maxx=std::max(t[p<<1].maxx,t[p<<1|1].maxx);
}
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
if(l==r)
{
t[p].sum=a[rk[l]];
t[p].maxx=a[rk[l]];
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void modify(int p,int x,int v)
{
if(t[p].l==t[p].r)
{
t[p].maxx=v;
t[p].sum=v;
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid)
{
modify(p<<1,x,v);
}
else
{
modify(p<<1|1,x,v);
}
pushup(p);
}
int query1(int p,int l,int r)
{
if(t[p].l==t[p].r)
{
return t[p].sum;
}
int ret=0;
if(t[p<<1].r>=l)
{
ret+=query1(p<<1,l,r);
}
if(t[p<<1|1].l<=r)
{
ret+=query1(p<<1|1,l,r);
}
pushup(p);
return ret;
}
int query2(int p,int l,int r)
{
if(t[p].l==t[p].r)
{
return t[p].maxx;
}
int ret=-1e9;
if(t[p<<1].r>=l)
{
ret=std::max(ret,query2(p<<1,l,r));
}
if(t[p<<1|1].l<=r)
{
ret=std::max(ret,query2(p<<1|1,l,r));
}
pushup(p);
return ret;
}
void add_edge(int u,int v)
{
g[++hhh].nxt=head[u];
head[u]=hhh;
g[hhh].to=v;
}
void dfs1(int u,int fa)
{
siz[u]=1;
son[u]=0;
for(int i=head[u];i;i=g[i].nxt)
{
int v=g[i].to;
if(v!=fa)
{
dep[v]=dep[u]+1;
faz[v]=u;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
{
son[u]=v;
}
}
}
}
void dfs2(int u,int x)
{
++cnt;
dfn[u]=cnt;
rk[cnt]=u;
top[u]=x;
if(son[u])
{
dfs2(son[u],x);
}
for(int i=head[u];i;i=g[i].nxt)
{
int v=g[i].to;
if(!(v==faz[u]||v==son[u]))
{
dfs2(v,v);
}
}
}
int query_tree_1(int u,int v)
{
int ret=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
{
std::swap(u,v);
}
ret+=query1(1,dfn[top[u]],dfn[u]);
u=faz[top[u]];
}
if(dep[u]<dep[v])
{
std::swap(u,v);
}
ret+=query1(1,dfn[v],dfn[u]);
return ret;
}
int query_tree_2(int u,int v)
{
int ret=-1e9;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
{
std::swap(u,v);
}
ret=std::max(ret,query2(1,dfn[top[u]],dfn[u]));
u=faz[top[u]];
}
if(dep[u]<dep[v])
{
std::swap(u,v);
}
ret=std::max(ret,query2(1,dfn[v],dfn[u]));
return ret;
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%lld%lld",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
dep[1]=1;
faz[1]=1;
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
scanf("%lld",&m);
while(m--)
{
int u,v;
scanf("%s%lld%lld",&op,&u,&v);
if(op[1]=='H')
{
modify(1,dfn[u],v);
}
if(op[1]=='M')
{
printf("%lld\n",query_tree_2(u,v));
}
if(op[1]=='S')
{
printf("%lld\n",query_tree_1(u,v));
}
}
return 0;
}