#include <bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define ld long double #define pb push_back #define ppb pop_back #define pii pair<ll, ll> #define pll pair<ll, ll> #define vi vector<ll> #define vll vector<ll> #define vull vector<ull> #define vpii vector<pll > #define vpll vector<pll > #define mp make_pair #define mt make_tuple #define ff first #define ss second #define uset unordered_set #define umap unordered_map #define all(x) x.begin(), x.end() #define revall(x) x.rbegin(), x.rend() #define rep(i, j, k) for(ll i = j; i < k; ++i) #define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define T int tt; cin>>tt; while(tt--) const ll MOD = (ll)(1e9+7); const int inf = (int)INFINITY; const ll INF = (ll)INFINITY; const int MAX = (int)(1e5+1); int x, temp[10], tree[4*MAX][10], a[MAX], lazy[4*MAX]; void build(int node, int l, int r) { if(l == r) { rep(i, 0, x) tree[node][i] = 0; tree[node][a[l]%x] = 1; return; } int m = (l + r)/2; build(node<<1, l, m); build(node<<1|1, m+1, r); rep(i, 0, x) tree[node][i] = tree[node<<1][i] + tree[node<<1|1][i]; } inline void update_lazy(int node, int l, int r) { rep(i, 0, x) temp[(i + lazy[node])%x] = tree[node][i]; rep(i, 0, x) tree[node][i] = temp[i]; if(l != r) { lazy[node<<1] = (lazy[node<<1] + lazy[node])%x; lazy[node<<1|1] = (lazy[node<<1|1] + lazy[node])%x; } lazy[node] = 0; } void update(int node, int l, int r, int i, int j, int val) { if(lazy[node]) update_lazy(node, l, r); if(j < l || i > r) return; if(i <= l && j >= r) { rep(i, 0, x) temp[(i + val)%x] = tree[node][i]; rep(i, 0, x) tree[node][i] = temp[i]; if(l != r) { lazy[node<<1] = (lazy[node<<1] + val)%x; lazy[node<<1|1] = (lazy[node<<1|1] + val)%x; } return; } int m = (l + r)/2; update(node<<1, l, m, i, j, val); update(node<<1|1, m+1, r, i, j, val); rep(i, 0, x) tree[node][i] = tree[node<<1][i] + tree[node<<1|1][i]; } ll query(int node, int l, int r, int i, int j) { if(lazy[node]) update_lazy(node, l, r); if(j < l || i > r) return 0; if(i <= l && j >= r) return tree[node][0]; int m = (l + r)/2; return query(node<<1, l, m, i, j) + query(node<<1|1, m+1, r, i, j); } int main() { fastio; int n, q; cin >> n >> q >> x; rep(i, 0, n) cin >> a[i]; build(1, 0, n-1); while(q--) { int a, b, c, val; cin >> c >> a >> b; --a, --b; if(c == 1) { cin >> val; update(1, 0, n-1, a, b, val%x); } else { cout << query(1, 0, n-1, a, b) << '\n'; } } return 0; }