#include <bits/stdc++.h>
using namespace std;
template <class T1>
void deb(T1 e) {
  cout << e << endl;
}
template <class T1, class T2>
void deb(T1 e1, T2 e2) {
  cout << e1 << " " << e2 << endl;
}
template <class T1, class T2, class T3>
void deb(T1 e1, T2 e2, T3 e3) {
  cout << e1 << " " << e2 << " " << e3 << endl;
}
template <class T1, class T2, class T3, class T4>
void deb(T1 e1, T2 e2, T3 e3, T4 e4) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << endl;
}
template <class T1, class T2, class T3, class T4, class T5>
void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << endl;
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
void deb(T1 e1, T2 e2, T3 e3, T4 e4, T5 e5, T6 e6) {
  cout << e1 << " " << e2 << " " << e3 << " " << e4 << " " << e5 << " " << e6
       << endl;
}
vector<int> adj[400010];
int nn, ns[400010], ne[400010];
int col[400010];
long long segtree[4 * 400010], lazy[4 * 400010];
int ulta[400010];
void dfs(int node, int par) {
  ns[node] = ++nn;
  ulta[nn] = node;
  for (auto b : adj[node]) {
    if (b == par) continue;
    dfs(b, node);
  }
  ne[node] = nn;
}
int beg, en;
void lazy_update(int lef, int rig, int cur, int val) {
  if (lazy[cur]) {
    segtree[cur] = lazy[cur];
    if (lef != rig) lazy[cur << 1] = lazy[(cur << 1) | 1] = lazy[cur];
    lazy[cur] = 0;
  }
  if (lef > en || rig < beg) return;
  if (lef >= beg && rig <= en) {
    segtree[cur] = (1ll << val);
    if (rig != lef) lazy[(cur << 1) | 1] = lazy[cur << 1] = (1ll << val);
    return;
  }
  int mid = (lef + rig) >> 1, b = (cur << 1);
  lazy_update(lef, mid, b, val);
  lazy_update(mid + 1, rig, b | 1, val);
  segtree[cur] = segtree[b] | segtree[b + 1];
}
long long query(int lef, int rig, int cur) {
  if (lazy[cur] > 0) {
    segtree[cur] = lazy[cur];
    if (lef != rig) lazy[cur << 1] = lazy[(cur << 1) | 1] = lazy[cur];
    lazy[cur] = 0;
  }
  if (lef > en || rig < beg) return 0ll;
  if (lef >= beg && rig <= en) return segtree[cur];
  int mid = (lef + rig) >> 1, b = (cur << 1);
  return query(lef, mid, b) | query(mid + 1, rig, b + 1);
}
void build(int lef, int rig, int cur) {
  if (lef == rig) {
    segtree[cur] = 1ll << col[ulta[lef]];
    return;
  }
  int mid = (lef + rig) >> 1, b = (cur << 1);
  build(lef, mid, b);
  build(mid + 1, rig, b | 1);
  segtree[cur] = segtree[b] | segtree[b + 1];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  ;
  int i, j, n, q, a, b, qt;
  cin >> n >> q;
  for (i = 1; i <= n; i++) cin >> col[i];
  for (i = 0; i < n - 1; i++) {
    cin >> a >> b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  dfs(1, -1);
  build(1, n, 1);
  while (q--) {
    cin >> qt;
    if (qt == 2) {
      cin >> a;
      beg = ns[a];
      en = ne[a];
      deb(__builtin_popcountll(query(1, n, 1)));
      continue;
    }
    cin >> a >> b;
    beg = ns[a];
    en = ne[a];
    lazy_update(1, n, 1, b);
  }
  return 0;
}
