/**
5037 线段树练习4加强版
链接:http://codevs.cn/problem/5037/
op 1 区间修改
op 2 区间多少个数为k的倍数;
依据数据范围:可记录每个块内每个数字出现的次数
区间加操作,完整块依旧0(1),非完整块 直接暴力即可 注意细节;
***********************************tricks*************************************************
卡常 卡空间 卡输入 取模优化 NICE!!!++;
*/
#include<bits/stdc++.h>
using namespace std;
bool Finish_read;
template<class T>inline void read(T &x){
Finish_read=0;
x=0;
int f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
if(ch==EOF) return;
ch=getchar();
}
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
x*=f;
Finish_read=1;
}
template<class T>inline void print(T x){
if(x/10!=0) print(x/10);
putchar(x%10+'0');
}
template<class T>inline void writeln(T x){
if(x<0)putchar('-');
x=abs(x);
print(x);
putchar('\n');
}
template<class T>inline void write(T x){
if(x<0) putchar('-');
x=abs(x);
print(x);
}
const int maxn=2e5+7;
int n,m,k,s[maxn],pos[maxn],blo,tag[510+2];
int a[510][maxn];
int Mod(int x,int mod){
while(x>=mod) x-=mod;
return x;
}
void push_down(int x){
if(tag[x]==-1) return ;
int kk=min(n,x*blo);
for(int i=(x-1)*blo+1;i<=kk;i++) a[x][s[i]]--,s[i]=Mod(s[i]+tag[x],k),a[x][s[i]]++;
tag[x]=-1;
}
int query(int l,int r){
int ans=0,tmp;
for(int i=pos[l]+1;i<=pos[r]-1;i++) {
if(tag[i]==-1||tag[i]==0) ans+=a[i][0];
else ans+=a[i][k-tag[i]];
}
if(pos[l]!=pos[r]){
int kk=pos[l]*blo;
if(tag[pos[l]]==-1)
for(int i=l;i<=kk;i++) {
if(s[i]==0) ans++;
}
else for(int i=l;i<=kk;i++) {
tmp=Mod(s[i]+tag[pos[l]],k);
if(tmp==0) ans++;
}
kk=(pos[r]-1)*blo+1;
if(tag[pos[r]]==-1)
for(int i=kk;i<=r;i++) {
if(s[i]==0) ans++;
}
else for(int i=kk;i<=r;i++) {
tmp=Mod(s[i]+tag[pos[r]],k);
if(tmp==0) ans++;
}
}
else {
if(tag[pos[l]]==-1)
for(int i=l;i<=r;i++) {
if(s[i]==0) ans++;
}
else for(int i=l;i<=r;i++) {
tmp=Mod(s[i]+tag[pos[l]],k);
if(tmp==0) ans++;
}
}
return ans;
}
void update(int l,int r,int val){
val=Mod(val,k);
int kk;
for(int i=pos[l]+1;i<=pos[r]-1;i++) {
if(tag[i]==-1) tag[i]=val;
else tag[i]=Mod((tag[i]+val),k);
}
if(pos[l]!=pos[r]){
//push_down(pos[l]),push_down(pos[r]);
kk=pos[l]*blo;
if(tag[pos[l]]!=-1&&tag[pos[l]]!=0){
for(int i=(pos[l]-1)*blo+1;i<l;i++) a[pos[l]][s[i]]--,s[i]=Mod(tag[pos[l]]+s[i],k),a[pos[l]][s[i]]++;
for(int i=l;i<=kk;i++) a[pos[l]][s[i]]--,s[i]=Mod(s[i]+val+tag[pos[l]],k),a[pos[l]][s[i]]++;
tag[pos[l]]=-1;
}
else for(int i=l;i<=kk;i++) a[pos[l]][s[i]]--,s[i]=Mod(s[i]+val,k),a[pos[l]][s[i]]++;
//for(int i=l;i<=kk;i++) a[pos[l]][s[i]]--,s[i]=Mod(s[i]+val,k),a[pos[l]][s[i]]++;
kk=(pos[r]-1)*blo+1;
if(tag[pos[r]]!=-1&&tag[pos[l]]!=0){
for(int i=(pos[r]-1)*blo+1;i<=r;i++) a[pos[r]][s[i]]--,s[i]=Mod(tag[pos[r]]+s[i]+val,k),a[pos[r]][s[i]]++;
for(int i=r+1;i<=min(n,pos[r]*blo);i++) a[pos[r]][s[i]]--,s[i]=Mod(tag[pos[r]]+s[i],k),a[pos[r]][s[i]]++;
tag[pos[r]]=-1;
}
else
for(int i=kk;i<=r;i++) a[pos[r]][s[i]]--,s[i]=Mod(s[i]+val,k),a[pos[r]][s[i]]++;
}
else {
push_down(pos[l]);
for(int i=l;i<=r;i++) a[pos[l]][s[i]]--,s[i]=Mod(s[i]+val,k),a[pos[l]][s[i]]++;
}
}
int l,r,val;
char cc[8];
int main(){
read(n),read(m),read(k);blo=(int)sqrt(n*1.0);for(int i=0;i<=100;i++) for(int j=0;j<k;j++) a[i][j]=0;
for(int i=1;i<=n;i++) read(s[i]);
for(int i=1;i<=n;i++) pos[i]=(i-1)/blo+1,s[i]=Mod(s[i],k),tag[pos[i]]=-1,a[pos[i]][s[i]]++;
while(m--){
scanf("%s",cc);
if(cc[0]=='c') {
read(l),read(r);
writeln(query(l,r));
}
else {
read(l),read(r),read(val);
update(l,r,val);
}
}
return 0;
}