#include <bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
const int N = 1e5 + 10;
int n, m, cnt = 0, cntt = 0, LC, RC;
int head[N];
int fa[N], son[N], dep[N], sz[N], top[N], num[N];
ll a[N], w[N], lazy[4 * N], val[4 * N];
struct node {
ll lx, rx;
int l, r, ls, rs, val;
}t[4 * N];
struct Edge {
int to, next;
}e[2 * N];
void add_edge(int u, int v) {
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
void dfs1(int x, int f) {
fa[x] = f;
dep[x] = dep[f] + 1;
sz[x] = 1;
for (int i = head[x]; i != -1; i = e[i].next) {
if (e[i].to != f) {
dfs1(e[i].to, x);
sz[x] += sz[e[i].to];
if (sz[son[x]] < sz[e[i].to]) son[x] = e[i].to;
}
}
}
void dfs2(int x, int t) {
top[x] = t;
num[x] = ++cntt;
w[cntt] = a[x];
if (!son[x]) return ;
dfs2(son[x], t);
for (int i = head[x]; i != -1; i = e[i].next) {
if (e[i].to != fa[x] && e[i].to != son[x]) {
dfs2(e[i].to, e[i].to);
}
}
}
void push_up(int pos) {
t[pos].val = t[pos << 1].val + t[pos << 1 | 1].val;
t[pos].ls = t[pos << 1].ls, t[pos].lx = t[pos << 1].lx;
t[pos].rs = t[pos << 1 | 1].rs, t[pos].rx = t[pos << 1 | 1].rx;
if (t[pos << 1].rx == t[pos << 1 | 1].lx) {
t[pos].val--;
if (t[pos << 1].ls == t[pos << 1].r - t[pos << 1].l + 1) {
t[pos].ls += t[pos << 1 | 1].ls;
}
if (t[pos << 1 | 1].rs == t[pos << 1 | 1].r - t[pos << 1 | 1].l + 1) {
t[pos].rs += t[pos << 1].rs;
}
}
}
node pushup(node x, node y) {
node z;
z.l = x.l, z.r = y.r;
z.val = x.val + y.val;
z.ls = x.ls, z.lx = x.lx;
z.rs = y.rs, z.rx = y.rx;
if (x.rx == y.lx) {
z.val--;
if (x.ls == x.r - x.l + 1) {
z.ls += y.ls;
}
if (y.rs == y.r - y.l + 1) {
z.rs += x.rs;
}
}
return z;
}
void push_down(int pos, int l, int r) {
if (lazy[pos]) {
lazy[pos << 1] = lazy[pos];
lazy[pos << 1 | 1] = lazy[pos];
int mid = (l + r) >> 1;
t[pos << 1].val = 1;
t[pos << 1].lx = lazy[pos];
t[pos << 1].rx = lazy[pos];
t[pos << 1].ls = t[pos << 1].rs = t[pos << 1].r - t[pos << 1].l + 1;
t[pos << 1 | 1].val = 1;
t[pos << 1 | 1].lx = lazy[pos];
t[pos << 1 | 1].rx = lazy[pos];
t[pos << 1 | 1].ls = t[pos << 1 | 1].rs = t[pos << 1 | 1].r - t[pos << 1 | 1].l + 1;
lazy[pos] = 0;
}
}
void build(int pos, int l, int r) {
t[pos].l = l, t[pos].r = r;
lazy[pos] = 0;
if (l == r) {
t[pos].lx = t[pos].rx = w[l];
t[pos].val = t[pos].ls = t[pos].rs = 1;
return ;
}
int mid = (l + r) >> 1;
build(pos << 1, l, mid);
build(pos << 1 | 1, mid + 1, r);
push_up(pos);
}
void update(int pos, int l, int r, int L, int R, ll k) {
if (l > R || r < L) {
return ;
}
if (L <= l && r <= R) {
lazy[pos] = k;
t[pos].val = 1;
t[pos].lx = k, t[pos].rx = k;
t[pos].ls = t[pos].rs = t[pos].r - t[pos].l + 1;
return ;
}
push_down(pos, l, r);
int mid = (l + r) >> 1;
update(pos << 1, l, mid, L, R, k);
update(pos << 1 | 1, mid + 1, r, L, R, k);
push_up(pos);
}
node query(int pos, int l, int r, int L, int R) {
if (L <= l && r <= R) {
if(l == L) LC = t[pos].lx;
if(r == R) RC = t[pos].rx;
return t[pos];
}
push_down(pos, l, r);
int mid = (l + r) >> 1;
int l1 = l, r1 = mid, l2 = mid + 1, r2 = r;
if (l1 > R || r1 < L) {
return query(pos << 1 | 1, mid + 1, r, L, R);
} else if (l2 > R || r2 < L) {
return query(pos << 1, l, mid, L, R);
} else {
return pushup(query(pos << 1, l, mid, L, R), query(pos << 1 | 1, mid + 1, r, L, R));
}
}
void _update(int x, int y, int z) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
update(1, 1, n, num[top[x]], num[x], z);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
update(1, 1, n, num[x], num[y], z);
}
ll _query(int x, int y) {
long long ans = 0;
int p = 0, q = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y), swap(p, q);
ans += query(1, 1, n, num[top[x]], num[x]).val;
if (RC == p) ans--;
p = LC;
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
ans += query(1, 1, n, num[x], num[y]).val;
if (LC == p) ans--;
if (RC == q) ans--;
return ans;
}
signed main() {
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++) {
head[i] = -1;
}
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
for (int i = 1; i <= n - 1; i++) {
int u, v;
scanf("%lld%lld", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
for (int i = 1; i <= m; i++) {
char op;
cin >> op;
if (op == 'C') {
int x, y, z;
scanf("%lld%lld%lld", &x, &y, &z);
_update(x, y, z);
} else {
int x, y;
scanf("%lld%lld", &x, &y);
printf("%lld\n", _query(x, y));
}
}
return 0;
}