#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1000000007, N = 101000;
struct Q{
int l, r;
mutable int v;
Q(int l = 0, int r = 0, int v = 0):l(l), r(r), v(v){}
bool operator< ( const Q& a) const { return l < a.l; }
};
set<Q> st;
int n, m, seed, vmax, nums[N], temp;
set<Q>::iterator split( int pos ){
auto i = st.lower_bound(Q(pos));
if ( i != st.end() && i -> l == pos )
return i;
--i;
if ( i -> r < pos )
return st.end();
int l = i -> l, r = i -> r, v = i -> v;
st.erase(i);
st.insert(Q(l, pos-1, v));
return st.insert(Q(pos, r, v)).first;
}
void assign( int l, int r, int c ){
auto ir = split(r+1), il = split(l);
st.erase(il, ir);
st.insert(Q(l, r, c));
}
int query( int l, int r, int& lst ){
auto ir = split(r+1), il = split(l);
int res = 0;
for ( --ir; ; --ir ) {
if ( ir -> v != lst )
lst = ir -> v, ++res;
if ( il == ir )
break;
}
return res;
}
struct EGDE {
int v, nxt;
}edge[N*2];
int cnt, head[N], fa[N], depth[N], sz[N], hson[N], tot, dfnin[N], dfnout[N], top[N], ord[N];
void add_edge( int u, int v ) {
edge[++cnt].v = v;
edge[cnt].nxt = head[u];
head[u] = cnt;
}
int root;
void DFS1( int u, int f ){
sz[u] = 1;
fa[u] = f;
depth[u] = depth[f] + 1;
for ( int i = head[u]; i; i = edge[i].nxt ) {
int v = edge[i].v;
if ( v == f )
continue;
DFS1(v, u);
sz[u] += sz[v];
if ( sz[hson[u]] < sz[v] )
hson[u] = v;
}
}
void DFS2( int u, int ct ){
top[u] = ct;
dfnin[u] = ++tot;
ord[tot] = nums[u];
if ( hson[u] )
DFS2(hson[u], ct);
for ( int i = head[u]; i; i = edge[i].nxt ) {
int v = edge[i].v;
if ( v == fa[u] || v == hson[u] )
continue;
DFS2(v, v);
}
dfnout[u] = tot;
}
int path( int u, int v, int w = 0 ){
int res = 0, lu = 0, lv = 0, ched = 0;//lb for v, la for u
for ( ; top[u] != top[v]; u = fa[top[u]] ) {
if ( depth[top[u]] < depth[top[v]] )
swap(u, v), ched ^= 1;
if ( w )
assign(dfnin[top[u]], dfnin[u], w);
else
res += ched ? query(dfnin[top[u]], dfnin[u], lv) : query(dfnin[top[u]], dfnin[u], lu);
}
if ( u != v ) {
if ( depth[u] < depth[v] )
swap(u, v), ched ^= 1;//u is deeper than v
if ( w )
assign(dfnin[v], dfnin[u], w);
else
res += ched ? query(dfnin[v], dfnin[u], lv) : query(dfnin[v], dfnin[u], lu);
}
return res - (lu==lv);
}
signed main() {
scanf("%lld%lld", &n, &m);
for ( int i = 1; i <= n; ++i )
scanf("%lld", &nums[i]);
for ( int i = 1, u, v; i < n; ++i ) {
scanf("%lld%lld", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
DFS1(1, 0);
DFS2(1, 1);
for ( int i = 1; i <= n; ++i )
st.insert(Q(i, i, ord[i]));
char str[2];
for ( int i = 1, a, b, c; i <= m; ++i ) {
scanf("%s%lld%lld", str, &a, &b);
if ( str[0] == 'C' ) {
scanf("%lld", &c);
path(a, b, c);
} else
printf("%lld\n", path(a, b));
}
return 0;
}
25分求调。基本可以确定不是树剖或者珂朵莉树的问题……