#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 1145;
struct T {
int front, back, num, flag;
}tr[N << 2];
int n, m;
int top[N], dep[N], dfn[N], idx = 0, fa[N], h_son[N], id[N], siz[N], a[N];
vector <int> e[N];
void push_down (int rt){
if (tr[rt].flag) {
int col = tr[rt].flag;
tr[rt << 1] = {col, col, 1, col};
tr[rt << 1 | 1] = {col, col, 1, col};
tr[rt].flag = 0;
}
}
void push_up (int rt) {
if (tr[rt << 1].num == 0 && tr[rt << 1 | 1].num == 0) return ;
if (tr[rt << 1].num == 0) {
tr[rt] = tr[rt << 1 | 1];
return ;
}
if (tr[rt << 1 | 1].num == 0) {
tr[rt] = tr[rt << 1];
return ;
}
tr[rt].front = tr[rt << 1].front;
tr[rt].back = tr[rt << 1 | 1].back;
tr[rt].num = tr[rt << 1].num + tr[rt << 1 | 1].num - (tr[rt << 1].back == tr[rt << 1 | 1].front);
}
void update (int rt, int l, int r, int L, int R, int col){
if (L <= l && r <= R) {
tr[rt] = {col, col, 1, col};
return;
}
push_down (rt);
int mid = (l + r) >> 1;
if (L <= mid) update (rt << 1, l, mid, L, R, col);
if (mid < R) update (rt << 1 | 1, mid + 1, r, L, R, col);
push_up (rt);
}
void Color (int u, int v, int col) {
while (top[u] != top[v]) {
if (dep[top[u]] > dep[top[v]]) {
update (1, 1, n, dfn[top[u]], dfn[u], col);
u = fa[top[u]];
} else {
update (1, 1, n, dfn[top[v]], dfn[v], col);
v = fa[top[v]];
}
}
if (dep[u] < dep[v])
update (1, 1, n, dfn[u], dfn[v], col);
else update (1, 1, n, dfn[v], dfn[u], col);
}
void build (int rt, int l, int r) {
tr[rt] = {0, 0, 0, 0};
if (l == r) {
tr[rt] = {a[dfn[l]], a[dfn[l]], 1, 0};
return ;
}
int mid = (l + r) >> 1;
build (rt << 1, l, mid);
build (rt << 1 | 1, mid + 1, r);
push_up(rt);
}
void merg (T &a, T b) {
// a.back = b.back;
if (a.num == 0) {a = b; return;}
a.num = a.num + b.num - (a.back == b.front);
a.back = b.back;
}
T query (int rt, int l, int r, int L, int R) {
if (L <= l && r <= R)
return tr[rt];
int mid = (l + r) >> 1;
push_down (rt);
T tmp;
tmp = {0, 0, 0, 0};
if (L <= mid) merg (tmp, query (rt << 1, l, mid, L, R));
if (mid < R) merg (tmp, query (rt << 1 | 1, mid + 1, r, L, R));
push_up (rt);
return tmp;
}
void dfs1 (int u, int f){
fa[u] = f;
siz[u] = 1;
dep[u] = dep[f] + 1;
h_son[u] = -1;
for(int i = 0; i < e[u].size(); i ++){
int v = e[u][i];
if (v == f) continue;
dfs1(v, u);
siz[u] += siz[v];
if ( (h_son[u] == -1) || siz[v] > siz[h_son[u]])
h_son[u] = v;
}
}
void dfs2 (int u, int tp){
dfn[u] = ++ idx;
top[u] = tp;
id[idx] = u;
if (h_son[u] != -1)
dfs2 (h_son[u], tp);
for (int i = 0; i < e[u].size(); i ++) {
int v = e[u][i];
if(v == fa[u] || v == h_son[u]) continue;
dfs2 (v, v);
}
}
int Query (int u, int v) {
T tmp;
// cout << tmp_u.num << endl;
int frou = -1, frov = -1;
int ans = 0;
while (top[u] != top[v]) {
if (dep[top[u]] > dep[top[v]]) {
tmp = query (1, 1, n, dfn[top[u]], dfn[u]);
ans += tmp.num;
if (frou == tmp.back)
ans --;
frou = tmp.front;
u = fa[top[u]];
} else {
tmp = query (1, 1, n, dfn[top[v]], dfn[v]);
ans += tmp.num;
if (frov == tmp.back)
ans --;
frov = tmp.front;
v = fa[top[v]];
}
}
if (dep[u] < dep[v]) {
tmp = query (1, 1, n, dfn[u], dfn[v]);
ans += tmp.num;
if (tmp.back == frov)
ans --;
if (tmp.front == frou)
ans --;
// ans = tmp_v.num + tmp_u.num - (tmp_v.front == tmp_u.front);
return ans;
}
tmp = query (1, 1, n, dfn[v], dfn[u]);
ans += tmp.num;
if (tmp.back == frou)
ans --;
if (tmp.front == frov)
ans --;
// tmp_u = tmp;
// ans = tmp_v.num + tmp_u.num - (tmp_v.front == tmp_u.front);
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++)
scanf ("%d", &a[i]);
for (int i = 1; i < n; i ++) {
int u, v;
scanf("%d%d", &u, &v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
build (1, 1, n);
while (m --) {
char op;
cin >> op;
int u, v, c;
scanf ("%d%d", &u, &v);
if (op == 'C') {
scanf ("%d", &c);
Color (u, v, c);//路径上染色
} else {
printf ("%d\n", Query (u, v));//查询
}
}
return 0;
}