#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
#define ls (x << 1)
#define rs (ls | 1)
#define lson ls, l, mid
#define rson rs, mid + 1, r
using namespace std;
const int N = 3e4 + 10;
struct Edge
{
int next, to;
}a[100010];
int head[210], tot;
void add(int from, int to)
{
tot++;
a[tot].to = to;
a[tot].next = head[from];
head[from] = tot;
}
int n, q;
int dfn[N], top[N], siz[N], fa[N], son[N], dep[N], data[N], w[N], tim;
void dfs1(int x, int f)
{
dep[x] = dep[f] + 1;
siz[x] = 1;
fa[x] = f;
for(int i = head[x];i;i = a[i].next)
{
if(a[i].to == f)continue;
dfs1(a[i].to, x);
siz[x] += siz[a[i].to];
if(son[x] == 0 || siz[a[i].to] > siz[son[x]])son[x] = a[i].to;
}
}
void dfs2(int x, int t)
{
dfn[x] = ++tim;
top[x] = t;
data[tim] = w[x];
if(son[x])dfs2(son[x], t);
for(int i = head[x];i;i = a[i].next)
{
if(a[i].to == fa[x] || a[i].to == son[x])continue;
dfs2(a[i].to, a[i].to);
}
}
struct Node
{
int mx, sum;
}tree[N << 2];
void update_up(int x)
{
tree[x].sum = tree[ls].sum + tree[rs].sum;
tree[x].mx = max(tree[ls].mx, tree[rs].mx);
}
void build(int x, int l, int r)
{
if(l == r)
{
tree[x].sum = tree[x].mx = data[l];
}
else
{
build(lson);
build(rson);
update_up(x);
}
}
void change(int x, int l, int r, int p, int k)
{
if(l == r && r == p)
{
tree[x].mx = tree[x].sum = k;
}
else
{
if(p <= mid)change(lson, p, k);
else if(p > mid)change(rson, p, k);
update_up(x);
}
}
int query1(int x, int l, int r, int s, int e)
{
if(r < s || e < l)return INT_MIN;
else if(s <= l && r <= e)return tree[x].mx;
else
{
return max(query1(lson, s, e), query1(rson, s, e));
}
}
int query2(int x, int l, int r, int s, int e)
{
if(r < s || e < l)return 0;
else if(s <= l && r <= e)return tree[x].sum;
else
{
return query2(lson, s, e) + query2(rson, s, e);
}
}
int tree_query1(int x, int y)
{
int res = INT_MIN;
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]])swap(x, y);
res = max(res, query1(1, 1, n, dfn[top[x]], dfn[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y])swap(x, y);
res = max(res, query1(1, 1, n, dfn[x], dfn[y]));
return res;
}
int tree_query2(int x, int y)
{
int res = 0;
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]])swap(x, y);
res = res + query2(1, 1, n, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if(dep[x] > dep[y])swap(x, y);
res = res + query2(1, 1, n, dfn[x], dfn[y]);
return res;
}
int main()
{
scanf("%d", &n);
for(int i = 1;i <= n - 1;i++)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);add(b, a);
}
for(int i = 1;i <= n;i++)
{
scanf("%d", &w[i]);
}
dfs1(1 ,0);
dfs2(1, 1);
build(1, 1, n);
scanf("%d", &q);
// for(int i = 1;i <= n;i++)
// {
// printf("%d\n", query2(1, 1, n, dfn[i], dfn[i]));
// }
for(int i = 1;i <= q;i++)
{
char ch[10];
int x, y;
scanf(" %s", ch + 1);
scanf("%d%d", &x, &y);
if(x > y)swap(x, y);
if(ch[2] == 'H')
{
change(1, 1, n, dfn[x], y);
}
if(ch[2] == 'M')
{
printf("%d\n", tree_query1(x, y));
}
if(ch[2] == 'S')
{
printf("%d\n", tree_query2(x, y));
}
}
return 0;
}