#include <bits/stdc++.h>
using namespace std;
const int N = 30010;
int n, q, w[N];
vector<int> g[N];
int son[N], id[N], wt[N], siz[N], father[N], top[N], depth[N], cnt;
using ll = long long;
struct seg_tree
{
#define lc(x) x<<1
#define rc(x) x<<1|1
int l, r;
ll sum, maxv;
};
seg_tree t[N<<2];
void pushup (int p)
{
t[p].sum = t[lc(p)].sum + t[rc(p)].sum;
t[p].maxv = max(t[lc(p)].maxv, t[rc(p)].maxv);
}
void build (int p, int l, int r)
{
t[p].l = l, t[p].r = r;
if (l == r)
{
t[p].maxv = wt[l];
t[p].sum = wt[l];
return ;
}
int mid = l + r >> 1;
build(lc(p), l, mid); build(rc(p), mid + 1, r);
pushup(p);
}
void update (int p, int x, int v)
{
if (t[p].l == t[p].r && t[p].l == x)
{
t[p].maxv = v;
t[p].sum = v;
return ;
}
int mid = t[p].l + t[p].r >> 1;
if (x <= mid) update(lc(p), x, v);
if (x > mid) update(rc(p), x, v);
pushup(p);
}
ll query_max (int p, int l, int r)
{
if (t[p].l >= l && t[p].r <= r) return t[p].maxv;
int mid = t[p].l + t[p].r >> 1;
if(l>mid) return query_max(rc(p),l,r);
else if(r<=mid) return query_max(lc(p),l,r);
else return max(query_max(lc(p) , l, mid),query_max(rc(p),mid+1,r));
}
ll query_sum (int p, int l, int r)
{
if (t[p].l >= l && t[p].r <= r) return t[p].sum;
int mid = t[p].l + t[p].r >> 1;
ll sum = 0;
if (l <= mid) sum += query_sum(lc(p), l, r);
if (r > mid) sum += query_sum(rc(p), l, r);
return sum;
}
void dfs1(int u,int fa)
{
d[u]=d[fa]+1;
siz[u]=1;
int ma=-1;
father[u]=fa;
for( auto v:g[u])
{
if(v==fa)continue;
dfs(v,u);
if(siz[v]>ma) son[u]=v,ma=siz[v];
}
}
void dfs2(int u,int topfather)
{
id[u]=++cnt;
wt[cnt]=w[u];
top[u]=topfather;
if(!son[u])return;
dfs2(son[u],topfather);
for(int v:g[u])
{
if(v==father[u]||v==son[u])continue;
dfs2(v,v);
}
}
void Qmax (int u, int v)
{
ll ans = -1e9;
while(top[u] != top[v])
{
if (depth[top[u]] < depth[top[v]]) swap(u, v);
ans = max(ans, query_max(1, id[top[u]], id[u]));
u = father[top[u]];
}
if (depth[u] > depth[v]) swap(u, v);
ans = max(ans, query_max(1, id[u], id[v]));
cout << ans << endl;
}
int lca(int x,int y)
{
while(x!=y)
{
if(d[top[x]]<deep[top[y]])swap(x,y);
x=fa[top[x]];
}
return d[x]<d[y]?x:y;
}
int main ()
{
cin >> n;
for (int i = 1; i < n; i ++ )
{
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = 1; i <= n; i ++ ) cin >> w[i];
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
cin >> q; while(q -- )
{
string op; int u, v; cin >> op >> u >> v;
if (op == "CHANGE") update(1, id[u], v);
if (op == "QMAX") Qmax(u, v);
if (op == "QSUM") Qsum(u, v);
}
return 0;
}
求lca
int lca(int x,int y)
{
while(top[x] !=top[y] )
{
if(d[top[x]]<deep[top[y]])swap(x,y);
x=fa[top[x]];
}
return d[x]<d[y]?x:y;
}