#include <bits/stdc++.h>
using namespace std;
const int N = 1000000, M = 60;
template <class elemT>
struct SegmentTree {
  static const int maxn = 1 << 19;
  static const elemT INF = 999999999, FNI = -INF;
  int qL, qR, N;
  elemT v, _sum;
  elemT sumv[maxn << 1], setv[maxn << 1];
  SegmentTree() {
    memset(sumv, 0, sizeof(sumv));
    for (int i = 0; i < (maxn << 1); i++) setv[i] = INF;
  }
  void Init(int n) { Set(1, N = n, 0); }
  void Set(int L, int R, elemT V) {
    qL = L;
    qR = R;
    v = V;
    update(1, 1, N);
  }
  void update(int o, int L, int R) {
    int lc = o << 1, rc = o << 1 | 1;
    if (qL <= L && R <= qR) {
      setv[o] = v;
    } else {
      if (setv[o] != INF) {
        setv[lc] = setv[rc] = setv[o];
        setv[o] = INF;
      }
      int M = L + (R - L) / 2;
      if (qL <= M)
        update(lc, L, M);
      else
        maintain(lc, L, M);
      if (M < qR)
        update(rc, M + 1, R);
      else
        maintain(rc, M + 1, R);
    }
    maintain(o, L, R);
  }
  void maintain(int o, int L, int R) {
    int lc = o << 1, rc = o << 1 | 1;
    if (R > L) {
      sumv[o] = sumv[lc] | sumv[rc];
    }
    if (setv[o] != INF) {
      sumv[o] = setv[o];
    }
  }
  long long Inquire(int L, int R) {
    qL = L;
    qR = R;
    _sum = 0;
    query(1, 1, N);
    return _sum;
  }
  void query(int o, int L, int R) {
    if (setv[o] != INF) {
      _sum |= setv[o];
    } else if (qL <= L && R <= qR) {
      _sum |= sumv[o];
    } else {
      int M = L + (R - L) / 2;
      if (qL <= M) query(o << 1, L, M);
      if (M < qR) query(o << 1 | 1, M + 1, R);
    }
  }
};
SegmentTree<long long> seg;
int color[N];
vector<int> G[N];
pair<int, int> s[N];
int setnum(int base, int r, int u) {
  int last = base;
  for (int i = 0; i < G[u].size(); i++)
    if (G[u][i] != r) {
      last = setnum(last, u, G[u][i]);
    }
  s[u] = pair<int, int>(base + 1, last + 1);
  return last + 1;
}
int main() {
  int n, m;
  while (scanf("%d%d", &n, &m) > 0) {
    for (int i = 1; i <= n; i++) {
      G[i].clear();
      scanf("%d", color + i);
    }
    for (int i = 1; i < n; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      G[u].push_back(v);
      G[v].push_back(u);
    }
    setnum(0, 0, 1);
    seg.Init(s[1].second);
    for (int i = 1; i <= n; i++)
      seg.Set(s[i].second, s[i].second, 1LL << color[i]);
    while (m--) {
      int t, v, c;
      scanf("%d%d", &t, &v);
      if (t < 2) {
        scanf("%d", &c);
        seg.Set(s[v].first, s[v].second, 1LL << c);
      } else {
        long long x = seg.Inquire(s[v].first, s[v].second), y = 0;
        for (int i = 1; i <= M; i++)
          if ((1LL << i) & x) y++;
        cout << y << endl;
      }
    }
  }
  return 0;
}
