#include<bits/stdc++.h>
using namespace std;
#define SIZE 100005
int num, n, q, M, x, y, k;
long long a[SIZE], ans;
struct SegmentTree {
int l, r;
long long sum, add, mul = 1;
} t[SIZE*4];
void build(int p, int l, int r) {
t[p].l = l, t[p].r = r;
if (l == r) {
t[p].sum = a[l]%M; return;
}
int mid = t[p].l+t[p].r>>1;
build(p*2, l, mid);
build(p*2+1, mid+1, r);
t[p].sum = (t[p*2].sum+t[p*2+1].sum)%M;
}
void pushdown(int p) {
int mid = t[p].l+t[p].r>>1;
t[p*2].sum = ((t[p*2].sum*t[p].mul)%M+t[p].add*(mid-t[p].l+1))%M;
t[p*2+1].sum = ((t[p*2+1].sum*t[p].mul)%M+t[p].add*(t[p].r-mid))%M;
t[p*2].mul = (t[p*2].mul*t[p].mul)%M;
t[p*2+1].mul = (t[p*2+1].mul*t[p].mul)%M;
t[p*2].add = ((t[p*2].add*t[p].mul)%M+t[p].add)%M;
t[p*2+1].add = ((t[p*2+1].add*t[p].mul)%M+t[p].add)%M;
t[p].mul = 1;
t[p].add = 0;
}
void ask1(int p, int l, int r, int k) {
int mid = t[p].l+t[p].r>>1;
if (t[p].l >= l && t[p].r <= r) {
t[p].mul = (t[p].mul*k)%M;
t[p].add = (t[p].add*k)%M;
t[p].sum = (t[p].sum*k)%M;
return;
}
pushdown(p);
if (l <= mid) ask1(p*2, l, r, k);
if (r >= mid+1) ask1(p*2+1, l, r, k);
t[p].sum = t[p*2].sum+t[p*2+1].sum;
}
void ask2(int p, int l, int r, int k) {
int mid = t[p].l+t[p].r>>1;
if (t[p].l >= l && t[p].r <= r) {
t[p].add = (t[p].add+k)%M;
t[p].sum = (t[p].sum+k*(t[p].r-t[p].l+1)%M)%M;
return;
}
pushdown(p);
if (l <= mid) ask2(p*2, l, r, k);
if (r >= mid+1) ask2(p*2+1, l, r, k);
t[p].sum = t[p*2].sum+t[p*2+1].sum;
}
long long ask3(int p, int l, int r) {
if (t[p].r<l||t[p].l>r) return 0;
int mid = t[p].l+t[p].r>>1;
if (t[p].l >= l && t[p].r <= r) {
return t[p].sum;
}
pushdown(p);
return (ask3(p*2, l, mid)%M+ask3(p*2+1, mid+1, r)%M)%M;
}
int main()
{
scanf("%d%d%d", &n, &q, &M);
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
build(1, 1, n);
for (int i = 1; i <= q; i++) {
scanf("%d%d%d", &num, &x, &y);
if (num != 3) scanf("%d", &k);
if (num == 1) {
ask1(1, x, y, k);
}
else if (num == 2) {
ask2(1, x, y, k);
}
else {
cout << ask3(1, x, y) << endl;
}
}
return 0;
}