#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define int long long
#define root 1,n,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int A = 1e7+10;
const int B = 1e6+10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int n,m,head[B],cnt;
int dfn[B],pre[B],size[B],js,top[B],fa[B],hson[B],dep[B];
ll val[B];
struct pp{int v,w,nxt;} e[B<<2];
void modify(int u,int v) {e[++cnt].nxt=head[u];e[cnt].v=v;head[u]=cnt;}
namespace Seg
{
struct node
{
int l,r;
ll sum,col,maxx;
node() {sum=col=maxx=0,l=r=0;}
void init(int l_,int r_) {l=l_,r=r_,sum=maxx=val[pre[l]],col=0;}
}z[B<<1];
node operator +(const node &l,const node &r)
{
node p;
p.col=0,p.l=l.l,p.r=r.r;
p.sum=(l.sum+r.sum),p.maxx=max(l.maxx,r.maxx);
return p;
}
void update(int rt) {z[rt]=z[rt<<1]+z[rt<<1|1];}
void build(int l,int r,int rt)
{
if (l==r) {z[rt].init(l,r);return;}
int m=l+r>>1;
build(lson),build(rson);
update(rt);
}
void modify(int l,int r,int rt,int x,ll v)
{
if (l==r) {z[rt].sum=z[rt].maxx=v;return;}
int m=l+r>>1;
if (x<=m) modify(lson,x,v);
else modify(rson,x,v);
update(rt);
}
node query(int l,int r,int rt,int nowl,int nowr)
{
if (nowl<=l && r<=nowr) return z[rt];
int m=l+r>>1;
if (nowl<=m)
{
if (m<nowr) return query(lson,nowl,nowr)+query(rson,nowl,nowr);
else return query(lson,nowl,nowr);
}
else return query(rson,nowl,nowr);
}
}
void dfs1(int u,int pre,int d)
{
fa[u]=pre,size[u]=1,dep[u]=d;
for (int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if (v==pre) continue;
dfs1(v,u,d+1);
size[u]+=size[v];
if (!hson[u] || size[hson[u]]<size[v]) hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp,dfn[u]=++js,pre[js]=u;
if (!hson[u]) return;
dfs2(hson[u],tp);
for (int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if (v!=hson[u] && v!=fa[u]) dfs2(v,v);
}
}
ll path_query(int x,int y)
{
ll ans=0;
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
ans=ans+Seg::query(root,dfn[top[x]],dfn[x]).sum;
x=fa[top[x]];
}
if (dep[x]>dep[y])swap(x,y);
ans=ans+Seg::query(root,dfn[x],dfn[y]).sum;
return ans;
}
ll path_query2(int x,int y)
{
ll ans=0;
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,Seg::query(root,dfn[top[x]],dfn[x]).maxx);
x=fa[top[x]];
}
if (dep[x]>dep[y])swap(x,y);
ans=max(ans,Seg::query(root,dfn[x],dfn[y]).maxx);
return ans;
}
main()
{
int a,b,w; char p[20];
n=read();
for (int i=1;i<n;i++) {a=read(),b=read(),modify(a,b),modify(b,a);}
for (int i=1;i<=n;i++) val[i]=read();
dfs1(1,0,1),dfs2(1,1),Seg::build(root);
m=read();
while (m--)
{
scanf("%s",p);
if (p[0]=='Q' && p[1]=='S') {a=read(),b=read();printf("%lld\n",path_query(a,b));}
else if (p[0]=='Q' && p[1]=='M') {a=read(),b=read();printf("%lld\n",path_query2(a,b));}
else if (p[0]=='C') {a=read(),b=read(); Seg::modify(root,a,b);}
}
}