#include<bits/stdc++.h>
long long n, m, a[20005], q;struct node {int l,r;long long sum,lazy,c;}tr[4 * 20005];void pushup(int u){tr[u].sum=(tr[u*2].sum+tr[u*2+1].sum)%m;}void pushdown(int u){tr[u*2].c=(tr[u*2].c*tr[u].c)%m;tr[u*2].lazy=(tr[u*2].lazy*tr[u].c+tr[u].lazy)%m;tr[u*2].sum =(tr[u].c*tr[u*2].sum+(tr[u*2].r-tr[u*2].l+1)*tr[u].lazy)%m;tr[u*2+1].c=(tr[u*2+1].c*tr[u].c)%m;tr[u*2+1].lazy=(tr[u*2+1].lazy*tr[u].c+tr[u].lazy)%m;tr[u*2+1].sum=(tr[u].c*tr[u*2+1].sum+(tr[u*2+1].r-tr[u*2+1].l+1)*tr[u].lazy)%m;tr[u].lazy=0;tr[u].c=1;}void build(int u,int l,int r){tr[u].l=l;tr[u].r=r;tr[u].c=1;if(tr[u].l==tr[u].r){tr[u].sum=a[l]%m;tr[u].lazy=0;return;}long long mid=(tr[u].l+tr[u].r)/2;build(u*2,l,mid);build(u*2+1,mid+1,r);pushup(u);}void mofity(int u,int l,int r,long long v){if(l<=tr[u].l && tr[u].r<=r){tr[u].lazy=(tr[u].lazy+v)%m;tr[u].sum=(tr[u].sum+(tr[u].r-tr[u].l+1)*v)%m;return;}pushdown(u);long long mid=(tr[u].r+tr[u].l)/2;if(l<=mid){mofity(u*2,l,r,v);}if(mid<r){mofity(u*2+1,l,r,v);}pushup(u);}void czc(int u,int l,int r,int v){if(l<=tr[u].l && tr[u].r<=r){tr[u].c=(tr[u].c*v)%m;tr[u].lazy=(tr[u].lazy*v)%m;tr[u].sum=(tr[u].sum*v)%m;return;}pushdown(u);long long mid =(tr[u].r+tr[u].l)/2;if(l<=mid){czc(u*2,l,r,v);}if(mid<r){czc(u*2+1,l,r,v);}pushup(u);}long long query(int u,int l,int r){if(l<=tr[u].l && tr[u].r<=r){return tr[u].sum%m;}pushdown(u);long long mid=(tr[u].r+tr[u].l)/2;long long ans=0;if(l<=mid)ans=query(u*2,l,r);if(mid<r) ans=(ans+query(u*2+1,l,r))%m;return ans%m;}int main(){scanf("%lld%lld%lld",&n,&q,&m);for(long long i=1;i<=n;i++){scanf("%lld", &a[i]);}build(1,1,n);while(q--){long long op,x,y,k;scanf("%lld",&op);if(op==1){scanf("%lld%lld%lld",&x,&y,&k);czc(1,x,y,k);}else if(op==3){scanf("%lld%lld", &x, &y);long long ans=query(1,x,y);printf("%lld\n",ans);}else{scanf("%lld%lld%lld",&x,&y,&k);mofity(1,x,y,k);}}return 0;}