1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<ctime> 5 #include<iostream> 6 #include<algorithm> 7 #include<queue> 8 #include<set> 9 #define inf (0x7fffffff) 10 #define l(a) ((a)<<1) 11 #define r(a) ((a)<<1|1) 12 #define b(a) (1<<(a)) 13 #define rep(i,a,b) for(int i=a;i<=(b);i++) 14 #define clr(a) memset(a,0,sizeof(a)) 15 typedef long long ll; 16 typedef unsigned long long ull; 17 using namespace std; 18 int readint(){ 19 int t=0,f=1;char c=getchar(); 20 while(!isdigit(c)){ 21 if(c=='-') f=-1; 22 c=getchar(); 23 } 24 while(isdigit(c)){ 25 t=(t<<3)+(t<<1)+c-'0'; 26 c=getchar(); 27 } 28 return t*f; 29 } 30 const int maxn=100009; 31 struct node{ 32 int l,r; 33 ll s,a,m; 34 }x[maxn<<2]; 35 int n,m; 36 ll mod; 37 void maintain(int t){ 38 x[t].s=(x[l(t)].s+x[r(t)].s)%mod; 39 } 40 void pushdown(int t){ 41 if(x[t].l==x[t].r){ 42 x[t].a=0;x[t].m=1;return; 43 } 44 if(x[t].m!=1){ 45 x[l(t)].s=x[l(t)].s*x[t].m%mod; 46 x[r(t)].s=x[r(t)].s*x[t].m%mod; 47 x[l(t)].m=x[l(t)].m*x[t].m%mod;x[r(t)].m=x[r(t)].m*x[t].m%mod; 48 x[l(t)].a=x[l(t)].a*x[t].m%mod;x[r(t)].a=x[r(t)].a*x[t].m%mod; 49 x[t].m=1; 50 } 51 if(x[t].a){ 52 x[l(t)].s=(x[l(t)].s+(x[l(t)].r-x[l(t)].l+1)*x[t].a)%mod; 53 x[r(t)].s=(x[r(t)].s+(x[r(t)].r-x[r(t)].l+1)*x[t].a)%mod; 54 x[l(t)].a=(x[l(t)].a+x[t].a)%mod;x[r(t)].a=(x[r(t)].a+x[t].a)%mod; 55 x[t].a=0; 56 } 57 } 58 ll del; 59 void add(int t,int l,int r){ 60 pushdown(t); 61 if(x[t].l==l&&x[t].r==r){ 62 x[t].s=(x[t].s+(x[t].r-x[t].l+1)*del)%mod; 63 x[t].a=(x[t].a+del)%mod; 64 return; 65 } 66 int mid=(x[t].l+x[t].r)>>1; 67 if(l>mid) add(r(t),l,r); 68 else if(r<=mid) add(l(t),l,r); 69 else{ 70 add(l(t),l,mid); 71 add(r(t),mid+1,r); 72 } 73 maintain(t); 74 } 75 void mul(int t,int l,int r){ 76 pushdown(t); 77 if(x[t].l==l&&x[t].r==r){ 78 x[t].s=(x[t].s*del)%mod; 79 x[t].m=x[t].m*del%mod; 80 x[t].a=x[t].a*del%mod; 81 return; 82 } 83 int mid=(x[t].l+x[t].r)>>1; 84 if(l>mid) mul(r(t),l,r); 85 else if(r<=mid) mul(l(t),l,r); 86 else{ 87 mul(l(t),l,mid); 88 mul(r(t),mid+1,r); 89 } 90 maintain(t); 91 } 92 ll qury(int t,int l,int r){ 93 pushdown(t); 94 if(x[t].l==l&&x[t].r==r) return x[t].s; 95 int mid=(x[t].l+x[t].r)>>1; 96 if(l>mid) return qury(r(t),l,r)%mod; 97 if(r<=mid) return qury(l(t),l,r)%mod; 98 return (qury(l(t),l,mid)%mod+qury(r(t),mid+1,r)%mod)%mod; 99 } 100 void build(int t,int l,int r){ 101 x[t].l=l;x[t].r=r;x[t].m=1; 102 if(l==r){ 103 x[t].s=readint()%mod; 104 return; 105 } 106 int mid=(l+r)>>1; 107 build(l(t),l,mid); 108 build(r(t),mid+1,r); 109 maintain(t); 110 } 111 int main(){ 112 //freopen("#input.txt","r",stdin); 113 //freopen("#output.txt","w",stdout); 114 n=readint();m=readint();mod=readint(); 115 build(1,1,n); 116 while(m--){ 117 int opt=readint(),L=readint(),R=readint(); 118 if(opt==3) printf("%lld ",(qury(1,L,R)+mod)%mod); 119 else{ 120 del=readint()%mod; 121 if(opt==2) add(1,L,R); 122 else mul(1,L,R); 123 } 124 } 125 //fclose(stdin); 126 //fclose(stdout); 127 return 0; 128 }