#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
using ii = pair<int, int>;
using vi = vector<int>;
using vl = vector<ll>;
using vii = vector<ii>;
using graph = vector<vi>;
using matrix = graph;
const int MAXN = 4e5 + 5;
const int INF = 0x3f3f3f3f;
const ll INFL = 1e18 + 4;
const ll mod = 1e9 + 7;
graph g;
int in[MAXN], out[MAXN];
bool seen[MAXN];
struct node {
  ll lazy, cor;
  node() : lazy(-1), cor(0) {}
} st[MAXN << 1];
int cnt = 1;
int idx[MAXN];
void dfs(int u) {
  seen[u] = 1;
  in[u] = cnt++;
  for (auto v : g[u])
    if (!seen[v]) {
      dfs(v);
    }
  out[u] = cnt;
}
ll base[MAXN], aux[MAXN];
void build(int p, int l, int r) {
  if (l == r) {
    st[p].cor = base[l];
    st[p].lazy = -1;
  } else {
    int m = l + r >> 1, q = m - l + 1 << 1;
    build(p + 1, l, m);
    build(p + q, m + 1, r);
    st[p].lazy = -1;
    st[p].cor = st[p + 1].cor | st[p + q].cor;
  }
}
void push(int p, int l, int r) {
  st[p].cor = st[p].lazy;
  if (l != r) {
    int m = l + r >> 1, q = m - l + 1 << 1;
    st[p + 1].lazy = st[p].lazy;
    st[p + q].lazy = st[p].lazy;
  }
  st[p].lazy = -1;
}
void update(int p, int l, int r, int ql, int qr, ll c) {
  if (st[p].lazy > 0) push(p, l, r);
  if (r < ql || qr < l) return;
  if (ql <= l && r <= qr) {
    st[p].lazy = c;
    push(p, l, r);
    return;
  }
  int m = l + r >> 1, q = m - l + 1 << 1;
  update(p + 1, l, m, ql, qr, c);
  update(p + q, m + 1, r, ql, qr, c);
  st[p].cor = st[p + 1].cor | st[p + q].cor;
}
ll query(int p, int l, int r, int ql, int qr) {
  if (st[p].lazy > 0) push(p, l, r);
  if (r < ql || qr < l) return 0ll;
  if (ql <= l && r <= qr) return st[p].cor;
  int m = l + r >> 1, q = m - l + 1 << 1;
  return query(p + 1, l, m, ql, qr) | query(p + q, m + 1, r, ql, qr);
}
int main() {
  int n, q;
  scanf("%d %d", &n, &q);
  g.assign(n + 1, vi());
  int u, v, t;
  ll x;
  for (int i = 1; i <= n; ++i) {
    scanf("%lld", &x);
    base[i] = 1ll << x;
  }
  for (int i = 1; i < n; ++i) {
    scanf("%d %d", &u, &v);
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1);
  for (int i = 1; i <= n; ++i) {
    aux[in[i]] = base[i];
  }
  copy(aux + 1, aux + n + 1, base + 1);
  build(1, 1, n);
  while (q--) {
    scanf("%d %d", &t, &v);
    if (t & 1) {
      scanf("%d", &u);
      update(1, 1, n, in[v], out[v] - 1, 1ll << u);
    } else {
      ll ans = query(1, 1, n, in[v], out[v] - 1);
      ans = __builtin_popcountll(ans);
      printf("%lld\n", ans);
    }
  }
}
