#include <bits/stdc++.h>
using namespace std;
int n, m, dfn[100010], siz[100010], tim, idfn[100010], a[100010], Q;
vector<int> v[100010];
inline int add(int a, int b) {
  if ((a += b) >= m) a -= m;
  return a;
}
void dfs(int np, int fath) {
  dfn[np] = ++tim;
  idfn[tim] = np;
  siz[np] = 1;
  for (auto &x : v[np]) {
    if (x == fath) continue;
    dfs(x, np);
    siz[np] += siz[x];
  }
}
bitset<1000> bas, prm;
inline void shift(bitset<1000> &bt, int v) {
  if (!v) return;
  bt = ((bt << v) | (bt >> (m - v))) & bas;
}
class sgt {
 public:
  bitset<1000> dat[400010];
  int lzy[400010];
  void pushnow(int p, int v) {
    lzy[p] = add(lzy[p], v);
    shift(dat[p], v);
  }
  void pushdown(int p) {
    if (lzy[p]) {
      pushnow((p << 1), lzy[p]);
      pushnow(((p << 1) | 1), lzy[p]);
      lzy[p] = 0;
    }
  }
  void pushup(int p) { dat[p] = dat[(p << 1)] | dat[((p << 1) | 1)]; }
  void build(int p, int l, int r) {
    for (int i = l; i <= r; i++) dat[p].set(a[idfn[i]]);
    if (l == r) return;
    int mid = (l + r) >> 1;
    build((p << 1), l, mid);
    build(((p << 1) | 1), mid + 1, r);
  }
  void modify(int p, int l, int r, int ml, int mr, int v) {
    if (ml <= l && r <= mr) {
      pushnow(p, v);
      return;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    if (ml <= mid) modify((p << 1), l, mid, ml, mr, v);
    if (mr > mid) modify(((p << 1) | 1), mid + 1, r, ml, mr, v);
    pushup(p);
  }
  void query(int p, int l, int r, int ql, int qr, bitset<1000> &q) {
    if (ql <= l && r <= qr) {
      q |= dat[p];
      return;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    if (ql <= mid) query((p << 1), l, mid, ql, qr, q);
    if (qr > mid) query(((p << 1) | 1), mid + 1, r, ql, qr, q);
    return;
  }
} T;
vector<int> prime;
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) bas.set(i);
  for (int i = 2; i < m; i++) prm.set(i);
  for (int i = 2; i < m; i++) {
    if (prm[i]) prime.push_back(i);
    for (int j = 0; j < prime.size() && i * prime[j] < m; j++) {
      prm[i * prime[j]] = 0;
      if ((i % prime[j]) == 0) break;
    }
  }
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i] %= m;
  for (int i = 1, ti, tj; i < n; i++) {
    scanf("%d%d", &ti, &tj);
    v[ti].push_back(tj);
    v[tj].push_back(ti);
  }
  dfs(1, 0);
  T.build(1, 1, n);
  scanf("%d", &Q);
  bitset<1000> ans;
  while (Q--) {
    int opt, x, y;
    scanf("%d%d", &opt, &x);
    if (opt == 1) {
      scanf("%d", &y);
      y %= m;
      T.modify(1, 1, n, dfn[x], dfn[x] + siz[x] - 1, y);
    } else {
      ans.reset();
      T.query(1, 1, n, dfn[x], dfn[x] + siz[x] - 1, ans);
      printf("%d\n", (ans & prm).count());
    }
  }
  return 0;
}
