#include <bits/stdc++.h>
using namespace std;
int n, Mod, phi;
int fpow(int a, int b) {
  int ans = 1, t = a;
  while (b) {
    if (b & 1) ans = 1ll * ans * t % Mod;
    t = 1ll * t * t % Mod;
    b >>= 1;
  }
  return ans;
}
int Inv(int a) { return fpow(a, phi - 1); }
int d[12], N;
struct Val {
  int cnt[12], x;
  int val;
  Val(int num = 1) {
    if (Mod) {
      val = num % Mod;
      memset(cnt, 0, sizeof(cnt));
      for (int i = 1; i <= N; i++)
        while (num % d[i] == 0) {
          num /= d[i];
          cnt[i]++;
        }
      x = num % Mod;
    }
  }
  int calc() {
    int res = x;
    for (int i = 1; i <= N; i++) res = 1ll * res * fpow(d[i], cnt[i]) % Mod;
    return val = res;
  }
};
Val operator*(const Val& a, const Val& b) {
  Val ans;
  ans.x = 1ll * a.x * b.x % Mod;
  for (int i = 1; i <= N; i++) ans.cnt[i] = a.cnt[i] + b.cnt[i];
  ans.val = 1ll * a.val * b.val % Mod;
  return ans;
}
Val operator/(const Val& a, const Val& b) {
  Val ans;
  ans.x = 1ll * a.x * Inv(b.x) % Mod;
  for (int i = 1; i <= N; i++) ans.cnt[i] = a.cnt[i] - b.cnt[i];
  ans.calc();
  return ans;
}
Val mul[400010];
int sum[400010];
void update(int root) {
  sum[root] = (sum[root << 1] + sum[root << 1 | 1]) % Mod;
  return;
}
void push(int root, Val x) {
  mul[root] = mul[root] * x;
  sum[root] = 1ll * sum[root] * x.val % Mod;
  return;
}
void pushdown(int root) {
  push(root << 1, mul[root]);
  push(root << 1 | 1, mul[root]);
  mul[root] = Val();
  return;
}
int a[100010];
void build(int root, int l, int r) {
  mul[root] = Val();
  if (l == r) {
    mul[root] = Val(a[l]);
    sum[root] = mul[root].val;
    return;
  }
  int mid = (l + r) >> 1;
  build(root << 1, l, mid);
  build(root << 1 | 1, mid + 1, r);
  update(root);
  return;
}
void Mul(int root, int l, int r, int x, int y, Val v) {
  if (x <= l && r <= y) {
    push(root, v);
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(root);
  if (x <= mid) Mul(root << 1, l, mid, x, y, v);
  if (y > mid) Mul(root << 1 | 1, mid + 1, r, x, y, v);
  update(root);
  return;
}
void Div(int root, int l, int r, int x, Val v) {
  if (l == r) {
    mul[root] = mul[root] / v;
    sum[root] = mul[root].val;
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(root);
  if (x <= mid)
    Div(root << 1, l, mid, x, v);
  else
    Div(root << 1 | 1, mid + 1, r, x, v);
  update(root);
  return;
}
int query(int root, int l, int r, int x, int y) {
  if (x <= l && r <= y) return sum[root];
  int mid = (l + r) >> 1, ans = 0;
  pushdown(root);
  if (x <= mid) ans = (ans + query(root << 1, l, mid, x, y)) % Mod;
  if (y > mid) ans = (ans + query(root << 1 | 1, mid + 1, r, x, y)) % Mod;
  return ans;
}
int main() {
  scanf("%d %d", &n, &Mod);
  phi = Mod;
  int t = Mod;
  for (int i = 2; i * i <= t; i++)
    if (t % i == 0) {
      d[++N] = i;
      phi = phi / i * (i - 1);
      while (t % i == 0) t /= i;
    }
  if (t > 1) {
    phi = phi / t * (t - 1);
    d[++N] = t;
  }
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  build(1, 1, n);
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int l, r, x;
      scanf("%d %d %d", &l, &r, &x);
      Mul(1, 1, n, l, r, Val(x));
    } else if (op == 2) {
      int p, x;
      scanf("%d %d", &p, &x);
      Div(1, 1, n, p, Val(x));
    } else {
      int l, r;
      scanf("%d %d", &l, &r);
      printf("%d\n", query(1, 1, n, l, r));
    }
  }
  return 0;
}
