#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, a[100010], sum[400010], al[400010], ar[400010], lazy[400010];
int cnt, fa[100010], dep[100010], siz[100010], son[100010], top[100010], dfn[100010], rnk[100010];
vector<int> v[100010];
void dfs1(int x, int f)
{
siz[x] = 1;
for (auto i : v[x])
{
if (i == f) continue;
fa[i] = x, dep[i] = dep[x] + 1;
dfs1(i, x);
siz[x] += siz[i];
if (siz[i] > siz[son[x]]) son[x] = i;
}
}
void dfs2(int x, int f)
{
top[x] = f, dfn[x] = ++cnt, rnk[cnt] = x;
if (!son[x]) return;
dfs2(son[x], f);
for (auto i : v[x])
{
if (fa[x] == i || son[x] == i) continue;
dfs2(i, i);
}
}
void maketag(int u, int x)
{
sum[u] = 1, al[u] = ar[u] = lazy[u] = x;
}
void pushdown(int u, int L, int R)
{
int M = L + R >> 1;
if (lazy[u]) maketag(u << 1, lazy[u]);
if (lazy[u]) maketag(u << 1 | 1, lazy[u]);
lazy[u] = 0;
}
void pushup(int u)
{
sum[u] = sum[u << 1] + sum[u << 1 | 1], al[u] = al[u << 1], ar[u] = ar[u << 1 | 1];
if (ar[u << 1] == al[u << 1 | 1]) sum[u]--;
}
void build(int u, int L, int R)
{
if (L == R)
{
sum[u] = 1, al[u] = ar[u] = a[rnk[L]];
return;
}
int M = L + R >> 1;
build(u << 1, L, M);
build(u << 1 | 1, M + 1, R);
pushup(u);
}
void update(int u, int L, int R, int l, int r, int x)
{
if (l <= L && R <= r) maketag(u, x);
else if (l <= R && L <= r)
{
int M = L + R >> 1;
pushdown(u, L, R);
update(u << 1, L, M, l, r, x);
update(u << 1 | 1, M + 1, R, l, r, x);
pushup(u);
}
}
int query_l(int u, int L, int R, int l, int r)
{
if (L == l && R == l) return al[u];
else if (L <= l && l <= R)
{
int M = L + R >> 1;
pushdown(u, L, R);
return query_l(u << 1, L, M, l, r) + query_l(u << 1 | 1, M + 1, R, l, r);
}
else return 0;
}
int query_r(int u, int L, int R, int l, int r)
{
if (L == r && R == r) return ar[u];
else if (L <= r && r <= R)
{
int M = L + R >> 1;
pushdown(u, L, R);
return query_r(u << 1, L, M, l, r) + query_r(u << 1 | 1, M + 1, R, l, r);
}
else return 0;
}
int query(int u, int L, int R, int l, int r)
{
if (l <= L && R <= r) return sum[u];
else if (l <= R && L <= r)
{
int M = L + R >> 1;
pushdown(u, L, R);
int x = query(u << 1, L, M, l, r), y = query(u << 1 | 1, M + 1, R, l, r);
if (x && y && query_r(u << 1, L, M, L, M) == query_l(u << 1 | 1, M + 1, R, M + 1, R)) return x + y - 1;
else return x + y;
}
else return 0;
}
void update_sum(int x, int y, int z)
{
int fx = top[x], fy = top[y];
while (fx != fy)
{
if (dep[fx] >= dep[fy])
{
update(1, 1, n, dfn[fx], dfn[x], z);
x = fa[fx];
}
else
{
update(1, 1, n, dfn[fy], dfn[y], z);
y = fa[fy];
}
fx = top[x], fy = top[y];
}
if (dep[x] <= dep[y]) update(1, 1, n, dfn[x], dfn[y], z);
else update(1, 1, n, dfn[y], dfn[x], z);
}
int query_sum(int x, int y)
{
int fx = top[x], fy = top[y], ans = 0, lx = 0, ly = 0;
while (fx != fy)
{
if (dep[fx] >= dep[fy])
{
ans += query(1, 1, n, dfn[fx], dfn[x]);
if (query_r(1, 1, n, dfn[fx], dfn[x]) == lx) ans--;
lx = query_l(1, 1, n, dfn[fx], dfn[x]), x = fa[fx];
}
else
{
ans += query(1, 1, n, dfn[fy], dfn[y]);
if (query_r(1, 1, n, dfn[fy], dfn[y]) == ly) ans--;
ly = query_l(1, 1, n, dfn[fy], dfn[y]), y = fa[fy];
}
fx = top[x], fy = top[y];
}
if (dfn[x] <= dfn[y])
{
ans += query(1, 1, n, dfn[x], dfn[y]);
if (lx == query_l(1, 1, n, dfn[x], dfn[y])) ans--;
if (ly == query_r(1, 1, n, dfn[x], dfn[y])) ans--;
}
else
{
ans += query(1, 1, n, dfn[y], dfn[x]);
if (ly == query_l(1, 1, n, dfn[x], dfn[y])) ans--;
if (lx == query_r(1, 1, n, dfn[x], dfn[y])) ans--;
}
return ans;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i < n; i++)
{
int x, y;
cin >> x >> y;
v[x].push_back(y), v[y].push_back(x);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
while (m--)
{
char op;
int x, y, z;
cin >> op >> x >> y;
if (op == 'C')
{
cin >> z;
update_sum(x, y, z);
}
else cout << query_sum(x, y) << '\n';
}
return 0;
}