#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 100000;
const int MAXM = MAXN - 1;
const int MAXQ = 100000;
int n, MOD, nq;
int val[MAXN];
int ghead[MAXN], gnxt[2 * MAXM], gto[2 * MAXM];
int l[MAXN], r[MAXN], rval[MAXN];
int cid;
typedef struct BS2 {
  unsigned long long val[16];
  void clear() { memset(val, 0, sizeof(val)); }
  void set(int bit) { val[bit / 64] |= 1ULL << (bit % 64); }
  void merge(const BS2 &a) {
    for (int i = (0); i < (16); ++i) val[i] |= a.val[i];
  }
  void set(const BS2 &a, const BS2 &b) {
    for (int i = (0); i < (16); ++i) val[i] = a.val[i] | b.val[i];
  }
  inline unsigned long long shft(unsigned long long &a, int lft, int rgt) {
    assert(lft >= 0 && rgt >= 0);
    if (lft >= 64) return 0;
    if (rgt >= 64) return 0;
    return (a << lft) >> rgt;
  }
  void rot(int by) {
    static unsigned long long tmp[16];
    memset(tmp, 0, sizeof(tmp));
    int a = by / 64, b = by % 64, A = MOD / 64, B = MOD % 64;
    for (int i = (0); i < (A + (B != 0 ? 1 : 0)); ++i) {
      if (a == A) {
        tmp[a] |= shft(val[i], 64 + b - B, 64 - B),
            tmp[0] |= shft(val[i], 0, B - b);
        a = 0, b = b + 64 - B;
      } else if (a + 1 == A && B < b) {
        tmp[a] |= shft(val[i], b, 0), tmp[a + 1] |= shft(val[i], b - B, 64 - B),
            tmp[0] |= shft(val[i], 0, 64 + B - b);
        a = 0, b = b - B;
      } else {
        tmp[a] |= shft(val[i], b, 0), tmp[a + 1] |= shft(val[i], 0, 64 - b);
        ++a;
      }
    }
    for (int i = (0); i < (16); ++i) val[i] = tmp[i];
  }
  int cnt(const BS2 &a) {
    int ret = 0;
    for (int i = (0); i < (16); ++i) {
      unsigned long long cur = val[i] & a.val[i];
      for (int j = (0); j < (64); ++j)
        if ((cur >> j) & 1) ++ret;
    }
    return ret;
  }
  void print() {
    for (int i = (0); i < (MOD); ++i) {
      if (i != 0 && i % 8 == 0) printf(" ");
      printf("%c", ((val[i / 64] >> (i % 64)) & 1) ? 'x' : '.');
    }
    for (int i = (MOD); i < (64 * 16); ++i)
      if ((val[i / 64] >> (i % 64)) & 1) printf(" [%d]", i);
  }
} BS;
void dfs(int at, int par) {
  rval[cid] = val[at];
  l[at] = cid++;
  for (int x = ghead[at]; x != -1; x = gnxt[x])
    if (gto[x] != par) dfs(gto[x], at);
  r[at] = cid;
}
BS sval[2 * MAXN], pr;
int slazy[2 * MAXN];
void sinit() {
  memset(sval, 0, sizeof(sval));
  memset(slazy, 0, sizeof(slazy));
  for (int i = (0); i < (n); ++i) sval[n + l[i]].set(val[i] % MOD);
  for (int i = n - 1; i >= 1; --i) sval[i].set(sval[i << 1], sval[i << 1 | 1]);
}
void sinc(int idx, int by) {
  if ((slazy[idx] += by) >= MOD) slazy[idx] -= MOD;
}
void spushone(int idx) {
  if (slazy[idx] == 0) return;
  sval[idx].rot(slazy[idx]);
  if (idx < n) {
    sinc(idx << 1, slazy[idx]);
    sinc(idx << 1 | 1, slazy[idx]);
  }
  slazy[idx] = 0;
}
void spush(int idx) {
  idx += n;
  int k = 0;
  while ((idx >> k) >= 2) ++k;
  for (; k >= 0; --k) {
    int cidx = idx >> k;
    spushone(cidx);
  }
}
void sbuild(int idx) {
  for (idx += n, idx >>= 1; idx >= 1; idx >>= 1) {
    spushone(idx << 1);
    spushone(idx << 1 | 1);
    sval[idx].set(sval[idx << 1], sval[idx << 1 | 1]);
  }
}
void _smod(int lidx, int ridx, int by) {
  for (lidx += n, ridx += n; lidx < ridx; lidx >>= 1, ridx >>= 1) {
    if (lidx & 1) sinc(lidx, by), ++lidx;
    if (ridx & 1) --ridx, sinc(ridx, by);
  }
}
void smod(int lidx, int ridx, int by) {
  spush(lidx);
  spush(ridx - 1);
  _smod(lidx, ridx, by);
  sbuild(lidx);
  sbuild(ridx - 1);
}
void sget(int lidx, int ridx, BS &ret) {
  spush(lidx);
  spush(ridx - 1);
  for (lidx += n, ridx += n; lidx < ridx; lidx >>= 1, ridx >>= 1) {
    if (lidx & 1) spushone(lidx), ret.merge(sval[lidx]), lidx++;
    if (ridx & 1) --ridx, spushone(ridx), ret.merge(sval[ridx]);
  }
}
int qtype[MAXQ], qx[MAXQ], qby[MAXQ];
int ret[MAXQ], nret;
void input() {
  scanf("%d%d", &n, &MOD);
  for (int i = (0); i < (n); ++i) scanf("%d", &val[i]);
  for (int i = (0); i < (n); ++i) ghead[i] = -1;
  for (int i = (0); i < (n - 1); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    gnxt[2 * i + 0] = ghead[a];
    ghead[a] = 2 * i + 0;
    gto[2 * i + 0] = b;
    gnxt[2 * i + 1] = ghead[b];
    ghead[b] = 2 * i + 1;
    gto[2 * i + 1] = a;
  }
  scanf("%d", &nq);
  for (int i = (0); i < (nq); ++i) {
    scanf("%d", &qtype[i]);
    if (qtype[i] == 1) scanf("%d%d", &qx[i], &qby[i]), --qx[i];
    if (qtype[i] == 2) scanf("%d", &qx[i]), --qx[i];
  }
}
void solve() {
  cid = 0;
  dfs(0, -1);
  memset(sval, 0, sizeof(sval));
  sinit();
  nret = 0;
  assert(cid == n);
  pr.clear();
  for (int i = (2); i < (MOD); ++i) {
    bool ok = true;
    for (int j = 2; j * j <= i; ++j)
      if (i % j == 0) ok = false;
    if (ok) pr.set(i);
  }
  for (int i = (0); i < (nq); ++i) {
    if (qtype[i] == 1) {
      smod(l[qx[i]], r[qx[i]], qby[i] % MOD);
    }
    if (qtype[i] == 2) {
      BS res;
      memset(&res, 0, sizeof(res));
      sget(l[qx[i]], r[qx[i]], res);
      ret[nret++] = res.cnt(pr);
    }
  }
}
void run() {
  input();
  solve();
  for (int i = (0); i < (nret); ++i) printf("%d\n", ret[i]);
}
int main() {
  run();
  return 0;
}
