#include <bits/stdc++.h>
using namespace std;
template <class t>
class STL {
  vector<long long> arr, st, lazy;
  int n;
  void build(int u, int i, int j) {
    if (i == j) {
      st[u] = arr[i];
      return;
    }
    int m = (i + j) / 2, l = u * 2 + 1, r = u * 2 + 2;
    build(l, i, m);
    build(r, m + 1, j);
    st[u] = t::op(st[l], st[r]);
  }
  void propagate(int u, int i, int j, long long x) {
    st[u] = t::lazy_op(i, j, x);
    if (i != j) {
      lazy[u * 2 + 1] = x;
      lazy[u * 2 + 2] = x;
    }
    lazy[u] = 0;
  }
  long long query(int a, int b, int u, int i, int j) {
    if (j < a or b < i) return t::neutro;
    int m = (i + j) / 2, l = u * 2 + 1, r = u * 2 + 2;
    if (lazy[u]) propagate(u, i, j, lazy[u]);
    if (a <= i and j <= b) return st[u];
    long long x = query(a, b, l, i, m);
    long long y = query(a, b, r, m + 1, j);
    return t::op(x, y);
  }
  void update(int a, int b, long long value, int u, int i, int j) {
    int m = (i + j) / 2, l = u * 2 + 1, r = u * 2 + 2;
    if (lazy[u]) propagate(u, i, j, lazy[u]);
    if (a <= i and j <= b)
      propagate(u, i, j, value);
    else if (j < a or b < i)
      return;
    else {
      update(a, b, value, l, i, m);
      update(a, b, value, r, m + 1, j);
      st[u] = t::op(st[l], st[r]);
    }
  }

 public:
  STL(vector<long long> &v) {
    arr = v;
    n = v.size();
    st.resize(n * 4 + 5);
    lazy.assign(n * 4 + 5, 0);
    build(0, 0, n - 1);
  }
  long long query(int a, int b) { return query(a, b, 0, 0, n - 1); }
  void update(int a, int b, long long value) {
    update(a, b, value, 0, 0, n - 1);
  }
};
struct RlQ {
  static long long const neutro = 0;
  static long long op(long long x, long long y) { return (x | y); }
  static long long lazy_op(int i, int j, long long x) { return x; }
};
int n, m, a, b, t, v, c, turn;
vector<long long> colors;
vector<bool> visited;
vector<vector<int> > g;
vector<long long> order;
vector<pair<int, int> > ranges;
void dfs(int u) {
  visited[u] = true;
  for (int v : g[u]) {
    if (!visited[v]) {
      order.push_back(colors[v]);
      ranges[v].first = turn;
      turn++;
      dfs(v);
      ranges[v].second = turn - 1;
    }
  }
}
int count(long long m) {
  int count = 0;
  for (long long i = 0; i < 60; i++)
    if (((long long)1 << i) & m) count++;
  return count;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  colors.resize(n);
  g.resize(n);
  visited.assign(n, false);
  ranges.resize(n);
  turn = 0;
  for (int i = 0; i < (int)n; i++) {
    cin >> c;
    colors[i] = (long long)1 << (c - 1);
  }
  for (int i = 0; i < (int)n - 1; i++) {
    cin >> a >> b;
    g[a - 1].push_back(b - 1);
    g[b - 1].push_back(a - 1);
  }
  order.push_back(colors[0]);
  ranges[0].first = turn;
  turn++;
  dfs(0);
  ranges[0].second = turn - 1;
  STL<RlQ> st(order);
  for (int i = 0; i < (int)m; i++) {
    cin >> t;
    if (t == 1) {
      cin >> v >> c;
      st.update(ranges[v - 1].first, ranges[v - 1].second,
                (long long)1 << (c - 1));
    } else {
      cin >> v;
      cout << count(st.query(ranges[v - 1].first, ranges[v - 1].second))
           << '\n';
    }
  }
}
