#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
int n,m,q,a[maxn];
struct node{
int l,r,sum,lazy,mul;
}nd[4*maxn];
inline int lc(int p){return p<<1;}
inline int rc(int p){return p<<1|1;}
void pushup(int p){
nd[p].sum=nd[lc(p)].sum+nd[rc(p)].sum;
}
void pushdown(int p){
nd[lc(p)].sum*=nd[p].mul;
nd[rc(p)].sum*=nd[p].mul;
nd[lc(p)].sum+=nd[p].lazy*(nd[lc(p)].r-nd[lc(p)].l+1);
nd[rc(p)].sum+=nd[p].lazy*(nd[rc(p)].r-nd[rc(p)].l+1);
nd[lc(p)].mul*=nd[p].mul;
nd[rc(p)].mul*=nd[p].mul;
nd[lc(p)].lazy*=nd[p].mul;
nd[rc(p)].lazy*=nd[p].mul;
nd[lc(p)].lazy+=nd[p].lazy;
nd[rc(p)].lazy+=nd[p].lazy;
nd[p].lazy=0;nd[p].mul=1;
}
void build(int l,int r,int p){
nd[p]={l,r,a[l],0,1};
if(l==r)return;
int mid=(l+r)>>1;
build(l,mid,lc(p));
build(mid+1,r,rc(p));
pushup(p);
}
int query(int x,int y,int p){
if(x<=nd[p].l&&y>=nd[p].r){
return nd[p].sum;
}
pushdown(p);
int mid=(nd[p].l+nd[p].r)>>1;
int res=0;
if(x<=mid)res+=query(x,y,lc(p));
if(y>mid)res+=query(x,y,rc(p));
return res;
}
void modify(int x,int y,int p,int k){
if(x<=nd[p].l&&y>=nd[p].r){
nd[p].sum+=(nd[p].r-nd[p].l+1)*k;
nd[p].lazy+=k;
return;
}
pushdown(p);
int mid=(nd[p].l+nd[p].r)>>1;
if(x<=mid)modify(x,y,lc(p),k);
if(y>mid)modify(x,y,rc(p),k);
pushup(p);
}
void multi(int x,int y,int p,int k){
if(x<=nd[p].l&&y>=nd[p].r){
nd[p].sum*=k;
nd[p].lazy*=k;
nd[p].mul*=k;
return;
}
pushdown(p);
int mid=(nd[p].l+nd[p].r)>>1;
if(x<=mid)modify(x,y,lc(p),k);
if(y>mid)modify(x,y,rc(p),k);
pushup(p);
}
signed main(){
ios::sync_with_stdio(false);
cin>>n>>q>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,n,1);
for(int i=1;i<=q;i++){
int t,x,y,k;cin>>t;
if(t==1){cin>>x>>y>>k;multi(x,y,1,k);}
if(t==2){cin>>x>>y>>k;modify(x,y,1,k);}
if(t==3){cin>>x>>y;cout<<query(x,y,1)%m<<endl;}
cout<<"data:";
for(int i=1;i<=n;i++){
cout<<query(i,i,1)<<' ';
}
cout<<endl;
}
return 0;
}