#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0;
  bool f = 0;
  char c = getchar();
  for (; c < '0' || c > '9'; c = getchar()) f = c == '-' ? 1 : 0;
  for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
  return f ? -x : x;
}
const int N = 100005, M = 1005, S = (1 << 16) - 1;
int n, m, q, A[N], add[M][M], cnt[1 << 16], pr[M], pc, np[M], _l, _r, _c,
    tg[N * 4], clk, dfn[N], out[N], B[N], ll, to[N * 2], nxt[N * 2], hd[N];
unsigned int cun[64];
struct na {
  unsigned int s[32];
  inline void clear() { memset(s, 0, sizeof s); }
  inline void operator|=(const na &a) {
    for (int i = 0; i < 32; i++) s[i] |= a.s[i];
  }
  inline void operator&=(const na &a) {
    for (int i = 0; i < 32; i++) s[i] &= a.s[i];
  }
  inline int count() {
    int rec = 0;
    for (int i = 0; i < 32; i++) rec += cnt[s[i] & S] + cnt[s[i] >> 16];
    return rec;
  }
  inline void move(int x) {
    memset(cun, 0, sizeof cun);
    int a = x >> 5, b = x & 31, t;
    for (int i = 0; i < 32; i++)
      cun[i + a] |= (s[i] << b), cun[i + a + 1] |= (b ? (s[i] >> (32 - b)) : 0);
    a = m >> 5, b = m & 31;
    cun[0] |= (t = (cun[a] >> b)), cun[a] ^= (t << b);
    for (int i = a + 1; i < a + 32; i++)
      cun[i - a - 1] |= (b ? (cun[i] << 32 - b) : 0),
          cun[i - a] |= (cun[i] >> b), cun[i] = 0;
    memcpy(s, cun, sizeof s);
  }
  inline void ins(int x) { s[x >> 5] |= (1u << (x & 31)); }
} e[N * 4], P, _a;
inline void adde() {
  int u = read(), v = read();
  to[++ll] = v, nxt[ll] = hd[u], hd[u] = ll;
  to[++ll] = u, nxt[ll] = hd[v], hd[v] = ll;
}
void dfs(int u, int f) {
  dfn[u] = ++clk, B[clk] = A[u];
  for (int i = hd[u], v; i; i = nxt[i])
    if ((v = to[i]) != f) dfs(v, u);
  out[u] = clk;
}
void build(int o, int l, int r) {
  for (int i = l; i <= r; i++) e[o].ins(B[i]);
  if (l == r) return;
  int mid = l + r >> 1;
  build(o << 1, l, mid);
  build(o << 1 | 1, mid + 1, r);
}
inline void pd(int o) {
  if (tg[o]) {
    tg[o << 1] = add[tg[o << 1]][tg[o]],
            tg[o << 1 | 1] = add[tg[o << 1 | 1]][tg[o]];
    e[o << 1].move(tg[o]), e[o << 1 | 1].move(tg[o]);
    tg[o] = 0;
  }
}
void update(int o, int l, int r) {
  if (_l <= l && r <= _r) {
    e[o].move(_c), tg[o] = add[tg[o]][_c];
    return;
  }
  pd(o);
  int mid = l + r >> 1;
  if (_l <= mid) update(o << 1, l, mid);
  if (_r > mid) update(o << 1 | 1, mid + 1, r);
  e[o] = e[o << 1], e[o] |= e[o << 1 | 1];
}
void query(int o, int l, int r) {
  if (_l <= l && r <= _r) {
    _a |= e[o];
    return;
  }
  pd(o);
  int mid = l + r >> 1;
  if (_l <= mid) query(o << 1, l, mid);
  if (_r > mid) query(o << 1 | 1, mid + 1, r);
}
int main() {
  n = read(), m = read();
  for (int i = 2; i < m; i++) {
    if (!np[i]) pr[++pc] = i, P.ins(i);
    for (int j = 1; j <= pc && i * pr[j] < m; j++) {
      np[i * pr[j]] = pr[j];
      if (i % pr[j] == 0) break;
    }
  }
  for (int i = 1; i < S; i++) cnt[i] = cnt[i >> 1] + (i & 1);
  for (int i = 1; i <= pc; i++)
    for (int i = 0; i < m; i++)
      for (int j = 0; j < m; j++) add[i][j] = (i + j) % m;
  for (int i = 1; i <= n; i++) A[i] = read() % m;
  for (int i = 1; i < n; i++) adde();
  dfs(1, 0);
  build(1, 1, n);
  q = read();
  for (int i = 1, op, u; i <= q; i++) {
    op = read(), u = read();
    _l = dfn[u], _r = out[u];
    if (op == 1)
      _c = read() % m, update(1, 1, n);
    else
      _a.clear(), query(1, 1, n), _a &= P, printf("%d\n", _a.count());
  }
  return 0;
}
