#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 1e5 + 5;
const ll inf=1e17;
ll fa[MAXN];
ll dep[MAXN];
ll siz[MAXN];
ll son[MAXN];
ll top[MAXN];
ll dfn[MAXN];
ll rnk[MAXN];
char op[10];
vector<ll>edge[MAXN];
ll cnt=0;
struct node{
ll l,r,sum,maxx;
};
ll n, m, A[MAXN];
node tree[MAXN<<2];
void push_up(int p){
if(tree[p].l==tree[p].r) return;
tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
tree[p].maxx=max(tree[p<<1].maxx,tree[p<<1|1].maxx);
}
void build(int p = 1, int cl = 1, int cr = n)
{
tree[p].l=cl;
tree[p].r=cr;
if (cl == cr) {
tree[p].sum=A[cl];
tree[p].maxx=A[cl];
tree[p].l=tree[p].r=cr;
return;
}
int mid = (cl + cr) >> 1;
build(p << 1, cl, mid);
build(p << 1 | 1, mid + 1, cr);
push_up(p);
}
ll query(int l, int r, int p=1)
{
ll cl=tree[p].l,cr=tree[p].r;
if(cl>r||cr<l) return 0;
if (cl >= l && cr <= r) return tree[p].sum;
ll mid = (cl + cr) >> 1, ans = 0;
if (mid >= l) ans += query(l, r, p << 1);
if (mid < r) ans += query(l, r, p << 1 | 1);
return ans;
}
ll qmax(int l,int r,int p=1){
ll cl=tree[p].l,cr=tree[p].r;
if(cl>r||cr<l) return 0;
if (cl >= l && cr <= r) return tree[p].maxx;
ll mid=(cl+cr)>>1;
ll maxx=-inf;
if(mid>=l) maxx=max(maxx,qmax(l,r,p<<1));
if(mid<r) maxx=max(maxx,query(l,r,p<<1|1));
return maxx;
}
void change(ll loc,ll p,ll x){
ll cl=tree[p].l,cr=tree[p].r;
if(tree[p].l==loc and tree[p].r==loc){
tree[p].sum=tree[p].maxx=x;
return;
}
ll mid=(cl+cr)>>1;
if(mid>=loc) change(loc,p<<1,x);
else change(loc,p<<1|1,x);
push_up(p);
}
void dfs1(ll now,ll Fa,ll depth){
fa[now]=Fa;
dep[now]=depth;
siz[now]=1;
if(edge[now].size()==1&&edge[now][0]==Fa){return;}
for(auto i:edge[now]){
if(i==Fa) continue;
dfs1(i,now,depth+1);
siz[now]+=siz[i];
if(siz[son[now]]<siz[i]) son[now]=i;
}
}
void dfs2(ll now,ll fa,ll step){
if(step==0) top[now]=now;
else top[now]=top[fa];
dfn[++cnt]=now;
rnk[now]=cnt;
if(son[now]==0) return;
dfs2(son[now],now,step+1);
for(auto i:edge[now]){
if(i==fa||i==son[now]||dep[i]<dep[now]) continue;
dfs2(i,-1,0);
}
}
ll LCA(ll x,ll y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
else y=fa[top[y]];
}
return dep[x]>dep[y]?y:x;
}
int main(){
scanf("%lld",&n);
for(int i=1;i<n;i++){
ll a,b;
scanf("%lld%lld",&a,&b);
edge[a].push_back(b);
edge[b].push_back(a);
}
dfs1(1,1,0);
dfs2(1,1,0);
for(int i=1;i<=n;i++){
ll tmp;
scanf("%lld",&tmp);
A[dfn[i]]=tmp;
}
build();
scanf("%lld",&m);
while(m--){
scanf("%s",op);
if(!strcmp(op,"CHANGE")){
ll u,t;
scanf("%lld%lld",&u,&t);
change(rnk[u],1,t);
}
else if(!strcmp(op,"QMAX")){
ll u,v;
scanf("%lld%lld",&u,&v);
ll w=LCA(u,v);
ll maxx=-inf;
while(top[u]!=top[w]){
maxx=max(maxx,qmax(rnk[top[u]],rnk[u]));
u=fa[top[u]];
}
maxx=max(maxx,qmax(rnk[w],rnk[u]));
while(top[v]!=top[w]){
maxx=max(maxx,qmax(rnk[top[v]],rnk[v]));
v=fa[top[v]];
}
maxx=max(maxx,qmax(rnk[w],rnk[v]));
printf("%lld\n",maxx);
}
else{
ll u,v;
scanf("%lld%lld",&u,&v);
ll w=LCA(u,v);
ll sum=0;
while(top[u]!=top[w]){
sum+=query(rnk[top[u]],rnk[u]);
u=fa[top[u]];
}
sum+=query(rnk[w],rnk[u]);
while(top[v]!=top[w]){
sum+=query(rnk[top[v]],rnk[v]);
v=fa[top[v]];
}
sum+=query(rnk[w],rnk[v]);
sum-=query(rnk[w],rnk[w]);
printf("%lld\n",sum);
}
}
return 0;
}