#include <iostream>
using namespace std;
const int N = 1e5 + 7;
struct tree
{
int l, r, sum;
int plz, mlz;
} e[N<<2];
int n, m, p, a[N];
inline int len(tree x) { return x.r - x.l + 1; }
inline void update_sum(int x_1, int x_2) { e[x_2].sum = (e[x_2].sum * e[x_1].mlz + e[x_1].plz * len(e[x_2])) % p; }
inline void update_mlz(int x_1, int x_2) { e[x_2].mlz = e[x_1].mlz * e[x_2].mlz % p; }
inline void update_plz(int x_1, int x_2) { e[x_2].plz = (e[x_1].mlz * e[x_2].plz + e[x_1].plz) % p; }
inline void Build(int x, int l, int r)
{
e[x].l = l, e[x].r = r;
e[x].plz = 0;
e[x].mlz = 1;
if(l == r) {
e[x].sum = a[l];
return ;
}
int mid = (l + r >> 1);
Build(x << 1, l, mid);
Build(x << 1 | 1, mid + 1, r);
e[x].sum = e[x<<1].sum + e[x<<1|1].sum;
}
inline void push_down(int x)
{
update_sum(x, x << 1);
update_sum(x, x << 1 | 1);
update_mlz(x, x << 1);
update_mlz(x, x << 1 | 1);
update_plz(x, x << 1);
update_plz(x, x << 1 | 1);
e[x].mlz = 1;
e[x].plz = 0;
}
// 维护加法
inline void change1(int x, int l, int r, int k)
{
if(e[x].l >= l && e[x].r <= r) {
e[x].sum += len(e[x]) * k; e[x].sum %= p;
e[x].plz += k; e[x].plz %= p;
return ;
}
push_down(x);
if(e[x<<1].r >= l) change1(x << 1, l, r, k);
if(e[x<<1|1].l <= r) change1(x << 1 | 1, l, r, k);
e[x].sum = (e[x<<1].sum + e[x<<1|1].sum) % p;
}
// 维护乘法
inline void change2(int x, int l, int r, int k)
{
if(e[x].l >= l && e[x].r <= r) {
e[x].sum *= k; e[x].sum %= p;
e[x].mlz *= k; e[x].mlz %= p;
return ;
}
push_down(x);
if(e[x<<1].r >= l) change1(x << 1, l, r, k);
if(e[x<<1|1].l <= r) change1(x << 1 | 1, l, r, k);
e[x].sum = (e[x<<1].sum + e[x<<1|1].sum) % p;
}
inline int query(int x, int l, int r)
{
if(e[x].l >= l && e[x].r <= r)
return e[x].sum;
int sum = 0;
if(e[x<<1].r >= l) sum += query(x << 1, l, r), sum %= p;
if(e[x<<1|1].l <= r) sum += query(x << 1 | 1, l, r), sum %= p;
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m >> p;
for(int i=1; i<=n; i++)
cin >> a[i];
Build(1, 1, n);
for(int i=1; i<=m; i++)
{
int opt; cin >> opt;
if(opt == 1) {
int l, r, k;
cin >> l >> r >> k;
change2(1, l, r, k);
}
if(opt == 2) {
int l, r, k;
cin >> l >> r >> k;
change1(1, l, r, k);
}
if(opt == 3) {
int l, r;
cin >> l >> r;
cout << query(1, l, r) << '\n';
}
}
}
求调,自认为码风还可以((