#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
typedef long long LL;
typedef struct Node
{
int le;
int ri;
LL sum;
int lazy_add;
int lazy_mul = 1;
}Nodetr[4 * N + 2];
Nodetr tr;
//建树
void bui_tr(int x, int L, int R)
{
tr[x].le = L;
tr[x].ri = R;
if(L == R)
{
tr[x].sum = (LL)a[L];
return;
}
int mid = tr[x].le + tr[x].ri >> 1;
bui_tr(2 * x, L, mid);
bui_tr(2 * x + 1, mid + 1, R);
tr[x].sum = (LL)(tr[2 * x].sum + tr[2 * x + 1].sum);
}
void spread(int x)
{
if(tr[x].lazy_add)
{
tr[2 * x].lazy_add += tr[x].lazy_add;
tr[2 * x + 1].lazy_add += tr[x].lazy_add;
tr[2 * x].sum += (LL)(tr[2 * x].ri - tr[2 * x].le + 1) * tr[x].lazy_add;
tr[2 * x + 1].sum += (LL)(tr[2 * x + 1].ri - tr[2 * x + 1].le + 1) * tr[x].lazy_add;
tr[x].lazy_add = 0;
}
if(tr[x].lazy_mul != 1)
{
tr[2 * x].lazy_mul *= tr[x].lazy_mul;
tr[2 * x + 1].lazy_mul *= tr[x].lazy_mul;
tr[2 * x].sum = (LL)tr[2 * x].sum * tr[x].lazy_mul;
tr[2 * x + 1].sum = (LL)tr[2 * x + 1].sum * tr[x].lazy_mul;
tr[x].lazy_mul = 1;
}
}
void change_add(int x, int l, int r, int k)
{
if(l <= tr[x].le && r >= tr[x].ri)
{
tr[x].lazy_add += k;
tr[x].sum += LL(tr[x].ri - tr[x].le + 1) * k;
return;
}
spread(x);
int mid = tr[x].le + tr[x].ri >> 1;
if(l <= mid) change_add(2 * x, l, r, k);
if(r >= mid + 1) change_add(2 * x + 1, l, r, k);
tr[x].sum = tr[2 * x].sum + tr[2 * x + 1].sum;
}
void change_mul(int x, int l, int r, int k)
{
if(l <= tr[x].le && r >= tr[x].ri)
{
tr[x].lazy_mul *= k;
tr[x].sum *= k;
return;
}
spread(x);
int mid = tr[x].le + tr[x].ri >> 1;
if(l <= mid) change_mul(2 * x, l, r, k);
if(r >= mid + 1) change_mul(2 * x + 1, l, r, k);
tr[x].sum = tr[2 * x].sum + tr[2 * x + 1].sum;
}
LL query_sum(int x, int l, int r)
{
if(l <= tr[x].le && r >= tr[x].ri)
{
return tr[x].sum;
}
spread(x);
LL ans = 0;
int mid = tr[x].le + tr[x].ri >> 1;
if(l <= mid) ans += query_sum(2 * x, l, r);
if(r >= mid + 1) ans += query_sum(2 * x + 1, l, r);
return ans;
}
int main()
{
int n, m, p;
cin >> n >> m >> p;
for(int i = 1 ; i <= n ; i ++) scanf("%d",&a[i]);
bui_tr(1, 1, n);
while(m --)
{
int tag;
scanf("%d",&tag);
if(tag == 1)//乘
{
int x, y, k;
scanf("%d%d%d",&x,&y,&k);
//区间乘一个数
change_mul(1,x,y,k);
}
else if(tag == 2)
{
int x, y, k;
scanf("%d%d%d",&x,&y,&k);
//区间加一个数
change_add(1, x, y, k);
}
else
{
int x, y;
scanf("%d%d",&x,&y);
printf("%lld\n",query_sum(1, x, y) % p);
}
}
return 0;
}