#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int MOD, PHI;
const int MXN = 1e5 + 5;
int add(int x, int y) { return (x += y) < MOD ? x : x - MOD; }
int sub(int x, int y) { return (x -= y) >= 00 ? x : x + MOD; }
int mul(int x, int y) { return (ll)x * y % MOD; }
int pwr(int x, int p) {
  if (p == 0) return 1;
  if (p % 2) return mul(x, pwr(x, p - 1));
  return pwr(mul(x, x), p / 2);
}
vector<int> primes;
struct node {
  int sum = 0;
  int mul1 = 1;
  int mul2 = 1;
  int pw[10] = {};
  node() {}
  node(int num) : node() {
    sum = mul1 = num % MOD;
    for (int i = 0; i < (int)primes.size(); ++i) {
      while (num % primes[i] == 0) {
        pw[i]++;
        num /= primes[i];
      }
    }
    mul2 = num % MOD;
  }
  void apply(node &n) {
    sum = mul(sum, n.mul1);
    mul1 = mul(mul1, n.mul1);
    mul2 = mul(mul2, n.mul2);
    for (int i = 0; i < (int)primes.size(); ++i) {
      pw[i] += n.pw[i];
    }
  }
} t[2 << 17];
void propagate(int x) {
  t[2 * x + 1].apply(t[x]);
  t[2 * x + 2].apply(t[x]);
  memset(t[x].pw, 0, sizeof t[x].pw);
  t[x].mul1 = t[x].mul2 = 1;
}
void build(int lo, int hi, int x = 0) {
  if (lo + 1 == hi) {
    int num;
    cin >> num;
    t[x] = num;
    return;
  }
  int mid = (lo + hi) / 2;
  build(lo, mid, 2 * x + 1);
  build(mid, hi, 2 * x + 2);
  t[x].sum = add(t[2 * x + 1].sum, t[2 * x + 2].sum);
}
void mult(int l, int r, node &n, int lo, int hi, int x = 0) {
  if (l <= lo && hi <= r) return t[x].apply(n);
  propagate(x);
  int mid = (lo + hi) / 2;
  if (l < mid) mult(l, r, n, lo, mid, 2 * x + 1);
  if (mid < r) mult(l, r, n, mid, hi, 2 * x + 2);
  t[x].sum = add(t[2 * x + 1].sum, t[2 * x + 2].sum);
}
void divide(int p, node &n, int lo, int hi, int x = 0) {
  if (lo + 1 == hi) {
    t[x].sum = t[x].mul2 = mul(t[x].mul2, pwr(n.mul2, PHI - 1));
    for (int i = 0; i < (int)primes.size(); ++i) {
      t[x].pw[i] -= n.pw[i];
      t[x].sum = mul(t[x].sum, pwr(primes[i], t[x].pw[i]));
    }
    return;
  }
  propagate(x);
  int mid = (lo + hi) / 2;
  if (p < mid) divide(p, n, lo, mid, 2 * x + 1);
  if (mid <= p) divide(p, n, mid, hi, 2 * x + 2);
  t[x].sum = add(t[2 * x + 1].sum, t[2 * x + 2].sum);
}
int query(int l, int r, int lo, int hi, int x = 0) {
  if (l <= lo && hi <= r) return t[x].sum;
  int ret = 0;
  propagate(x);
  int mid = (lo + hi) / 2;
  if (l < mid) ret = add(ret, query(l, r, lo, mid, 2 * x + 1));
  if (mid < r) ret = add(ret, query(l, r, mid, hi, 2 * x + 2));
  return ret;
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  int n;
  cin >> n >> MOD;
  int tmp = PHI = MOD;
  for (int i = 2; i * i <= MOD; ++i) {
    if (tmp % i) continue;
    while (tmp % i == 0) tmp /= i;
    primes.push_back(i);
    PHI -= PHI / i;
  }
  if (tmp > 1) {
    primes.push_back(tmp);
    PHI -= PHI / tmp;
  }
  build(0, n);
  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int t, l, r, p, x;
    cin >> t;
    if (t == 1) {
      cin >> l >> r >> x;
      node nd = x;
      mult(l - 1, r, nd, 0, n);
    } else if (t == 2) {
      cin >> p >> x;
      node nd = x;
      divide(p - 1, nd, 0, n);
    } else {
      cin >> l >> r;
      cout << query(l - 1, r, 0, n) << '\n';
    }
  }
}
