#include <cmath> #include <cstdio> #include <cstring> #include <iostream> using namespace std;
  typedef long long ll; const int N = 5e5+15;
  struct type {     int cnt[10];     ll mul;     type()     {         memset(cnt, 0, sizeof(cnt));         mul = 1;     } };
  namespace tree {     struct node {         int l, r;         ll sum;         type lz;     } a[N*4];     ll val[N];     void build(int l, int r, int i = 1);     void modify(int ql, int qr, type &tmp, int i = 1);     void div(int pos, type &tmp, int i = 1);     ll query(int ql, int qr ,int i = 1); } using namespace tree;
  int n, P, q; int data[N]; int p[10], tot; int pow_v[10][N*20];
  void divide(); void prework_pow(); ll get_pow(int i, int j);
  signed main() {     cin >> n >> P;     for(int i = 1; i <= n; i++)         cin >> data[i];     divide();     prework_pow();     tree::build(1, n);     cin >> q;     int opt, l, r, x;     for(int i = 1; i <= q; i++)     {         cin >> opt;         if(opt == 1)         {             cin >> l >> r >> x;             type tmp;             for(int j = 1; j <= tot; j++)                 while(x%p[j] == 0)                     x /= p[j], tmp.cnt[j]++;             tmp.mul = x;             tree::modify(l, r, tmp);         }         else if(opt == 2)         {             cin >> l >> x;             type tmp;             for(int j = 1; j <= tot; j++)                 while(x%p[j] == 0)                     x /= p[j], tmp.cnt[j]++;             tmp.mul = x;             tree::div(l, tmp);         }         else if(opt == 3)         {             cin >> l >> r;             cout << tree::query(l, r) << "\n";         }     } }
  void divide() {     int tmp = P;     for(int i = 2; (ll)i*i <= tmp; i++)     {         if(tmp%i == 0)         {             p[++tot] = i;             while(tmp%i == 0) tmp /= i;         }     }     if(tmp != 1) p[++tot] = tmp; } void prework_pow() {     for(int i = 1; i <= tot; i++)     {         pow_v[i][0] = 1;         for(int j = 1; j < N*20; j++)             pow_v[i][j] = (ll)pow_v[i][j-1]*p[i]%P;     } } ll get_pow(int i, int j) {
 
 
 
      return pow_v[i][j]; }
  namespace tree {     #define ls (i<<1)     #define rs (i<<1|1)     ll exgcd(ll a, ll b, ll &x, ll &y)     {         if(!b) return x = 1, y = 0, b;         ll d = exgcd(b, a%b, y, x);         y -= (a/b)*x;         return d;     }     ll inv(ll a, ll p)     {         ll x, y;         exgcd(a, p, x, y);         x = (x%p+p)%p;         return x;     }     void modify(node &i, type &tmp)     {         (i.sum *= tmp.mul) %= P;         (i.lz.mul *= tmp.mul) %= P;         if(i.l == i.r)             (val[i.l] *= tmp.mul) %= P;         for(int j = 1; j <= tot; j++)         {             i.lz.cnt[j] += tmp.cnt[j];             (i.sum *= get_pow(j,tmp.cnt[j])) %= P;         }     }     void push_up(int i)     {         a[i].sum = (a[ls].sum + a[rs].sum)%P;     }     void push_down(int i)     {         modify(a[ls], a[i].lz);         modify(a[rs], a[i].lz);         memset(a[i].lz.cnt, 0, sizeof(a[i].lz.cnt));         a[i].lz.mul = 1;     }     void build(int l, int r, int i)     {         a[i].l = l, a[i].r = r;         if(l == r)         {             int x = data[l];             for(int j = 1; j <= tot; j++)             {                 int cnt = 0;                 while(x%p[j] == 0)                     x /= p[j], cnt++;                 a[i].lz.cnt[j] = cnt;             }             val[l] = x;             a[i].sum = data[l]%P;             return void();         }         int mid = (l+r)>>1;         build(l, mid, ls);         build(mid+1, r, rs);         push_up(i);     }     void modify(int ql, int qr, type &tmp, int i)     {         if(ql <= a[i].l && a[i].r <= qr)             return modify(a[i], tmp);         push_down(i);         if(ql <= a[ls].r) modify(ql, qr, tmp, ls);         if(qr >= a[rs].l) modify(ql, qr, tmp, rs);         push_up(i);     }     void div(int pos, type &tmp, int i)     {         if(a[i].l == a[i].r)         {             (val[a[i].l] *= inv(tmp.mul, P)) %= P;             a[i].sum = val[a[i].l];             for(int j = 1; j <= tot; j++)             {                 a[i].lz.cnt[j] -= tmp.cnt[j];                 (a[i].sum *= get_pow(j,a[i].lz.cnt[j])) %= P;             }             return void();         }         push_down(i);         if(pos <= a[ls].r) div(pos, tmp, ls);         if(pos >= a[rs].l) div(pos, tmp, rs);         push_up(i);     }     ll query(int ql, int qr, int i)     {         if(ql <= a[i].l and a[i].r <= qr)             return a[i].sum;         push_down(i); ll ans = 0;         if(ql <= a[ls].r) ans += query(ql, qr, ls);         if(qr >= a[rs].l) ans += query(ql, qr, rs);         return ans%P;     } }
   |