#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int block=970;
int n,m,cnt,opt[500009],ll[500009],rr[500009],sl[1550],sr[1550],tag[1550],xx[500009],a[1000009];
int root[100009],num[100009],ans[500009],father[1000009],maxn[1550],val[1000009];
inline int Readint()
{
char ch;
int i=0,f=1;
for(ch=getchar();(!isdigit(ch))&&ch!='-';ch=getchar());
if(ch=='-')
{
ch=getchar();
f=-1;
}
for(;isdigit(ch);ch=getchar()) i=(i<<1)+(i<<3)+(ch-'0');
return i*f;
}
inline int getfather(int x)
{
if(x==father[x]) return x;
else {
father[x]=getfather(father[x]);
return father[x];
}
}
inline void rebuild(int p)
{
for(int j=sl[p];j<=sr[p];++j)
{
maxn[p]=max(maxn[p],a[j]);
num[a[j]]++;
if(root[a[j]]==0)
{
root[a[j]]=j;
val[j]=a[j];
}
father[j]=root[a[j]];
}
}
inline void make_pieces()
{
for(int i=1;i<=n;i+=block)
{
sl[++cnt]=i;
sr[cnt]=min(i+block-1,n);
}
}
inline void pushdown(int p)
{
for(int i=sl[p];i<=sr[p];++i)
{
a[i]=val[getfather(i)];
root[a[i]]=num[a[i]]=0;
a[i]-=tag[p];
}
tag[p]=0;
for(int i=sl[p];i<=sr[p];++i) father[i]=0;
}
inline void merge(int p,int q,int w)
{
if(root[w]) father[root[q]]=root[w];
else {
root[w]=root[q];
val[root[w]]=w;
}
num[w]+=num[q];
root[q]=num[q]=0;
}
inline void make_tag(int p,int x)
{
if(x*2<=maxn[p]-tag[p])
{
for(int i=tag[p]+1;i<=tag[p]+x;++i)if(root[i]) merge(p,i,i+x);
tag[p]+=x;
return;
}
for(int i=maxn[p];i>tag[p]+x;i--) if(root[i]) merge(p,i,i-x);
maxn[p]=min(maxn[p],tag[p]+x);
}
inline void change(int p,int l,int r,int x)
{
if(sl[p]<=l&&r<=sr[p])
{
pushdown(p);
for(int i=l;i<=r;++i) if(a[i]>x) a[i]-=x;
rebuild(p);
return;
}
if(l<=sl[p]&&sr[p]<=r)
{
make_tag(p,x);
return;
}
if(sl[p]<=l&&l<=sr[p])
{
pushdown(p);
for(int i=l;i<=sr[p];++i) if(a[i]>x) a[i]-=x;
rebuild(p);
}
if(sl[p]<=r&&r<=sr[p])
{
pushdown(p);
for(int i=sl[p];i<=r;++i) if(a[i]>x) a[i]-=x;
rebuild(p);
}
}
inline int query(int p,int l,int r,int x)
{
int res=0;
if(sl[p]<=l&&r<=sr[p])
{
for(int i=l;i<=r;++i)
{
if(val[getfather(i)]-tag[p]==x) res++;
}
return res;
}
if(l<=sl[p]&&sr[p]<=r) if(x+tag[p]<500002) return num[x+tag[p]];
if(sl[p]<=l&&l<=sr[p])
{
for(int i=l;i<=sr[p];++i)
if(val[getfather(i)]-tag[p]==x) res++;
return res;
}
if(sl[p]<=r&&r<=sr[p])
{
for(int i=sl[p];i<=r;++i)
if(val[getfather(i)]-tag[p]==x) res++;
return res;
}
}
int main()
{
n=Readint(),m=Readint();
for(int i=1;i<=n;++i) {
a[i]=Readint();
}
make_pieces();
for(int i=1;i<=m;++i) {
opt[i]=Readint(),ll[i]=Readint(),rr[i]=Readint(),xx[i]=Readint();
}
for(int h=1;h<=cnt;++h)
{
memset(root,0,sizeof(root));
memset(num,0,sizeof(num));
rebuild(h);
for(int j=1;j<=m;++j)
{
if(ll[j]>sr[h]||rr[j]<sl[h]) continue;
if(opt[j]==1) change(h,ll[j],rr[j],xx[j]);
if(opt[j]==2) ans[j]+=query(h,ll[j],rr[j],xx[j]);
}
}
for(int i=1;i<=m;++i) if(opt[i]==2) printf("%d\n",ans[i]);
return 0;
}