#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const int MAXN = 100001;
const int MAXP = 2000001;
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int mod;
vector<int> primes;
int num[MAXN];
int inv[MAXN];
int pot[10][MAXP];
long long int modularInverse(long long int a, long long int m) {
  long long int r0 = a, r1 = m, ri, s0 = 1, s1 = 0, si;
  while (r1) {
    si = s0 - s1 * (r0 / r1), s0 = s1, s1 = si;
    ri = r0 % r1, r0 = r1, r1 = ri;
  }
  if (r0 < 0) s0 *= -1;
  if (s0 < 0) s0 += m;
  return s0;
}
struct Segment {
  int l, r;
  long long int val, sum;
  vector<int> total;
  Segment *left, *right;
  Segment() {}
  Segment(int a, int b, int c)
      : l(a), r(b), total(c, 0), left(NULL), right(NULL), val(1), sum(1) {}
  void build() {
    if (l == r) {
      sum = num[l] % mod;
      for (int i = 0; i < primes.size(); i++)
        while (num[l] % primes[i] == 0) num[l] /= primes[i], total[i]++;
      val = num[l] % mod;
      return;
    }
    int m = (l + r) / 2;
    (left = new Segment(l, m, total.size()))->build();
    (right = new Segment(m + 1, r, total.size()))->build();
    sum = (left->sum + right->sum) % mod;
  }
  long long int getSum() {
    long long int s = val;
    for (int i = 0; i < total.size(); i++) s = s * pot[i][total[i]] % mod;
    return s;
  }
  void push() {
    if (val != 1) {
      left->val = left->val * val % mod;
      left->sum = left->sum * val % mod;
      right->val = right->val * val % mod;
      right->sum = right->sum * val % mod;
      val = 1;
    }
    for (int i = 0; i < total.size(); i++) {
      if (total[i] != 0) {
        left->total[i] += total[i];
        left->sum = left->sum * pot[i][total[i]] % mod;
        right->total[i] += total[i];
        right->sum = right->sum * pot[i][total[i]] % mod;
        total[i] = 0;
      }
    }
  }
  void multiply(int a, int b, int x) {
    if (b < l || a > r) return;
    if (a <= l && r <= b) {
      sum = sum * x % mod;
      for (int i = 0; i < primes.size(); i++)
        while (x % primes[i] == 0) x /= primes[i], total[i]++;
      val = val * x % mod;
      return;
    }
    push();
    left->multiply(a, b, x);
    right->multiply(a, b, x);
    sum = (left->sum + right->sum) % mod;
  }
  void divide(int a, int x) {
    if (a < l || a > r) return;
    if (a <= l && r <= a) {
      for (int i = 0; i < primes.size(); i++)
        while (x % primes[i] == 0) x /= primes[i], total[i]--;
      val = val * inv[x] % mod;
      sum = getSum();
      return;
    }
    push();
    left->divide(a, x);
    right->divide(a, x);
    sum = (left->sum + right->sum) % mod;
  }
  int query(int a, int b) {
    if (b < l || a > r) return 0;
    if (a <= l && r <= b) return sum;
    push();
    return (left->query(a, b) + right->query(a, b)) % mod;
  }
};
Segment *tree;
void decompose(int m) {
  for (long long int i = 2; i * i <= m; i++) {
    if (m % i == 0) primes.push_back(i);
    while (m % i == 0) m /= i;
  }
  if (m > 1) primes.push_back(m);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, op, l, r, x, q;
  cin >> n >> mod;
  for (int i = 0; i < MAXN; i++)
    if (i) inv[i] = modularInverse(i, mod);
  decompose(mod);
  for (int i = 0; i < primes.size(); i++) {
    long long int p = 1;
    for (int j = 0; j < MAXP; j++) {
      pot[i][j] = p;
      p = p * primes[i] % mod;
    }
  }
  for (int i = 0; i < n; i++) cin >> num[i];
  (tree = new Segment(0, n - 1, primes.size()))->build();
  cin >> q;
  while (q--) {
    cin >> op >> l >> r;
    if (op == 1) {
      cin >> x;
      l--, r--;
      tree->multiply(l, r, x);
    } else if (op == 2) {
      l--;
      tree->divide(l, r);
    } else {
      l--, r--;
      cout << tree->query(l, r) << '\n';
    }
  }
  return 0;
}
