#include<bits/stdc++.h>
#define root tree[k]
#define ls tree[k<<1]
#define rs tree[k<<1|1]
#define mid root.l+(root.r-root.l)/2
#define inf 0x3f3f3f3f
using namespace std;
struct edge
{
int nx,to;
}e[200000];
struct pot
{
int l,r,max,sum,tag;
}tree[200000];
int n,m,r,p,cnt,x,y,q,tot,
fa[200000],dep[200000],siz[200000],son[200000],dfn[200000],rk[200000],head[200000],top[200000],dis[200000];
string st;
void ad(int x,int y)
{
tot++;
e[tot].to=y;
e[tot].nx=head[x];
head[x]=tot;
}
void dfs(int k,int ft)
{
fa[k]=ft;dep[k]=dep[ft]+1;siz[k]=1;son[k]=0;
for (int i=head[k];i;i=e[i].nx)
if (e[i].to!=ft)
{
dfs(e[i].to,k);
siz[k]+=siz[e[i].to];
if (siz[e[i].to]>siz[son[k]]) son[k]=e[i].to;
}
}
void dfs1(int k,int rt)
{
dfn[k]=++cnt;
rk[cnt]=k;
top[k]=rt;
if (son[k]) dfs1(son[k],rt);
for (int i=head[k];i;i=e[i].nx)
if (e[i].to!=fa[k])
{
if (e[i].to==rt||e[i].to==son[k]) continue;
dfs1(e[i].to,e[i].to);
}
}
void push_down(int k)
{
if (root.tag==inf) return;
ls.max=rs.max=root.tag;
ls.sum=root.tag*(ls.r-ls.l+1);
rs.sum=root.tag*(rs.r-rs.l+1);
ls.tag=rs.tag=root.tag;
root.tag=inf;
}
void push_up(int k)
{
root.max=max(ls.max,rs.max);
root.sum=ls.sum+rs.sum;
}
void build(int k,int l,int r)
{
root.l=l,root.r=r,root.tag=inf;
if (l==r) root.max=root.sum=dis[rk[l]];
else
{
build(k<<1,l,l+(r-l)/2);
build(k<<1|1,l+(r-l)/2+1,r);
push_up(k);
}
}
void modify(int k,int l,int r,int val)
{
if (root.l==l&&root.r==r)
{
root.max=val;
root.sum=val*(r-l+1);
root.tag=val;
return;
}
push_down(k);
if (l<=mid) modify(k<<1,l,min(r,mid),val);
if (r>mid) modify(k<<1|1,max(l,mid+1),r,val);
push_up(k);
}
int querymx(int k,int l,int r)
{
if (l>r) return -inf;
if (root.l==l&&root.r==r)
{
return root.max;
}
int ans=-inf;
push_down(k);
if (l<=mid) ans=max(ans,querymx(k<<1,l,min(r,mid)));
if (r>mid) ans=max(ans,querymx(k<<1|1,max(l,mid+1),r));
push_up(k);
return ans;
}
int querysum(int k,int l,int r)
{
if (root.l==l&&root.r==r)
{
return root.sum;
}
int ans=0;
push_down(k);
if (l<=mid) ans+=querysum(k<<1,l,min(r,mid));
if (r>mid) ans+=querysum(k<<1|1,max(l,mid+1),r);
push_up(k);
return ans;
}
void Modify(int x,int y,int val)
{
while (top[x]!=top[y])
{
if (!dep[top[x]]<dep[top[y]]) swap(x,y);
modify(1,dfn[x],dfn[top[x]],val);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
modify(1,dfn[x],dfn[y],val);
}
int Querymax(int x,int y)
{
int sum=-inf;
while (top[x]!=top[y])
{
if (!dep[top[x]]<dep[top[y]]) swap(x,y);
sum=max(sum,querymx(1,dfn[x],dfn[top[x]]));
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
sum=max(sum,querymx(1,dfn[x],dfn[y]));
return sum;
}
int Querysum(int x,int y)
{
int sum=0;
while (top[x]!=top[y])
{
if (!dep[top[x]]<dep[top[y]]) swap(x,y);
sum+=querysum(1,dfn[x],dfn[top[x]]);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
sum+=querysum(1,dfn[x],dfn[y]);
return sum;
}
int main()
{
cin>>n;
for (int i=1;i<n;i++)
{
cin>>x>>y;
ad(x,y);
ad(y,x);
}
dfs(1,0);
dfs1(1,1);
for (int i=1;i<=n;i++) cin>>dis[i];
build(1,1,n);
cin>>q;
for (int i=1;i<=q;i++)
{
cin>>st;
cin>>x>>y;
if (st=="CHANGE") Modify(x,x,y);
else if (st=="QMAX") cout<<Querymax(x,y);
else cout<<Querysum(x,y);
}
}