Rt
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=INT_MAX;
const ll N=3e4+1;
struct Node{
ll rev,seg;
ll size,son,father,mx;
ll dep,top;
ll sum;
ll first;
ll next;
ll to;
};
Node tree[N];
ll num[N];
ll Sum=0;
ll Mx=-inf;
#define lson value<<1
#define rson value<<1|1
inline void Pushup(ll value){
tree[value].sum=tree[lson].sum+tree[rson].sum;
tree[value].mx=max(tree[lson].mx,tree[rson].mx);
return;
}
inline void Build(ll l,ll r,ll value){
if (l==r){
tree[value].mx=tree[value].sum=num[l+r>>1];
return;
}
ll mid=l+r>>1;
Build(l,mid,lson);
Build(mid+1,r,rson);
Pushup(value);
return;
}
inline void Query(ll value,ll l,ll r,ll L,ll R){
if (L>r||R<l)
return;
if (L<=l&&r<=R){
Sum+=tree[value].sum;
Mx=max(Mx,tree[value].mx);
return;
}
ll mid=l+r>>1;
ll res=0;
if (L<=mid)
Query(lson,l,mid,L,R);
if (R>mid)
Query(rson,mid+1,r,L,R);
return;
}
inline void Modify(ll value,ll l,ll r,ll val,ll pos){
if (pos>r||pos<l)
return;
if (l==r&&l==pos){
tree[value].sum=val;
tree[value].mx=val;
return;
}
ll mid=l+r>>1;
if (pos<=mid)
Modify(lson,l,mid,val,pos);
if (pos>=mid+1)
Modify(rson,mid+1,r,val,pos);
Pushup(value);
return;
}
inline void dfs1(ll u,ll f){
ll e,v;
tree[u].size=1;
tree[u].father=f;
tree[u].dep=tree[f].dep+1;
for (e=tree[u].first;v=tree[e].to;e=tree[e].next)
if (v!=f){
dfs1(v,u);
tree[u].size+=tree[v].size;
if (tree[v].size>tree[tree[u].son].size)
tree[u].son+=v;
}
}
inline void dfs2(ll u,ll f){
ll e,v;
if (tree[u].son){
tree[tree[u].son].seg=++tree[0].seg;
tree[tree[u].son].top=tree[u].top;
tree[tree[0].seg].rev=tree[u].son;
dfs2(tree[u].son,u);
}
for (e=tree[u].first;v=tree[e].to;e=tree[e].next)
if (!tree[v].top){
tree[v].seg=++tree[0].seg;
tree[tree[0].seg].rev=v;
tree[v].top=v;
dfs2(v,u);
}
return;
}
ll tot=0;
inline void Add(ll x,ll y){
tree[++tot].next=tree[x].first;
tree[x].first=tot;
tree[tot].to=y;
return;
}
inline void Insert(ll a,ll b){
Add(a,b);
Add(b,a);
return;
}
inline void Ask(ll x,ll y){
ll fx=tree[x].top;
ll fy=tree[y].top;
while (fx!=fy){
if (tree[fx].dep<tree[fy].dep)
swap(x,y),swap(fx,fy);
Query(1,1,tree[0].seg,tree[fx].seg,tree[fy].seg);
x=tree[fx].father;fx=tree[x].top;
}
if(tree[x].dep>tree[y].dep)
swap(x,y);
Query(1,1,tree[0].seg,tree[x].seg,tree[y].seg);
}
inline ll read(){
char ch=getchar();
ll f=1,x=0;
while(!isdigit(ch)&&ch^'-')
ch=getchar();
if(ch=='-')
f=-1,ch=getchar();
while(isdigit(ch))
x=x*10+ch-'0',ch=getchar();
return x*f;
}
char s[10];
int main(){
ll n;
scanf("%lld",&n);
for (ll i=1;i<n;i++)
Add(read(),read());
for (ll i=1;i<=n;i++)
num[i]=read();
dfs1(1,0);
tree[0].seg=tree[1].seg=tree[1].top=tree[1].rev=1;
dfs2(1,0);
Build(1,tree[0].seg,1);
ll t=read();
while (t--){
scanf("%s",s+1);
ll u=read(),v=read();
if (s[1]=='C')
Modify(1,1,tree[0].seg,v,tree[u].seg);
else{
Sum=0;
Mx=-inf;
if (s[2]=='M')
printf("%lld\n",Mx);
else
printf("%lld\n",Sum);
}
}
}