#include<bits/stdc++.h>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)(a);i<=(sign)(b);++i)
#define Fordown(i,a,b) for(register sign i=(sign)(a);i>=(sign)(b);--i)
template<typename T>bool cmax(T &a,T b){return (a<b)?a=b,1:0;}
template<typename T>bool cmin(T &a,T b){return (a>b)?a=b,1:0;}
template<typename T>T read()
{
	T ans=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')f=-1,ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
	return ans*f;
}
template<typename T>void write(T x,char y)
{
	if(x==0)
	{
		putchar('0'),putchar(y);
		return;
	}
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	static char wr[20];
	int top=0;
	for(;x;x/=10)wr[++top]=x%10+'0';
	while(top)putchar(wr[top--]);
	putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
	freopen("E.in","r",stdin);
	freopen("E.out","w",stdout);
#endif
}
const int N=1e5+5;
int n,m;
int a[N];
void input()
{
	n=read<int>(),m=read<int>();
	For(i,1,n)a[i]=read<int>();
}
const int BLOCK=320;
int st[BLOCK],ed[BLOCK],bl[N];
int pre[N],pos[N];
struct node
{
	int rt,num;
}d[BLOCK][N];
int L[BLOCK],R[BLOCK];
int find(int x){return x==pre[x]?x:pre[x]=find(pre[x]);}
void rebuild(int id)
{
	R[id]=0;
	For(i,st[id],ed[id])
	{
		cmax(R[id],a[i]);
		if(!d[id][a[i]].rt)pre[i]=i,pos[i]=a[i],d[id][a[i]].rt=i;
		else pre[i]=d[id][a[i]].rt;
		d[id][a[i]].num++;
	}
}
void init()
{
	int tim=sqrt(n),now=0;
	For(i,1,n)
	{
		if(i%tim==1)st[++now]=i;
		if(i%tim==0||i==n)ed[now]=i;
		bl[i]=now;
	}
	For(i,1,now)rebuild(i);
}
void push_down(int id)
{
	For(i,st[id],ed[id])a[i]=pos[find(i)],d[id][a[i]]=(node){0,0},a[i]-=L[id];
	For(i,st[id],ed[id])pre[i]=0;
	L[id]=0;
}
void merge(int id,int x,int y)
{
	node &A=d[id][x],&B=d[id][y];
	if(B.rt)pre[A.rt]=B.rt;
	else B.rt=A.rt,pos[B.rt]=y;
	B.num+=A.num;
	A=(node){0,0};
}
void modify(int id,int v)
{
	if(v*2<=R[id]-L[id])
	{
		For(i,L[id]+1,L[id]+v)
			if(d[id][i].rt)merge(id,i,i+v);

		L[id]+=v;
	}
	else
	{
		For(i,L[id]+v+1,R[id])
			if(d[id][i].rt)merge(id,i,i-v);

		cmin(R[id],L[id]+v);
	}
}
void modify(int l,int r,int v)
{
	if(bl[l]==bl[r])
	{
		push_down(bl[l]);
		For(i,l,r)if(a[i]>v)a[i]-=v;
		rebuild(bl[l]);
	}
	else
	{
		push_down(bl[l]),push_down(bl[r]);
		For(i,l,ed[bl[l]])if(a[i]>v)a[i]-=v;
		For(i,bl[l]+1,bl[r]-1)modify(i,v);
		For(i,st[bl[r]],r)if(a[i]>v)a[i]-=v;
		rebuild(bl[l]),rebuild(bl[r]);
	}
}
int get_ans(int l,int r,int v)
{
	int ans=0;
	if(bl[l]==bl[r])
	{
		push_down(bl[l]);
		For(i,l,r)if(a[i]==v)ans++;
		rebuild(bl[l]);
	}
	else
	{
		push_down(bl[l]),push_down(bl[r]);
		For(i,l,ed[bl[l]])if(a[i]==v)ans++;
		For(i,bl[l]+1,bl[r]-1)if(v+L[i]<=N-5)ans+=d[i][v+L[i]].num;
		For(i,st[bl[r]],r)if(a[i]==v)ans++;
		rebuild(bl[l]),rebuild(bl[r]);
	}
	return ans;
}
void work()
{
	int ty,l,r,x;
	For(i,1,m)
	{
		ty=read<int>(),l=read<int>(),r=read<int>(),x=read<int>();
		if(ty==1)modify(l,r,x);
		else write(get_ans(l,r,x),'\n');
	}
}
int main()
{
	file();
	input();
	init();
	work();
	return 0;
}

