#include <bits/stdc++.h>
using namespace std;
const int N = 200'447;
const int LOG = 20;
vector<int> g[N];
int tin[N];
int tout[N];
int up[N][LOG];
int T;
int d[N];
void dfs(int v, int p, int depth)
{
tin[v] = T++;
up[v][0] = p;
for(int i = 1; i < LOG; i++)
up[v][i] = up[up[v][i - 1]][i - 1];
d[v] = depth;
for (int to : g[v])
if (to != p)
dfs(to, v, depth + 1);
tout[v] = T++;
}
bool is_ancestor(int p, int v)
{
return tin[p] <= tin[v] && tout[v] <= tout[p];
}
int lca(int u, int v)
{
if (is_ancestor(v, u)) return v;
for(int i = LOG - 1; i >= 0; i--)
{
if (!is_ancestor(up[v][i], u))
v = up[v][i];
}
return up[v][0];
}
struct SegTree
{
vector<long long> add;
void init(int _n)
{
int n = 1;
while(n < _n)
n *= 2;
add.resize(2 * n);
}
void upd(int v, int tl, int tr, int l, int r, long long val)
{
if(r <= tl || tr <= l)
return;
if(l <= tl && tr <= r)
{
add[v] += val;
return;
}
int tm = (tl + tr) / 2;
upd(2 * v + 1, tl, tm, l, r, val);
upd(2 * v + 2, tm, tr, l, r, val);
}
long long query(int v, int tl, int tr, int pos)
{
if(tl + 1 == tr)
return add[v];
int tm = (tl + tr) / 2;
if(pos < tm)
return add[v] + query(2 * v + 1, tl, tm, pos);
else
return add[v] + query(2 * v + 2, tm, tr, pos);
}
};
int main()
{
int n, q;
cin >> n >> q;
vector<int> val(n);
for(int i = 0; i < n; i++)
cin >> val[i];
for(int i = 0; i < n - 1; i++)
{
int u, v;
cin >> u >> v;
u--, v--;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(0, 0, 0);
SegTree Tr;
Tr.init(T);
for(int v = 0; v < n; v++)
Tr.upd(0, 0, T, tin[v], tout[v], val[v]);
for(int i = 1; i <= q; i++)
{
char t;
cin >> t;
if(t == 'P')
{
int v;
cin >> v;
v--;
Tr.upd(0, 0, T, tin[v], tout[v], -i - val[v]);
val[v] = -i;
}
else
{
int a, b;
cin >> a >> b;
a--, b--;
int c = lca(a, b);
long long ans = 0;
ans += Tr.query(0, 0, T, tin[a]);
ans += Tr.query(0, 0, T, tin[b]);
ans -= 2 * Tr.query(0, 0, T, tin[c]);
ans += val[c];
ans += 1LL * i * (d[a] + d[b] - 2 * d[c] + 1);
cout << ans << '\n';
}
}
return 0;
}