#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
namespace INPUT{
char buf[1<<20],*p1,*p2;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
inline T read(){
T x=0,p=1;
char ch=gc();
for(;ch<'0'||ch>'9';ch=gc())
if(ch=='-') p=-1;
for(;ch>='0'&&ch<='9';ch=gc())
x=(x<<3)+(x<<1)+(ch^48);
return x*p;
}
#include<assert.h>
#pragma GCC optimize(2)
const int N=100005,M=350;
#define B 310
int pos[N],DL[M],DR[M];
int fa[M][N],siz[M][N];
int find(int p,int x) {
assert(x>0&&x<N);
return fa[p][x]==x?x:fa[p][x]=find(p,fa[p][x]);
}
void Union(int p,int u,int v){
u=find(p,u),v=find(p,v);
fa[p][v]=u,siz[p][u]+=siz[p][v];
}
int n,m,a[N];
int LazyTag[M];
int Mx[M];
void build(int p,int l=1,int r=n,int x=0){
for(int i=DL[p];i<=DR[p];i++) a[i]=find(p,a[i]);
for(int i=DL[p];i<=DR[p];i++) fa[p][a[i]]=a[i],siz[p][a[i]]=0;
Mx[p]=0;
for(int i=DL[p];i<=DR[p];i++){
a[i]+=LazyTag[p];
if(l<=i&&i<=r&&a[i]>x) a[i]-=x;
assert(a[i]>0&&a[i]<N);
Mx[p]=max(Mx[p],a[i]);
siz[p][a[i]]++;
}
LazyTag[p]=0;
}
void Change(int p,int x){
if(Mx[p]<=x) return ;
if(2*x>=Mx[p]){
for(int i=x+1-LazyTag[p];i<=Mx[p];i++){
assert(i>0&&i<N);
if(!siz[p][i]) continue;
assert(i-x>0&&i-x<N);
Union(p,fa[p][i-x],fa[p][i]);
}
}
else {
for(int i=1-LazyTag[p];i<=min(Mx[p],x-LazyTag[p]);i++){
assert(i>0&&i<N);
if(!siz[p][i]) continue;
if(Mx[p]<i+LazyTag[p]+x) Mx[p]=i+LazyTag[p]+x;
assert(1<=i+x&&i+x<N);
Union(p,fa[p][i+x],fa[p][i]);
}
LazyTag[p]-=x;
}
}
void Change(int l,int r,int x){
int L=pos[l],R=pos[r];
if(L+1<=R){
build(L,l,DR[L],x),build(R,DL[R],r,x);
for(int i=L+1;i<=R-1;i++) Change(i,x);
}
else build(L,l,r,x);
}
int Query(int p,int l,int r,int x){
int ans=0;
for(int i=l;i<=r;i++)
if(find(p,a[i])+LazyTag[p]==x) ans++;
return ans;
}
int Query(int l,int r,int x){
int L=pos[l],R=pos[r];
int ans=0;
if(L+1<=R){
ans+=Query(L,l,DR[L],x),ans+=Query(R,DL[R],r,x);
for(int i=L+1;i<=R-1;i++) {
assert(1<=x-LazyTag[i]&&x-LazyTag[i]<N);
ans+=siz[i][find(i,x-LazyTag[i])];
}
}
else ans+=Query(L,l,r,x);
return ans;
}
int main(){
n=read<int>(),m=read<int>();
for(int i=1;i<=n;i++) pos[i]=(i-1)/B+1;
int sz=(n-1)/B+1;
for(int i=1;i<=sz;i++)
DL[i]=(i-1)*B+1,DR[i]=min(i*B,n);
for(int i=1;i<=n;i++) a[i]=read<int>();
for(int i=1;i<=sz;i++)
for(int v=1;v<=1e5;v++) fa[i][v]=v;
for(int i=1;i<=sz;i++) build(i);
int op,l,r,x;
for(int i=1;i<=m;i++){
op=read<int>();
l=read<int>(),r=read<int>(),x=read<int>();
if(op==1) Change(l,r,x);
if(op==2) printf("%d\n",Query(l,r,x));
}
}