#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define mp make_pair
namespace IO {
#define int long long
#define gh getchar
inline int read(){char ch=gh();int x=0;bool t=0;while(ch<'0'||ch>'9') t|=ch=='-',ch=gh();while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();return t?-x:x;}
inline char getc(){char ch=gh();while(ch<'a'||ch>'z') ch=gh();return ch;}
inline void write(int x){if(x < 0){putchar('-');x = -x;}if(x > 9){write(x / 10);}putchar((x % 10 + '0'));}
}
using namespace IO;
using namespace std;
const int Maxn = 100010;
int a[Maxn], dfn[Maxn], rdfn[Maxn], num, top[Maxn], wc[Maxn], sz[Maxn];
int fa[Maxn];vector<int> G[Maxn]; int dep[Maxn];
int ls, rs;
void dfs(int u, int f){
fa[u] = f; sz[u] = 1; dep[u] = dep[f] + 1;
for(auto v : G[u]){
if(v == f) continue;
dfs(v,u);
sz[u] += sz[v];
if(sz[v] > sz[wc[u]]) wc[u] = v;
}
}
void dfs2(int u, int tp){
top[u] = tp; dfn[u] = ++num; rdfn[num] = u;
if(wc[u]) dfs2(wc[u],tp);
for(auto v : G[u]){
if(v != wc[u] and v != fa[u]){
dfs2(v,v);
}
}
}
#define ls(u) u << 1
#define rs(u) u << 1 | 1
int n, m;
struct Node{
int lf, rt, cnt;
int l, r;
int tag;
}t[Maxn << 2];
void push_up(int u){t[u].cnt = t[ls(u)].cnt + t[rs(u)].cnt;
if(t[ls(u)].rt == t[rs(u)].lf) t[u].cnt--;
t[u].lf = t[ls(u)].lf; t[u].rt = t[rs(u)].rt;
}
void build(int u, int l, int r){
t[u].tag = 0;t[u].l = l; t[u].r = r;
if(l == r){
t[u].cnt = 1;
t[u].lf = t[u].rt = a[rdfn[l]]; return ;
}int mid = (l + r) >> 1;
build(ls(u), l, mid);
build(rs(u),mid+1,r);
push_up(u);
}
void push_down(int u){
if(t[u].tag){
t[rs(u)].tag = t[ls(u)].tag = t[u].tag;
t[rs(u)].lf = t[rs(u)].rt = t[ls(u)].lf = t[ls(u)].rt = t[u].tag;
t[rs(u)].cnt = t[ls(u)].cnt = 1; t[u].tag = 0;
}
}
void update(int u, int l, int r, int L, int R, int d){
if(L <= l and r <= R) {
t[u].lf = t[u].rt = d; t[u].tag = d; t[u].cnt = 1;
return;
}int mid = (l + r) >> 1;
push_down(u);
if(L <= mid) update(ls(u), l, mid, L, R, d);
if(mid < R) update(rs(u), mid+1,r, L, R, d);
push_up(u);
}
int query(int u, int l, int r, int L, int R){
if(l == L) ls = t[u].lf;
if(r == R) rs = t[u].rt;
if(L <= l and r <= R){
return t[u].cnt;
}int mid = (l + r) >> 1, ans = 0, k = 0,p = 0;
push_down(u);
if(R <= mid)return query(ls(u),l,mid,L,R);
if(L > mid) return query(rs(u),mid+1,r,L,R);
if(t[ls(u)].rt == t[rs(u)].lf){
ans = query(ls(u),l,mid,L,R) + query(rs(u),mid+1,r,L,R) - 1;
}else ans = query(ls(u),l,mid,L,R) + query(rs(u),mid+1,r,L,R);
return ans;
}
int qry(int x, int y){
int ans = 0, lf1 = 0, lf2 = 0;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x,y); swap(lf1,lf2);
ans += query(1,1,n,dfn[top[x]],dfn[x]);
if(lf1 == rs)ans--; lf1 = ls;
x = fa[top[x]];
}
if(dfn[x] > dfn[y]){
swap(x,y); swap(lf1,lf2);
}
ans += query(1,1,n,dfn[x],dfn[y]);
if(ls == lf1) ans--;
if(rs == lf2) ans--;
return ans;
}
void upd(int x, int y, int d){
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x,y);
update(1,1,n,dfn[top[x]],dfn[x],d);
x = fa[top[x]];
}if(dfn[x] > dfn[y]) swap(x,y);
update(1,1,n,dfn[x],dfn[y],d);
}
signed main(){
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1,u,v; i < n; i++){
cin >> u >> v;
G[u].pb(v); G[v].pb(u);
}
dfs(1, 1); dfs2(1,1); build(1,1,n);
char op;
for(int i = 1,x,y,z; i <= m; i++){
cin >> op;
if(op == 'C'){ x=read(),y=read(),z=read();
upd(x,y,z);
}
else { cin >> x >> y;
cout << qry(x,y) << endl;
}
}
}