#include<bits/stdc++.h>
#define FOR(i,u) for(ll i=G.head[u];i;i=G.nex[i])
#define lc (d<<1)
#define rc (d<<1|1)
#define mid (l+r>>1)
#define ll long long
#define C const
using namespace std;
void read(ll &x) {
x=0;
char y=getchar();
bool flag=0;
while(y<'0' || y>'9') {
if(y=='-')flag=1;
y=getchar();
}
while((y>='0' && y<='9')) {
x=(x<<1)+(x<<3)+(y-'0');
y=getchar();
}
if(flag)x=-x;
}
void write(ll x) {
if(x<0) {
putchar('-');
x=-x;
}
if(x<10)putchar(x+'0');
else {
write(x/10);
putchar(x%10+'0');
}
}
C ll N=3e4+5;
#define For(i,u,G) for(ll i=G.head[u];i;i=G.nex[i])
struct my_edge{
ll head[N],nex[N<<1],to[N<<1],size;
void push(ll u,ll v){
nex[++size]=head[u];
to[size]=v;
head[u]=size;
}
void clear(){
size=0;
memset(head,0,sizeof head);
}
}G;
ll n,m,u,v,w,k,fa[N],h[N],siz[N],top[N],son[N],dfn[N],fn[N],a[N],tot;
void dfs1(ll u,ll f){
fa[u]=f;
siz[u]=1;
h[u]=h[f]+1;
ll v,maxid=0;
For(i,u,G){
v=G.to[i];
if(v==f)continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[maxid])maxid=v;
}
son[u]=maxid;
}
void dfs2(ll u,ll f){
top[u]=f;
dfn[u]=++tot;
fn[tot]=u;
if(son[u]==0)return;
dfs2(son[u],f);
ll v;
For(i,u,G){
v=G.to[i];
if(v==fa[u] || v==son[u])continue;
dfs2(v,v);
}
}
struct my_segment_tree{
ll sum[4*N],maxn[4*N],lb1[4*N],lb2[4*N];
void Up(C ll &d){
maxn[d]=max(maxn[lc],maxn[rc]);
sum[d]=sum[lc]+sum[rc];
}
void Down(C ll &d,C ll &l,C ll &r){
if(lb2[d]!=-1){
maxn[lc]=lb2[d];
maxn[rc]=lb2[d];
sum[lc]=lb2[d]*(mid-l+1);
sum[rc]=lb2[d]*(r-mid);
lb2[lc]=lb2[d];
lb2[rc]=lb2[d];
lb1[lc]=lb1[rc]=0;
lb2[d]=-1;
}
if(lb1[d]){
maxn[lc]+=lb1[d];
maxn[rc]+=lb1[d];
sum[lc]+=lb1[d]*(mid-l+1);
sum[rc]+=lb1[d]*(r-mid);
lb1[lc]+=lb1[d];
lb1[rc]+=lb1[d];
lb1[d]=0;
}
}
void build(C ll &d,C ll &l,C ll &r){
lb2[d]=-1;
if(l==r){
sum[d]=maxn[d]=a[l];
return;
}
build(lc,l,mid);
build(rc,mid+1,r);
Up(d);
}
void change(C ll &d,C ll &l,C ll &r,C ll &x,C ll &y,C ll &k){
if(r<x || y<l)return;
if(x<=l && r<=y){
maxn[d]=k;
sum[d]=(r-l+1)*k;
lb2[d]=k;
lb1[d]=0;
return;
}
Down(d,l,r);
change(lc,l,mid,x,y,k);
change(rc,mid+1,r,x,y,k);
Up(d);
}
void add(C ll &d,C ll &l,C ll &r,C ll &x,C ll &y,C ll &k){
if(r<x || y<l)return;
if(x<=l && r<=y){
maxn[d]+=k;
sum[d]+=(r-l+1)*k;
lb1[d]+=k;
return;
}
Down(d,l,r);
add(lc,l,mid,x,y,k);
add(rc,mid+1,r,x,y,k);
Up(d);
}
ll query_max(C ll &d,C ll &l,C ll &r,C ll &x,C ll &y){
if(r<x || y<l)return -2e9;
if(x<=l && r<=y)return maxn[d];
Down(d,l,r);
return max(query_max(lc,l,mid,x,y),query_max(rc,mid+1,r,x,y));
}
ll query_sum(C ll &d,C ll &l,C ll &r,C ll &x,C ll &y){
if(r<x || y<l)return 0;
if(x<=l && r<=y)return sum[d];
Down(d,l,r);
return query_sum(lc,l,mid,x,y)+query_sum(rc,mid+1,r,x,y);
}
}tree;
string op;
ll maxn;
ll LCA(ll u,ll v,bool op){
if(op){
maxn=-2e9;
while(top[u]!=top[v]){
if(h[top[v]]<h[top[u]])swap(u,v);
maxn=max(maxn,tree.query_max(1,1,n,dfn[top[v]],dfn[v]));
v=fa[top[v]];
}
if(h[v]<h[u])maxn=max(maxn,tree.query_max(1,1,n,dfn[v],dfn[u]));
else maxn=max(maxn,tree.query_max(1,1,n,dfn[u],dfn[v]));
}else{
maxn=0;
while(top[u]!=top[v]){
if(h[top[v]]<h[top[u]])swap(u,v);
maxn+=tree.query_sum(1,1,n,dfn[top[v]],dfn[v]);
v=fa[top[v]];
}
if(h[v]<h[u])maxn+=tree.query_sum(1,1,n,dfn[v],dfn[u]);
else maxn+=tree.query_sum(1,1,n,dfn[u],dfn[v]);
}
return maxn;
}
signed main() {
read(n);
for(int i=1;i<n;i++){
read(u);read(v);
G.push(u,v);
G.push(v,u);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=n;i++)read(a[i]);
tree.build(1,1,n);
read(m);
while(m--){
cin>>op;
if(op=="CHANGE"){
read(u);read(k);
u=dfn[u];
tree.change(1,1,n,u,u,k);
}else{
read(u);read(v);
write(LCA(u,v,(op=="QMAX")));
puts("");
}
}
return 0;
}