#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
vector<int> ed[N];
int n, q, cnt;
int a[N], Lc, Rc;
int dfn[N], rnk[N], top[N], siz[N], son[N], fa[N], h[N];
struct segt {
int d[N * 4], lc[N * 4], rc[N * 4], tg[N * 4];
void pushup(int p) {
d[p] = d[p << 1] + d[(p << 1) | 1];
lc[p] = lc[p << 1];
rc[p] = rc[(p << 1) | 1];
if(rc[p << 1] == lc[(p << 1) | 1])
--d[p];
}
void _fill(int p, int x) {
d[p] = 1;
tg[p] = lc[p] = rc[p] = x;
}
void pushdown(int p) {
if(!tg[p]) return;
_fill(p << 1, tg[p]);
_fill((p << 1) | 1, tg[p]);
tg[p] = 0;
}
void build(int l, int r, int p) {
if(l == r) {
d[p] = 1;
lc[p] = rc[p] = a[rnk[l]];
tg[p] = 0;
return;
}
int mid = (l + r) >> 1;
build(l, mid, p << 1);
build(mid + 1, r, (p << 1) | 1);
pushup(p);
}
void modify(int l, int r, int s, int t, int o, int p) {
if(s <= l && r <= t) {
_fill(p, o);
return;
}
pushdown(p);
int mid = (l + r) >> 1;
if(s <= mid) modify(l, mid, s, t, o, p << 1);
if(t > mid) modify(mid + 1, r, s, t, o, (p << 1) | 1);
pushup(p);
}
int query(int l, int r, int s, int t, int p) {
if(s <= l && r <= t) {
if(r == t) Rc = rc[p];
if(l == s) Lc = lc[p];
return d[p];
}
pushdown(p);
int mid = (l + r) >> 1;
if(t <= mid) return query(l, mid, s, t, p << 1);
if(s > mid) return query(mid + 1, r, s, t, (p << 1) | 1);
int ret = query(l, mid, s, t, p << 1) + query(mid + 1, r, s, t, (p << 1) | 1);
if(rc[p << 1] == lc[(p << 1) | 1])
--ret;
return ret;
}
} tr;
void dfs1(int x) {
siz[x] = 1;
son[x] = -1;
for(auto p : ed[x])
if(!h[p]) {
h[p] = h[x] + 1;
fa[p] = x;
dfs1(p);
siz[x] += siz[p];
if(son[x] == -1 || siz[son[x]] < siz[p])
son[x] = p;
}
}
void dfs2(int x, int tp) {
top[x] = tp;
rnk[dfn[x] = ++cnt] = x;
if(~son[x]) {
dfs2(son[x], tp);
for(auto p : ed[x])
if(p != son[x] && p != fa[x])
dfs2(p, p);
}
}
void modify_path(int x, int y, int o) {
while(top[x] != top[y]) {
if(h[top[x]] < h[top[y]]) swap(x, y);
tr.modify(1, n, dfn[top[x]], dfn[x], o, 1);
x = fa[top[x]];
}
if(h[x] > h[y]) swap(x, y);
tr.modify(1, n, dfn[x], dfn[y], o, 1);
}
int query_path(int x, int y) {
int la = 0, lb = 0, ans = 0;
while(top[x] != top[y]) {
if(h[top[x] < h[top[y]]]) {
swap(x, y);
swap(la, lb);
}
ans += tr.query(1, n, dfn[top[x]], dfn[x], 1);
if(Rc == la) --ans;
la = Lc;
x = fa[top[x]];
}
if(h[x] > h[y]) {
swap(x, y);
swap(la, lb);
}
ans += tr.query(1, n, dfn[x], dfn[y], 1);
if(Rc == lb) --ans;
if(Lc == la) --ans;
return ans;
}
char c[10];
int u, v, w;
int main() {
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
for(int i = 1; i < n; ++i) {
scanf("%d%d", &u, &v);
ed[u].push_back(v);
ed[v].push_back(u);
}
h[1] = 1;
dfs1(1);
dfs2(1, 1);
tr.build(1, n, 1);
while(q--) {
scanf("%s%d%d", c, &u, &v);
if(c[0] == 'C') {
scanf("%d", &w);
modify_path(u, v, w);
} else
printf("%d\n", query_path(u, v));
}
}
WA.record