#define int long long
using namespace std;
struct node
{
int val,muladd,plusadd;
}tree[100005];
int a[100005],MOD;
void build(int num,int l,int r)
{
tree[num].plusadd=0;
tree[num].muladd=1;
if(l==r)tree[num].val=a[l];
else
{
int mid=l+r>>1;
build(num*2,l,mid);
build(num*2+1,mid+1,r);
tree[num].val=tree[num*2].val+tree[num*2+1].val;
}
tree[num].val%=MOD;
}
void push_down(int num,int l,int r)
{
int mid=l+r>>1;
tree[num*2].val=(tree[num*2].val*tree[num].muladd+tree[num].plusadd*(mid-l+1))%MOD;
tree[num*2+1].val=(tree[num*2+1].val*tree[num].muladd+tree[num].plusadd*(r-mid))%MOD;
tree[num*2].muladd=(tree[num*2].muladd*tree[num].muladd)%MOD;
tree[num*2+1].muladd=(tree[num*2+1].muladd*tree[num].muladd)%MOD;
tree[num*2].plusadd=(tree[num*2].plusadd*tree[num].muladd+tree[num].plusadd)%MOD;
tree[num*2+1].plusadd=(tree[num*2+1].plusadd*tree[num].muladd+tree[num].plusadd)%MOD;
tree[num].plusadd=0;
tree[num].muladd=1;
}
void upd_plus(int num,int rangel,int ranger,int l,int r,int k)
{
if(r<rangel||l>ranger)return;
if(l<=rangel&&r>=ranger)
{
tree[num].val=(tree[num].plusadd+k*(ranger-rangel+1))%MOD;
tree[num].plusadd=(tree[num].plusadd+k)%MOD;
return;
}
push_down(num,rangel,ranger);
int mid=rangel+ranger>>1;
upd_plus(num*2,rangel,mid,l,r,k);
upd_plus(num*2+1,mid+1,ranger,l,r,k);
tree[num].val=(tree[num*2].val+tree[num*2+1].val)%MOD;
}
void upd_mul(int num,int rangel,int ranger,int l,int r,int k)
{
if(r<rangel||l>ranger)return;
if(l<=rangel&&r>=ranger)
{
tree[num].val=tree[num].val*k%MOD;
tree[num].plusadd=tree[num].plusadd*k%MOD;
tree[num].muladd=tree[num].muladd*k%MOD;
return;
}
push_down(num,rangel,ranger);
int mid=rangel+ranger>>1;
upd_mul(num*2,rangel,mid,l,r,k);
upd_mul(num*2+1,mid+1,ranger,l,r,k);
tree[num].val=(tree[num*2].val+tree[num*2+1].val)%MOD;
}
int query(int num,int rangel,int ranger,int l,int r)
{
if(r<rangel||l>ranger)return 0;
if(l<=rangel&&r>=ranger)return tree[num].val;
push_down(num,rangel,ranger);
int mid=rangel+ranger>>1;
return (query(num*2,rangel,mid,l,r)+query(num*2+1,mid+1,ranger,l,r))%MOD;
}
signed main()
{
int n,m;
cin>>n>>m>>MOD;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++)
{
int op;
cin>>op;
int temp1,temp2,temp3;
if(op==1)
{
cin>>temp1>>temp2>>temp3;
upd_mul(1,1,n,temp1,temp2,temp3);
}
else if(op==2)
{
cin>>temp1>>temp2>>temp3;
upd_plus(1,1,n,temp1,temp2,temp3);
}
else if(op==3)
{
cin>>temp1>>temp2;
cout<<query(1,1,n,temp1,temp2)<<endl;
}
cout<<"QUERY:"<<query(1,1,n,1,n)<<endl;
}
return 0;
}