#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<iostream>
#include<string>
#include<cmath>
#define N 200100
#define lc(x) (x<<1)
#define rc(x) ((x<<1)+1)
#define FOR(i,a,b) for(i=(a);i<=(b);i++)
#define ROF(i,a,b) for(i=(a);i>=(b);i--)
typedef long long LL;
using namespace std;
struct node{int l,r,Max,sum;};
int last[N],pre[N],e[N],w[N],idx[N];
int siz[N],son[N],fa[N],dep[N],top[N],b[N];
int a[N];char op[101];
int t1,t2,t3,n,q,len=0,size=0;
void add(int x,int y)
{pre[++len]=last[x];last[x]=len;e[len]=y;}
int swap(int &x,int &y){int t=x;x=y;y=t;}
struct segtree
{
node tree[4*N];
void init(){memset(tree,0,sizeof(tree));}
void update(int x)
{
tree[x].Max=max(tree[lc(x)].Max,tree[rc(x)].Max);
tree[x].sum=tree[lc(x)].sum+tree[rc(x)].sum;
}
void build(int x,int L,int R)
{
tree[x].l=L;tree[x].r=R;int mid=(L+R)>>1;
if (L==R) {tree[x].Max=tree[x].sum=a[L];return;}
build(lc(x),L,mid);build(rc(x),mid+1,R);
update(x);
}
int qmax(int x,int L,int R)
{
if (tree[x].l==L&&tree[x].r==R) return tree[x].Max;
int mid=(tree[x].l+tree[x].r)>>1;
if (R<=mid) return qmax(lc(x),L,R);
if (L>mid) return qmax(rc(x),L,R);
return max(qmax(lc(x),L,mid),qmax(rc(x),mid+1,R));
}
int qsum(int x,int L,int R)
{
if (tree[x].l==L&&tree[x].r==R) return tree[x].sum;
int mid=(tree[x].l+tree[x].r)>>1;
if (R<=mid) return qsum(lc(x),L,R);
if (L>mid) return qsum(rc(x),L,R);
return qsum(lc(x),L,mid)+qsum(rc(x),mid+1,R);
}
void modify(int x,int p,int ti)
{
if (tree[x].l==tree[x].r) {tree[x].Max=tree[x].sum=ti;return;}
int mid=(tree[x].l+tree[x].r)>>1;
if (p<=mid) modify(lc(x),p,ti);
else modify(rc(x),p,ti);
update(x);
}
}Tree;
void DFS1(int x,int par,int Dep)
{
dep[x]=Dep;siz[x]=1;son[x]=0;
for(int p=last[x];p;p=pre[p])
{
int v=e[p],ID=idx[p];
if (par==v) continue;
fa[v]=x;
DFS1(v,x,Dep+1);
if (son[x]==0||siz[v]>siz[son[x]]) son[x]=v;
siz[x]+=siz[v];
}
}
void DFS2(int x,int Top)
{
w[x]=++size;top[x]=Top;
a[size]=b[x];
if (son[x]!=0) DFS2(son[x],Top);
for(int p=last[x];p;p=pre[p])
{
int v=e[p];
if (v==fa[x]||v==son[x]) continue;
DFS2(v,v);
}
}
int getmax(int va,int vb)
{
int f1=top[va],f2=top[vb],tmp=-1e9;
while (f1!=f2)
{
if (dep[f1]<dep[f2]){swap(f1,f2);swap(va,vb);}
tmp=max(tmp,Tree.qmax(1,w[f1],w[va]));
va=fa[f1];f1=top[va];
}
if (va==vb) return max(tmp,Tree.qmax(1,w[va],w[vb]));
if (dep[va]>dep[vb]) swap(va,vb);
return max(tmp,Tree.qmax(1,w[va],w[vb]));
}
int getsum(int va,int vb)
{
int f1=top[va],f2=top[vb],tmp=0;
while (f1!=f2)
{
if (dep[f1]<dep[f2]){swap(f1,f2);swap(va,vb);}
tmp+=Tree.qsum(1,w[f1],w[va]);
va=fa[f1];f1=top[va];
}
if (va==vb) return tmp+Tree.qsum(1,w[va],w[vb]);
if (dep[va]>dep[vb]) swap(va,vb);
return tmp+Tree.qsum(1,w[va],w[vb]);
}
int main()
{
memset(pre,0,sizeof(pre));
memset(last,0,sizeof(last));
memset(idx,0,sizeof(idx));
len=size=0;Tree.init();
scanf("%d",&n);int i,ops,t1,t2;
FOR(i,1,n-1)
{
scanf("%d%d",&t1,&t2);
add(t1,t2);add(t2,t1);
}
FOR(i,1,n) scanf("%d",&b[i]);
DFS1(1,-1,1);
DFS2(1,1);
Tree.build(1,1,n);
scanf("%d",&ops);
FOR(i,1,ops)
{
scanf("%s%d%d",op,&t1,&t2);
if (op[0]=='C') Tree.modify(1,w[t1],t2);
if (op[1]=='M') printf("%d\n",getmax(t1,t2));
if (op[1]=='S') printf("%d\n",getsum(t1,t2));
}
}