#include<bits/stdc++.h>
#define ll long long
#define r(x) x = read()
#define mid ( (l+r)>>1 )
#define mm(x,y) (x%p)*(y%p)%p
#define pp(x,y) (x+y)%p
#define P 1e9+7
const ll N = 2*1e5;
ll n,m,p,arr[N];
ll opt,x,y,k;
struct Tree{
ll sum;
ll plz, mlz = 1;
} tr[N<<2];
inline ll read()
{
ll x = 0, f = 1;
char ch = getchar();
while(!isdigit(ch))
{
if( ch == '-' ) f = -1;
ch = getchar();
}
while(isdigit(ch))
{
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x*f;
}
inline void build(ll o,ll l,ll r)
{
if( l == r )
{
tr[o].sum = arr[l];
return;
}
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
tr[o].sum = tr[o<<1].sum + tr[o<<1|1].sum;
}
inline void pushdown(ll o,ll l,ll r)///!!!!
{
ll mlazy = tr[o].mlz, plazy = tr[o].plz;
tr[o<<1].sum = pp( mm(tr[o<<1].sum, mlazy) , mm(plazy, mid-l+1) );
tr[o<<1].mlz = mm( tr[o<<1].mlz, mlazy);
tr[o<<1].plz = pp( mm( tr[o<<1].plz, mlazy) , plazy );
tr[o<<1|1].sum = pp( mm(tr[o<<1|1].sum, mlazy) , mm(plazy, r-mid) );
tr[o<<1|1].mlz = mm( tr[o<<1|1].mlz, mlazy);
tr[o<<1|1].plz = pp( mm( tr[o<<1|1].plz, mlazy), plazy );
tr[o].mlz = 1;
tr[o].plz = 0;
}
inline void mult(ll o,ll l,ll r)
{
if(x<=l && r<=y)
{
tr[o].sum = mm(tr[o].sum, k);
tr[o].mlz = mm(tr[o].mlz, k);
tr[o].plz = mm(tr[o].plz, k);
return;
}
pushdown(o,l,r);
if( x <= mid ) mult(o<<1,l,mid);
if( y >= mid+1 ) mult(o<<1|1,mid+1,r);
tr[o].sum = pp(tr[o<<1].sum, tr[o<<1|1].sum);
}
inline void plus(ll o,ll l,ll r)///!!
{
if(x<=l && r<=y)
{
tr[o].sum = pp(tr[o].sum, mm(k, r-l+1) );
tr[o].plz = pp(tr[o].plz, k);
return;
}
pushdown(o,l,r);
if( x <= mid ) plus(o<<1,l,mid);
if( y >= mid+1 ) plus(o<<1|1,mid+1,r);
tr[o].sum = pp(tr[o<<1].sum, tr[o<<1|1].sum);
}
inline ll query(ll o,ll l,ll r)
{
if(x<=l && r<=y) return tr[o].sum;
pushdown(o,l,r);
ll tot = 0;
if( x <= mid ) tot = pp(tot, query(o<<1,l,mid) );
if( y >= mid+1 ) tot = pp(tot, query(o<<1|1,mid+1,r) );
return tot%p;
}
int main()
{
//freopen("1.in","r",stdin);
r(n), r(m), r(p);
//p = P;
for(ll i = 1; i <= n; i++) r(arr[i]);
build(1,1,n);
for(ll i = 1; i <= m; i++)
{
r(opt), r(x), r(y);
if( opt == 3 ) printf("%lld\n", query(1,1,n) );
else
{
r(k);
if( opt == 2 ) plus(1,1,n);
else mult(1,1,n);
}
}
return 0;
}