#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
struct node{
int l,r;
int sum;
int add,mul;
}tr[4 * N];
int n,m,p;
void push_up(int u){
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(int u,int l,int r){
tr[u].l = l;tr[u].r = r;
if(l == r){
tr[u].sum = a[l];
tr[u].add = 0;
tr[u].mul = 1;
return;
}
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
push_up(u);
}
void eval(node & t,int add,int mul){
t.sum = ((t.sum * mul) + (t.r - t.l + 1) * add) % p;
t.mul = t.mul * mul % p;
t.add = (t.add * mul + add) % p ;
}
void push_down(int u){
eval(tr[u << 1],tr[u].add,tr[u].mul);
eval(tr[u << 1 | 1],tr[u].add,tr[u].mul);
tr[u].add = 0,tr[u].mul = 1;
}
void modify(int u,int l,int r,int add,int mul){
if(tr[u].l >= l && tr[u].r <= r){
eval(tr[u],add,mul);
}
else {
push_down(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(u << 1,l,r,add,mul);
if(r > mid) modify(u << 1 | 1,l,r,add,mul);
push_up(u);
}
}
int query(int u,int l,int r){
if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
push_down(u);
int mid = tr[u].l + tr[u].r >> 1;
int sum = 0;
if(l <= mid) (sum += query(u << 1,l,r)) %= p;
if(r > mid) (sum += query(u << 1 | 1,l,r)) %= p;
return sum;
}
signed main(){
cin >> n >> m >> p;
for(int i = 1;i <= n;i++){
cin >> a[i];
}
build(1,1,n);
while(m--){
int l,r,t,k;
cin >> t;
if(t == 1){
cin >> l>>r >>k;
modify(1,l,r,0,k);
}
if(t == 2){
cin >> l >> r>>k;
modify(1,l,r,k,1);
}
if(t == 3){
cin >>l >> r;
cout << query(1,l,r)<<endl;
}
}
return 0;
}