#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#define maxn 30002
#define inf 1000000
using namespace std;
struct edge{ int to,point,v;};
struct node{ int maxi; int sumi;};
edge e[maxn<<1];
int cnt,size[maxn],a[maxn],fa[maxn][30],deep[maxn],pos[maxn],belong[maxn],A[maxn<<2][2],n,sz;
void add(int u1,int v1){
e[++cnt].to=e[u1].point;e[u1].point=cnt;e[cnt].v=v1;}
void adds(int u1,int v1){ add(u1,v1); add(v1,u1);}
void init(){
scanf("%d",&n);
cnt=0;
for (int i=1;i<n;++i){
int u1,v1;
scanf("%d%d",&u1,&v1);
adds(u1,v1);
}
for (int i=1;i<=n;++i) scanf("%d",&a[i]);
deep[1]=1;
}
void dfs1(int x){
size[x]=1;
for (int i=1;i<=20;++i) fa[x][i]=fa[fa[x][i-1]][i-1];
for (int p=e[x].point;p;p=e[p].to)
if (e[p].v!=fa[x][0]){
fa[e[p].v][0]=x; deep[e[p].v]=deep[x]+1;
dfs1(e[p].v);
size[x]+=size[e[p].v];
}
}
void dfs2(int x,int chain){
int k=0;
pos[x]=++sz;belong[x]=chain;
for (int p=e[x].point;p;p=e[p].to)
if (e[p].v!=fa[x][0]&&size[e[p].v]>size[k]) k=e[p].v;
if (!k) return;
dfs2(k,chain);
for (int p=e[x].point;p;p=e[p].to)
if (e[p].v!=fa[x][0]&&e[p].v!=k)
dfs2(e[p].v,e[p].v);
}
int lca(int u,int v){
if (deep[u]<deep[v]) swap(u,v);
for (int i=20;i>=0;--i)
if (deep[fa[u][i]]>=deep[v]) u=fa[u][i];
for (int i=20;i>=0;--i)
if (fa[u][i]!=fa[v][i]) { u=fa[u][i]; v=fa[v][i];}
if (u!=v) return fa[u][0];
return u;
}
void update(int rt){ A[rt][0]=max(A[rt<<1][0],A[rt<<1|1][0]); A[rt][1]=A[rt<<1][1]+A[rt<<1|1][1];}
void build(int l,int r,int rt){
if (l==r) { A[rt][0]=a[l]; A[rt][1]=a[l]; return;}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
update(rt);
}
void change(int l,int r,int rt,int x,int y){
if (l==r) { A[rt][0]=y; A[rt][1]=y; return;}
int mid=(l+r)>>1;
if (x<=mid) change(l,mid,rt<<1,x,y);
if (x>mid) change(mid+1,r,rt<<1|1,x,y);
update(rt);
}
node query(int l,int r,int rt,int ll,int rr){
if (l>=ll&&rr>=r) return (node){A[rt][0],A[rt][1]};
int mid=(l+r)>>1;
node q1={-inf,0},q2={-inf,0};
if (ll<=mid) q1=query(l,mid,rt<<1,ll,rr);
if (rr>mid) q2=query(mid+1,r,rt<<1|1,ll,rr);
return (node){max(q1.maxi,q2.maxi),q1.sumi+q2.sumi};
}
node find2(int &u,int v){ return query(1,n,1,pos[v],pos[u]);}
node find1(int &u,int v){
node x={-inf,0},y={-inf,0};
while (belong[u]!=belong[v]){
int p=belong[u];
y=query(1,n,1,pos[p],pos[u]);
x=(node){max(x.maxi,y.maxi),x.sumi+y.sumi};
u=fa[belong[u]][0];
}
return x;
}
node find(int u,int v){
node x1={-inf,0},x2={-inf,0};
x1=(node)find1(u,v); x2=(node)find2(u,v);
return (node){max(x1.maxi,x2.maxi),x1.sumi+x2.sumi};
}
void solve(){
int q,x,y,u; char ch[100]; node ans1,ans2;
for (int i=1;i<=n;++i) change(1,n,1,pos[i],a[i]);
scanf("%d",&q);
while (q--){
scanf("%s%d%d",ch,&x,&y);
if (ch[0]=='C') { change(1,n,1,pos[x],y); a[x]=y;}
else { u=lca(x,y);
ans1=find(x,u);
ans2=find(y,u);
if (ch[1]=='M') printf("%d\n",max(ans1.maxi,ans2.maxi));
else printf("%d\n",ans1.sumi+ans2.sumi-a[u]);}
}
}
int main(){
init();
dfs1(1);
dfs2(1,1);
solve();
return 0;
}