#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
int n, q, m;
int a[N];
struct seg_tree
{
struct node
{
int l, r, num, add, mult;
} tr[4 * N];
void push_up(int p)
{
tr[p].num = (tr[p * 2].num + tr[p * 2 + 1].num) % m;
}
void push_down(int p)
{
tr[p * 2].num = (tr[p * 2].num * tr[p].mult + (tr[p].add * (tr[p * 2].r - tr[p * 2].l + 1))) % m;
tr[p * 2 + 1].num += (tr[p * 2 + 1].num * tr[p].mult + (tr[p].add * (tr[p * 2 + 1].r - tr[p * 2 + 1].l + 1))) % m;
tr[p * 2].mult = (tr[p * 2].mult * tr[p].mult) % m;
tr[p * 2 + 1].mult = (tr[p * 2 + 1].mult * tr[p].mult) % m;
tr[p * 2].add = (tr[p * 2].add * tr[p].mult + tr[p].add) % m;
tr[p * 2 + 1].add = (tr[p * 2 + 1].add * tr[p].mult + tr[p].add) % m;
tr[p].mult = 1, tr[p].add = 0;
}
void build(int p, int l, int r)
{
tr[p] = {l, r, 0, 0, 1};
if (l == r)
{
tr[p].num = a[l];
return;
}
int mid = (l + r) >> 1;
build(p * 2, l, mid);
build(p * 2 + 1, mid + 1, r);
push_up(p);
}
void modify(int p, int l, int r, int k)
{
if (tr[p].l < l || tr[p].r > r) return;
if (tr[p].l >= l && tr[p].r <= r)
{
tr[p].num = (tr[p].num + k * (tr[p].r - tr[p].l + 1)) % m;
tr[p].add = (tr[p].add + k) % m;
return;
}
push_down(p);
int mid = (tr[p].l + tr[p].r) >> 1;
if (l <= mid) modify(p * 2, l, r, k);
if (r > mid) modify(p * 2 + 1, l, r, k);
push_up(p);
}
void mul(int p, int l, int r, int k)
{
if (tr[p].l < l || tr[p].r > r) return;
if (tr[p].l >= l && tr[p].r <= r)
{
tr[p].num = (tr[p].num * k) % m;
tr[p].mult = (tr[p].mult * k) % m;
tr[p].add = (tr[p].add * k) % m;
return;
}
push_down(p);
int mid = (tr[p].l + tr[p].r) >> 1;
if (l <= mid) mul(p * 2, l, r, k);
if (r > mid) mul(p * 2 + 1, l, r, k);
push_up(p);
}
int query(int p, int l, int r)
{
if (tr[p].l >= l && tr[p].r <= r) return (tr[p].num % m);
push_down(p);
int mid = (tr[p].l + tr[p].r) >> 1, res = 0;
if (l <= mid) res += query(p * 2, l, r);
if (r > mid) res += query(p * 2 + 1, l, r);
return (res % m);
}
} ST;
signed main()
{
scanf("%lld%lld%lld", &n, &q, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
ST.build(1, 1, n);
while (q--)
{
int op, x, y, k;
scanf("%lld%lld%lld", &op, &x, &y);
if (op == 1)
{
scanf("%lld", &k);
ST.mul(1, x, y, k);
}
else if (op == 2)
{
scanf("%lld", &k);
ST.modify(1, x, y, k);
}
else
{
printf("%lld\n", ST.query(1, x, y));
}
}
return 0;
}