WA30pts
#include<bits/stdc++.h>
#define mid ((l + r) >> 1)
#define int long long
#define INT_MIN LONG_LONG_MIN
using namespace std;
const int N = 30010;
class p
{
public:
int first, second;
};
vector <int> e[N];
int top[N], dep[N], son[N], size[N], f[N];
int sum[N << 3], dfn[N], lll, maxn[N << 3], tag[N << 3];
int n, val[N], m, a, b, c;
char s[100010];
void build(int root, int l, int r)
{
if (l == r)
{
sum[root] = val[dfn[l]];
maxn[root] = val[dfn[l]];
return;
}
build(root << 1, l, mid);
build((root << 1) + 1, mid + 1, r);
maxn[root] = max(maxn[root << 1], maxn[(root << 1) + 1]);
sum[root] = sum[root << 1] + sum[(root << 1) + 1];
return;
}
void update(int root, int l, int r, int x, int k)
{
if(l == r)
{
sum[root] = k;
maxn[root] = k;
return;
}
if (x > mid)
update((root << 1) + 1, mid + 1, r, x, k);
else
update(root << 1, l, mid, x, k);
maxn[root] = max(maxn[root << 1], maxn[(root << 1) + 1]);
sum[root] = sum[root << 1] + sum[(root << 1) + 1];
return;
}
p query(int root, int l, int r, int qx, int qy)
{
if (qx > qy)
swap(qx ,qy);
if (l >= qx && r <= qy)
return {sum[root], maxn[root]};
if (l == r)
return {0, INT_MIN};
p u = {0, INT_MIN}, v = {0, INT_MIN};
if (mid >= qx)
u = query(root << 1, l, mid, qx, qy);
if (qy > mid)
v = query((root << 1) + 1, mid + 1, r, qx, qy);
return {u.first + v.first, max(u.second, v.second)};
}
void dfs1(int x, int fa)
{
f[x] = fa;
dep[x] = dep[fa] + 1;
size[x] = 1;
for (auto i : e[x])
{
if (i == fa)
continue;
dfs1(i, x);
size[x] += size[i];
if(size[son[x]] < size[i])
son[x] = i;
}
return;
}
void dfs2(int x, int t)
{
dfn[x] = ++lll;
top[x] = t;
if (!son[x])
return;
dfs2(son[x], t);
for(auto i : e[x])
{
if (i == f[x] || i == son[x])
continue;
dfs2(i, i);
}
}
int query_max(int x, int y)
{
int ans = INT_MIN;
while (top[x] != top[y])
{
if (dep[top[x]] < dep[top[y]])
swap(x, y);
ans = max(ans, query(1, 1, n, dfn[top[x]], dfn[x]).second);
x = f[top[x]];
}
if (dep[x] > dep[y])
swap(x, y);
ans = max(ans, query(1, 1, n, dfn[x], dfn[y]).second);
return ans;
}
int query_sum(int x, int y)
{
int ans = 0;
while (top[x] != top[y])
{
if (dep[top[x]] < dep[top[y]])
swap(x, y);
ans += query(1, 1, n, dfn[top[x]], dfn[x]).first;
x = f[top[x]];
}
if (dep[x] > dep[y])
swap(x, y);
ans += query(1, 1, n, dfn[x], dfn[y]).first;
return ans;
}
signed main()
{
cin >> n;
for (int i = 1, u, v; i < n; i++)
{
scanf("%lld%lld", &u, &v);
e[u].push_back(v);
e[v].push_back(u);
}
for (int i = 1; i <= n; i++)
scanf("%lld", val + i);
f[1] = 1;
dep[1] = 1;
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
cin >> m;
while (m--)
{
scanf("%s%lld%lld", s, &a, &b);
if (s[1] == 'M')
{
if (dep[a] > dep[b])
{
swap(a, b);
}
cout << query_max(a, b) << "\n";
}
else if (s[1] == 'S')
{
if (dep[a] > dep[b])
{
swap(a, b);
}
cout << query_sum(a, b) << "\n";
}
else
{
update(1, 1, n, dfn[a], b);
}
}
}