// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define N 100005
#define M 350
#define R register
#define il inline
#define For(i,x,y) for(i=(x);i<=(y);++i)
#define Rof(i,x,y) for(i=(x);i>=(y);--i)
using namespace std;

struct node{ int fa,sz; } v[M][N];
int bl[N],lb[N],rb[N],fa[N],tag[N],mx[M],sz[M][N],a[N],pos[N];
il void rd(int &x){
	char c=getchar();int y=0;
	while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') y=y*10+c-'0',c=getchar();
	x=y;
}
il void init(int i){
	int j;mx[i]=0;
	For(j,lb[i],rb[i]){
		mx[i]=max(mx[i],a[j]);
		if(!v[i][a[j]].fa) v[i][a[j]].fa=fa[j]=j,pos[j]=a[j];
		else fa[j]=v[i][a[j]].fa;
		v[i][a[j]].sz++;
	}
}
il int find(int x){ return (x==fa[x])?x:fa[x]=find(fa[x]); }
il void reset(int x){
	int i;
	For(i,lb[x],rb[x]){
		a[i]=pos[find(i)];
		v[x][a[i]].fa=v[x][a[i]].sz=0;
		a[i]-=tag[x];
	}
	For(i,lb[x],rb[x]) fa[i]=pos[i]=0;
	tag[x]=mx[x]=0;
}
il void merge(int x,int a,int b){
	v[x][b].fa?fa[v[x][a].fa]=v[x][b].fa:(v[x][b].fa=v[x][a].fa,pos[v[x][b].fa]=b,fa[v[x][b].fa]=v[x][b].fa);
	v[x][b].sz+=v[x][a].sz;
	v[x][a].sz=v[x][a].fa=0;
}
il void update(int l,int r,int x){
	int i,j;
	if(bl[l]!=bl[r]){
		reset(bl[l]),reset(bl[r]);
		For(i,l,min(r,rb[bl[l]])) if(a[i]>x) a[i]-=x;
		For(i,max(l,lb[bl[r]]),r) if(a[i]>x) a[i]-=x;	
		init(bl[l]),init(bl[r]);		
		For(i,bl[l]+1,bl[r]-1){
			if(mx[i]-tag[i]>=2*x){
				For(j,tag[i]+1,x+tag[i])
					if(v[i][j].fa) merge(i,j,j+x);
				tag[i]+=x;
			} else{
				Rof(j,mx[i],x+tag[i]+1)
					if(v[i][j].fa) merge(i,j,j-x);
				mx[i]=min(mx[i],tag[i]+x);
			}
		}
	} else{
		reset(bl[l]);
		For(i,l,r) a[i]-=x;
		init(bl[l]);
	}
}
il int query(int l,int r,int x){
	int ans=0,i;
	if(bl[l]!=bl[r]){
		For(i,l,min(rb[bl[l]],r)) ans+=(pos[find(i)]-tag[bl[i]]==x);
		For(i,max(l,lb[bl[r]]),r) ans+=(pos[find(i)]-tag[bl[i]]==x);
		For(i,bl[l]+1,bl[r]-1) if(x+tag[i]<N)ans+=v[i][x+tag[i]].sz;		
	} else For(i,l,r) ans+=(pos[find(i)]-tag[bl[i]]==x);
	return ans;
}
int main(){
	int n,block,op,l,r,x,i,m;
	rd(n),rd(m);block=sqrt(n);
	For(i,1,n) rd(a[i]);
	For(i,1,n){
		bl[i]=i/block+1;
		if(!lb[bl[i]]) lb[bl[i]]=i;
	}
	Rof(i,n,1) if(!rb[bl[i]]) rb[bl[i]]=i;
	For(i,1,bl[n])
		init(i);
	while(m--){
		scanf("%d%d%d%d",&op,&l,&r,&x);
		if(op==1) update(l,r,x);
		else printf("%d\n",query(l,r,x));
	}
}