#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;
int n, m, mod;
int a[maxn];
int tree[maxn * 4];
int add[maxn * 4];//加法标记
int mul[maxn * 4];//乘法标记
namespace SegmentTree{
#define lz (p * 2)
#define rz (p * 2 + 1)
inline update(int p){
tree[p] = (tree[lz] + tree[rz]) % mod;
}
inline void build(ll p, ll l, ll r){
add[p] = 0;
mul[p] = 1;
if(l == r){
tree[p] = a[l];
return;
}
int mid = (l + r) / 2;
build(lz, l, mid);
build(rz, mid + 1, r);
update(p);
}
inline void pushdown(ll p, ll l, ll r){
add[lz] = (add[lz] * mul[p]) % mod;
add[rz] = (add[rz] * mul[p]) % mod;
mul[lz] = (mul[lz] * mul[p]) % mod;
mul[rz] = (mul[rz] * mul[p]) % mod;
add[lz] = (add[lz] + add[p]) % mod;
add[rz] = (add[rz] + add[p]) % mod;
ll mid = (l + r) / 2;
tree[lz] = (tree[lz] * mul[p] + (mid - l + 1) * add[p]) % mod;
tree[rz] = (tree[rz] * mul[p] + (r - mid) * add[p]) % mod;
add[p] = 0;
mul[p] = 1;
}
inline void Add(ll l, ll r, ll k, ll p, ll cl, ll cr){
if(cl >= l && cr <= r){
add[p] = (add[p] + k) % mod;
tree[p] = (tree[p] + (cr - cl + 1) * k) % mod;
return;
}
else{
int mid = (cl + cr) / 2;
pushdown(p, cl, cr);
if(l <= mid) Add(l, r, k, lz, cl, mid);
if(mid < r) Add(l, r, k, rz, mid + 1, cr);
update(p);
}
}
inline void Mul(ll l, ll r, ll k, ll p, ll cl, ll cr){
if(cl >= l && cr <= r){
mul[p] = (mul[p] * k) % mod;
add[p] = (add[p] * k) % mod;
tree[p] = (tree[p] * k)% mod;
return;
}
else{
int mid = (cl + cr) / 2;
pushdown(p, cl, cr);
if(l <= mid) Mul(l, r, k, lz, cl, mid);
if(mid < r) Mul(l, r, k, rz, mid + 1, cr);
update(p);
}
}
inline ll ask(ll l, ll r, ll p, ll cl, ll cr){
if(cl >= l && cr <= r){
return tree[p];
}
pushdown(p, cl, cr);
ll mid = (cl + cr) / 2;
if(r <= mid) return ask(l, r, lz, cl, mid);
if(l > mid) return ask(l, r, rz, mid + 1, cr);
return ask(l ,r, lz, cl, mid) + ask(l, r, rz, mid + 1, cr);
}
}
int main(){
cin >> n >> m >> mod;
for(int i = 1 ; i <= n ; i++){
cin >> a[i];
}
SegmentTree::build(1, 1, n);
for(int i = 1 ; i <= m ; i++){
int op;
int x, y, k;
cin >> op;
if(op == 1){
cin >> x >> y >> k;
SegmentTree::Add(x, y, k, 1, 1, n);
}
else if(op == 2){
cin >> x >> y >> k;
SegmentTree::Mul(x, y, k, 1, 1, n);
}
else{
cin >> x >> y;
cout << SegmentTree::ask(x, y, 1, 1, n) % mod << endl;
}
}
}