#include <bits/stdc++.h>
#define mid (l + r >>1)
#define len (r - l + 1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int maxn = 100005;
int cnt,head[maxn],to[maxn<<1],nxt[maxn<<1];
int w[maxn],wt[maxn];
int a[maxn<<2],maxx[maxn<<2],laz[maxn<<2];
int n;
int siz[maxn],dep[maxn],son[maxn],tot,id[maxn],top[maxn],fa[maxn];
int read()
{
int x = 0,f = 1;
char ch = getchar();
while(ch < '0'||ch > '9') {if(ch == '-') f = -1;ch = getchar();}
while(ch >= '0'&& ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
int add(int x,int y)
{
nxt[++cnt] = head[x];
to[cnt] = y;
head[x] = cnt;
}
void pushup(int rt)
{
a[rt] = a[rt<<1] + a[rt<<1|1];
maxx[rt] = max(maxx[rt<<1],maxx[rt<<1|1]);
}
void build(int rt,int l,int r)
{
if(l == r)
{
a[rt] = maxx[rt] = wt[l];
return;
}
build(lson);
build(rson);
pushup(rt);
}
void update(int rt,int l,int r,int u,int k)
{
if(r < u||l > u) return;
if(l == r&& l == u)
{
a[rt] = k;
maxx[rt] = k;
return;
}
if(u <= mid) update(lson,u,k);
else update(rson,u,k);
pushup(rt);
}
int querysum(int rt,int l,int r,int L,int R)
{
if(L <= l && r <= R)
{
return a[rt];
}
if(l > R||r <L) return 0;
int ans = 0;
if(L <= mid) ans += querysum(lson,L,R);
if(R > mid) ans += querysum(rson,L,R);
return ans;
}
int querymax(int rt,int l,int r,int L,int R)
{
if(L <= l && r <= R)
{
return maxx[rt];
}
if(l > R||r < L) return 0;
int ans = -0x3f3f3f3f;
if(L <= mid) ans = max(ans,querymax(lson,L,R));
if(R > mid) ans = max(ans,querymax(rson,L,R));
return ans;
}
void dfs1(int x,int fath)
{
dep[x] = dep[fath] + 1;
fa[x] = fath;
siz[x] = 1;
for(int i = head[x];i;i = nxt[i])
{
int v = to[i];
if(v == fath) continue;
dfs1(v,x);
siz[x] += siz[v];
if(siz[son[x]]<siz[v]) son[x] = v;
}
}
void dfs2(int x,int topf)
{
id[x] = ++tot;
wt[tot] = w[x];
top[x] = topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(int i = head[x];i;i = nxt[i])
{
int v = to[i];
if(v == fa[x]||v == son[x]) continue;
dfs2(v,v);
}
}
int query1(int x,int y)
{
int ans = 0;
while(top[x]!=top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x,y);
int res = querysum(1,1,n,id[top[x]],id[x]);
ans += res;
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
ans += querysum(1,1,n,id[x],id[y]);
return ans;
}
int query2(int x,int y)
{
int ans = -0x3f3f3f3f;
while(top[x]!=top[y])
{
if(dep[top[x]] < dep[top[y]]) swap(x,y);
int res = querymax(1,1,n,id[top[x]],id[x]);
ans = max(ans,res);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
ans = max(ans,querymax(1,1,n,id[x],id[y]));
return ans;
}
int main()
{
n = read();
for(int i = 1;i <= n-1;i++)
{
int aa = read(),bb = read();
add(aa,bb);
add(bb,aa);
}
for(int i = 1;i <= n;i++)
{
w[i] = read();
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
int m = read();
for(int i = 1;i <= m;i++)
{
int x,y;
char s[10];
scanf("%s%d%d",s,&x,&y);
if (s[1]=='H') update(1,1,n,id[x],y);
if (s[1]=='M') printf("%d\n",query2(x,y));
if (s[1]=='S') printf("%d\n",query1(x,y));
}
return 0;
}