#include<bits/stdc++.h>
#define int long long
const int N=3e5+5;
struct node
{
int maxx,sum,l,r;
}tree[4*N];
int cnt,n,q,fa[N],dep[N],siz[N],top[N],dfn[N],rnk[N],hson[N],vis[N],dat[N];
std::vector<int> Tree[N];
inline int read()
{
int w=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
w=(w<<3)+(w<<1)+(ch-48);
ch=getchar();
}
return w*f;
}
void dfs1(int p,int deep)
{
dep[p]=deep;
hson[p]=0;
siz[p]=1;
int Size=Tree[p].size();
for(int i=0;i<Size;i++)
{
int to=Tree[p][i];
if(!vis[to])
{
vis[to]=1;
fa[to]=p;
dfs1(to,deep+1);
siz[p]+=siz[to];
if(siz[hson[p]]<siz[to])
{
hson[p]=to;
}
}
}
}
void dfs2(int p,int tot)
{
cnt++;
dfn[p]=cnt;
rnk[cnt]=p;
top[p]=tot;
if(hson[p]!=0)
{
vis[hson[p]]=1;
dfs2(hson[p],tot);
}
int Size=Tree[p].size();
for(int i=0;i<Size;i++)
{
int to=Tree[p][i];
if(to!=hson[p]&&!vis[to])
{
vis[to]=1;
dfs2(to,to);
}
}
}
void Build(int p,int l,int r)
{
tree[p].l=l;tree[p].r=r;
if(l==r)
{
tree[p].maxx=tree[p].sum=dat[dfn[l]];
return ;
}
int mid=(l+r)/2;
Build(p*2,l,mid);
Build(p*2+1,mid+1,r);
tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
tree[p].maxx=std::max(tree[p*2].maxx,tree[p*2+1].maxx);
}
void Init()
{
int root=1;
vis[root]=1;
dfs1(root,1);
memset(vis,0,sizeof(vis));
vis[root]=1;
dfs2(root,root);
Build(1,1,n);
}
int AskSum(int p,int l,int r)
{
if(l<=tree[p].l&&tree[p].r<=r)
{
return tree[p].sum;
}
int mid=(tree[p].l+tree[p].r)/2,res=0;
if(l<=mid) res+=AskSum(p*2,l,r);
if(r>=mid+1) res+=AskSum(p*2+1,l,r);
return res;
}
int AskMax(int p,int l,int r)
{
if(l<=tree[p].l&&tree[p].r<=r)
{
return tree[p].maxx;
}
int mid=(tree[p].l+tree[p].r)/2,Max=-0x3f3f3f3f3f3f3f3f;
if(l<=mid) Max=std::max(Max,AskMax(p*2,l,r));
if(r>=mid+1) Max=std::max(Max,AskMax(p*2+1,l,r));
return Max;
}
void Change(int p,int l,int x)
{
if(tree[p].l==tree[p].r&&tree[p].l==l)
{
tree[p].sum+=x;
tree[p].maxx+=x;
return ;
}
int mid=(tree[p].l+tree[p].r)/2;
if(l<=mid) Change(p*2,l,x);
if(l>=mid+1) Change(p*2+1,l,x);
tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;
tree[p].maxx=std::max(tree[p*2].maxx,tree[p*2+1].maxx);
}
int JumpLinkMax(int u,int v)
{
int res=-0x3f3f3f3f3f3f3f3f;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
res=std::max(res,AskMax(1,dfn[top[u]],dfn[u]));
u=fa[top[u]];
}
if(dep[u]<dep[v]) std::swap(u,v);
res=std::max(res,AskMax(1,dfn[v],dfn[u]));
return res;
}
int JumpLinkSum(int u,int v)
{
int res=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) std::swap(u,v);
res+=AskSum(1,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) std::swap(u,v);
res+=AskSum(1,dfn[v],dfn[u]);
return res;
}
void Query()
{
q=read();
for(int i=1;i<=q;i++)
{
char s[15];scanf("%s",s+1);
if(s[1]=='C')
{
int u=read(),x=read();
Change(1,dfn[u],x-dat[u]);// add one point change
dat[u]=x;
}
if(s[1]=='Q'&&s[2]=='M')
{
int u=read(),v=read();
printf("%lld\n",JumpLinkMax(u,v));
}
if(s[1]=='Q'&&s[2]=='S')
{
int u=read(),v=read();
printf("%lld\n",JumpLinkSum(u,v));
}
}
}
void Input()
{
n=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
Tree[u].push_back(v);
Tree[v].push_back(u);
}
for(int i=1;i<=n;i++) dat[i]=read();
Init();
Query();
}
signed main()
{
//freopen("1.in","r",stdin);
//freopen("liu.out","w",stdout);
Input();
return 0;
}