#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,M=5e5+5,V=1e5+10;
struct Q{
int op,l,r,x;
}q[M];
int n,m,a[N],ans[M];
int len,L[N],R[N];
int bl,br,Max,tag;
int prt[N],rt[V],val[N],cnt[V];
inline int Find(int x){
if(x==prt[x])return x;
return prt[x]=Find(prt[x]);
}
inline void Merge(int x,int y){
if(rt[y]){
prt[rt[x]]=rt[y];
}else{
rt[y]=rt[x];
val[rt[y]]=y;
}
cnt[y]+=cnt[x];
rt[x]=0;
cnt[x]=0;
}
inline void build(){
memset(rt,0,sizeof(rt));
memset(cnt,0,sizeof(cnt));
Max=tag=0;
for(register int i=bl;i<=br;++i){
val[i]=0;
Max=max(Max,a[i]);
if(!rt[a[i]]){
rt[a[i]]=i;
val[i]=a[i];
prt[i]=i;
}else{
prt[i]=rt[a[i]];
}
cnt[a[i]]++;
}
}
inline void update(int x){
if(Max-tag<(x<<1)){
for(register int i=x+tag+1;i<=Max;++i)
if(rt[i])Merge(i,i-x);
if(tag+x<Max)Max=tag+x;
}else{
for(register int i=tag+x;i>=tag;--i)
if(rt[i])Merge(i,i+x);
tag+=x;
}
}
inline void rebuild(int l,int r,int x){
for(register int i=bl;i<=br;++i){
a[i]=val[Find(i)];
rt[a[i]]=0;
cnt[a[i]]=0;
a[i]-=tag;
}
int ql=max(bl,l),qr=min(br,r);
for(register int i=ql;i<=qr;++i)
if(a[i]>x)a[i]-=x;
Max=tag=0;
for(register int i=bl;i<=br;++i){
val[i]=0;
Max=max(Max,a[i]);
if(!rt[a[i]]){
rt[a[i]]=i;
val[i]=a[i];
prt[i]=i;
}else{
prt[i]=rt[a[i]];
}
cnt[a[i]]++;
}
}
inline int query(int l,int r,int x){
if(x+tag>100001)return 0;
if(l<=bl&&br<=r)
return cnt[x+tag];
int ql=max(bl,l),qr=min(br,r),res=0;
for(register int i=ql;i<=qr;++i)
res+=(val[Find(i)]+tag==x);
return res;
}
template<typename T>
inline void read(T &x){
char c;
x=0;
int fu=1;
c=getchar();
while(c>'9'||c<'0'){
if(c=='-')fu=-1;
c=getchar();
}
while(c<='9'&&c>='0'){
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
x*=fu;
}
template<typename T>
inline void print(T x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)print(x/10);
putchar(x%10+'0');
}
int main(){
read(n);read(m);
len=n/sqrt(n);
for(register int i=1;i<=n;++i)
read(a[i]);
for(register int i=1;i<=m;++i){
read(q[i].op);read(q[i].l);read(q[i].r);read(q[i].x);
}
for(register int i=1,block=sqrt(n);i<=len;++i){
L[i]=(i-1)*block+1;
R[i]=i*block;
}
if(R[len]<n){
len++;
L[len]=R[len-1]+1;
R[len]=n;
}
for(register int i=1;i<=len;++i){
bl=L[i];br=R[i];
build();
for(register int j=1;j<=m;++j){
if(q[j].op==1){
if(q[j].l<=bl&&br<=q[j].r)
update(q[j].x);
else
rebuild(q[j].l,q[j].r,q[j].x);
}else{
ans[j]+=query(q[j].l,q[j].r,q[j].x);
}
}
}
for(register int i=1;i<=m;++i)
if(q[i].op==2){print(ans[i]);printf("\n");}
return 0;
}