7 pts
#include<bits/stdc++.h>
#define N 100005
using namespace std;
bool mbegin;
int lb=1400;
inline int read(){
register int x=0;
register bool f=0;
register char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-48;
c=getchar();
}
return f?-x:x;
}
char cr[200];int tt;
inline void write(register int x,register char k='\n') {
if(!x) putchar('0');
if(x < 0) putchar('-'),x=-x;
while(x) cr[++tt]=x%10+'0',x/=10;
while(tt) putchar(cr[tt--]);
putchar(k);
}
struct bl{
int mx,fa[5*N],mns,sz[5*N];
void init()
{
for(register int i=1;i<=mx;i++) fa[i]=i;
}
int find(int x)
{
if(fa[x]==x) return x;
else return fa[x]=find(fa[x]);
}
}b;
int a[10*N],i,j,n,m,q,op[5*N],l[5*N],r[5*N],x[5*N];
#define bo(x) (((x)-1)/lb+1)
inline void single_change(int pos,int v)
{
int act=b.find(a[pos]);
if(act<=v+b.mns)
return;
a[pos]=act-v;
b.sz[act]--;
b.sz[act-v]++;
}
inline void block_change(int pos,int v)
{
if(b.mx<=v+b.mns)
return;
int q=b.mx-b.mns;
if(2*v>q)
{
for(register int i=v+b.mns;i<=b.mx;i++)
{
int ii=b.fa[i],iv=b.fa[i-v];
b.sz[iv]+=b.sz[ii],b.sz[ii]=0;
b.fa[ii]=b.fa[iv];
}
while(!b.sz[b.mx]) b.mx--;
}
else
{
for(register int i=1+b.mns;i<=v+b.mns;i++)
{
int ii=b.fa[i],iv=b.fa[i+v];
b.sz[iv]+=b.sz[ii],b.sz[ii]=0;
b.fa[ii]=b.fa[iv];
}
b.mns+=v;
}
}
inline int single_ask(int pos,int v)
{
int act=b.find(a[pos]);
return (act==v+b.mns)?1:0;
}
inline int block_ask(int pos,int v)
{
if(v+b.mns>v+b.mx) return 0;
return b.sz[v+b.mns];
}
int ans[5*N];
bool mend;
int main()
{
n=read();
m=read();
for(i=1;i<=n;i++) a[i]=read();
for(j=1;j<=m;j++)
{
op[j]=read();l[j]=read();r[j]=read();x[j]=read();
}
int bln=bo(n);
for(register int bli=1;bli<=bln;bli++)
{
memset(b.sz,0,sizeof(b.sz));
b.mns=b.mx=0;
for(i=lb*bli-lb+1;i<=min(lb*bli,n);i++)
{
b.sz[a[i]]++;
b.mx=max(b.mx,a[i]);
}
b.init();
for(j=1;j<=m;j++)
{
#define l l[j]
#define r r[j]
#define op op[j]
#define x x[j]
int lo=bo(l),ro=bo(r);
if(op==1)
{
if(lo==bli)
for(i=l;i<=min(r,lo*lb);i++)
single_change(i,x);
b.mx=0;
for(i=(lo-1)*lb+1;i<=lo*lb;i++)
b.mx=max(b.mx,b.find(a[i]));
if(lo!=ro&&ro==bli)
{
for(i=(ro-1)*lb+1;i<=r;i++) single_change(i,x);
b.mx=0;
for(i=(ro-1)*lb+1;i<=min(r,lo*lb);i++)
b.mx=max(b.mx,b.find(a[i]));
}
if(bli>lo&&bli<ro) block_change(bli,x);
}
if(op==2)
{
int an=0;
if(lo==bli)
for(i=l;i<=min(r,lo*lb);i++) an+=single_ask(i,x);
if(lo!=ro&&ro==bli) for(i=(ro-1)*lb+1;i<=r;i++) an+=single_ask(i,x);
if(bli>lo&&bli<ro) an+=block_ask(bli,x);
ans[j]+=an;
}
}
}
for(j=1;j<=m;j++)
if(op==2) write(ans[j]);
return 0;
}