#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define int long long
#define lc u << 1
#define rc u << 1 | 1
const int maxn = 100100;
int w[maxn];
vector<int> e[maxn];
int dep[maxn], son[maxn], top[maxn], sz[maxn], fa[maxn];
int cnt, id[maxn], nw[maxn];
int Lc, Rc;
struct tree
{
int l, r;
int tag, sum;
int dl, dr;
} tr[4 * maxn];
void pushup(int u)
{
tr[u].sum = tr[lc].sum + tr[rc].sum;
tr[u].dl = tr[lc].dl;
tr[u].dr = tr[rc].dr;
if (tr[lc].dr == tr[rc].dl)
tr[u].sum--;
}
void pushdown(int u)
{
if (tr[u].tag)
{
tr[lc].sum = 1;
tr[rc].sum = 1;
tr[lc].tag = tr[u].tag;
tr[rc].tag = tr[u].tag;
tr[lc].dl = tr[u].dl;
tr[lc].dr = tr[u].dl;
tr[rc].dl = tr[u].dl;
tr[lc].dr = tr[u].dl;
tr[u].tag = 0;
}
}
void update(int u, int l, int r, int k)
{
if (l <= tr[u].l && tr[u].r <= r)
{
tr[u].sum = 1;
tr[u].tag = 1;
tr[u].dl = k;
tr[u].dr = k;
return;
}
pushdown(u);
int mid = (tr[u].l + tr[u].r) >> 1;
if (r <= mid)
update(lc, l, r, k);
else if (l > mid)
update(rc, l, r, k);
else
{
update(lc, l, mid, k);
update(rc, mid + 1, r, k);
}
pushup(u);
}
void update_path(int u, int v, int k)
{
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap(u, v);
update(1, id[top[u]], id[u], k);
u = fa[top[u]];
}
if (dep[u] < dep[v])
swap(u, v);
update(1, id[v], id[u], k);
}
int query(int u, int l, int r, int L, int R)
{
if (tr[u].l == L)
Lc = tr[u].dl;
if (tr[u].r == R)
Rc = tr[u].dr;
if (l <= tr[u].l && tr[u].r <= r)
return tr[u].sum;
pushdown(u);
int res = 0;
int mid = (tr[u].l + tr[u].r) >> 1;
if (r <= mid)
return query(lc, l, r, L, R);
else if (l > mid)
return query(rc, l, r, L, R);
else
{
res = query(lc, l, mid, L, R) + query(rc, mid + 1, r, L, R);
if (tr[lc].dr == tr[rc].dl)
res--;
return res;
}
}
int query_path(int u, int v)
{
int res = 0;
int ans1 = -1, ans2 = -1;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap(u, v), swap(ans1, ans2);
res += query(1, id[top[u]], id[u], id[top[u]], id[u]);
if (Rc == ans1)
res--;
ans1 = Lc;
u = fa[top[u]];
}
if (dep[u] < dep[v])
{
swap(u, v);
swap(ans1, ans2);
}
res += query(1, id[v], id[u], id[v], id[u]);
if (Rc == ans1)
res--;
if (Lc == ans2)
res--;
return res;
}
void build(int u, int l, int r)
{
tr[u] = {l, r, 0, 0, nw[l], nw[r]};
if (l == r)
return;
int mid = (l + r) >> 1;
build(lc, l, mid);
build(rc, mid + 1, r);
}
void dfs1(int u, int f)
{
dep[u] = dep[f] + 1, sz[u] = 1, fa[u] = f;
for (int v : e[u])
{
if (v == f)
continue;
dfs1(v, u);
sz[u] += sz[v];
if (sz[son[u]] < sz[v])
son[u] = v;
}
}
void dfs2(int u, int t)
{
top[u] = t, id[u] = ++cnt, nw[cnt] = w[u];
if (!son[u])
return;
dfs2(son[u], t);
for (int v : e[u])
{
if (v == fa[u] || v == son[u])
continue;
dfs2(v, v);
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> w[i];
for (int i = 1, u, v; i < n; i++)
{
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1, 1);
dfs2(1, 1);
build(1, 1, n);
for (int i = 1; i <= n; i++)
update(1, id[i], id[i], w[i]);
char op;
int a, b, c;
while (m--)
{
cin >> op;
if (op == 'C')
{
cin >> a >> b >> c;
update_path(a, b, c);
}
else
{
cin >> a >> b;
cout << query_path(a, b) << '\n';
}
}
return 0;
}