#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define Rep(i,a,b) for(register int i=(a);i<=int(b);++i)
#define Dep(i,a,b) for(register int i=(a);i>=int(b);--i)
#define rep(i,a,b) for(register int i=(a);i<int(b);++i)
#define mem(x,v) memset(x,v,sizeof(x))
#define gc getchar
#define pc putchar
#define fi first
#define se second
#define debug(x) cout << #x" = " << x << endl;
#define pp(x,y) cout << "pp: " << x << " " << y << endl;
#define rank __RAnK
inline ll read(){
	register ll x=0,f=1;register char c=gc();
	for(;!isdigit(c);c=gc())if(c=='-')f=-1;
	for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
#define rd read
void write(ll x){if(x<0)x=-x,pc('-');if(x>=10)write(x/10);putchar(x%10+'0');}
void writeln(ll x){write(x);puts("");}
const int maxn = 100050;
const int maxval = 100050;
const int unit = 400;
int n,m;
int L[maxn/unit+10],R[maxn/unit+10],del[maxn/unit+10],mx[maxn/unit+10];
int bel[maxn];
int pos[maxn/unit+10][maxval];
int a[maxn],val[maxn],fa[maxn],size[maxn];
inline int find(int x){
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void build(int x){
	Rep(i,L[x],R[x]){
		a[i] = val[find(i)];
		pos[x][a[i]] = 0;
		fa[i] = i;
		size[i] = 1;
	}
	mx[x] = 0;
	Rep(i,L[x],R[x]){
		if(!pos[x][a[i]]){
			pos[x][a[i]] = i;
			mx[x] = max(mx[x],a[i]);
			val[i] = a[i];
		} else{
			fa[i] = pos[x][a[i]];
			size[pos[x][a[i]]] += size[i];
		}
	}
	if(mx[x] <= 0){
		for(;;);
	}
//	assert(mx[x] > 0);
//	Rep(i,L[x],R[x]) val[i] = a[i];
}
void modify(int x,int l,int r,int v){
	Rep(i,L[x],R[x]) a[i]=val[find(i)];
	Rep(i,L[x],R[x]) pos[x][a[i]] = 0;
	Rep(i,l,r) if(a[i]-del[x]>v) a[i]-=v;
	Rep(i,l,r) val[i]=a[i],fa[i]=i;
	build(x);
}
void modify(int l,int r,int x){
	if(bel[l] == bel[r]){
		modify(bel[l],l,r,x);
		return ;
	}
	modify(bel[l],l,R[bel[l]],x);
	modify(bel[r],L[bel[r]],r,x);
	Rep(i,bel[l]+1,bel[r]-1){
		if(mx[i] <= x) continue;
		if(x < mx[i] - del[i] && mx[i] - del[i] <= 2*x){
			Rep(v,del[i]+x+1,mx[i]){
				if(!pos[i][v]) continue;
				if(!pos[i][v-x]){
					pos[i][v-x] = pos[i][v];
					val[pos[i][v]] = v-x;
					pos[i][v] = 0;
				} else{
					size[pos[i][v-x]] += size[pos[i][v]];
					fa[pos[i][v]] = pos[i][v-x];
					pos[i][v] = 0;
				}
			}
			while(!pos[i][mx[i]])mx[i]--;
		}

		if(2*x < mx[i] - del[i]){
			Rep(v,del[i]+1,del[i]+x){
//				assert(pos[i][v] == find(pos[i][v]));
				if(!pos[i][v]) continue;
				if(!pos[i][v+x]){
					pos[i][v+x] = pos[i][v];
					val[pos[i][v]] = v+x;
					pos[i][v]=0;
				} else{
					size[pos[i][v+x]] += size[pos[i][v]];
					fa[pos[i][v]] = pos[i][v+x];
					pos[i][v] = 0;
				}
			}
			del[i] += x;
		}
	}
}

int query(int l,int r,int x){
	int ans = 0;
	if(bel[l] == bel[r]){
		Rep(i,l,r) ans += ((val[find(i)] - del[bel[i]]) == x);
		return ans;
	}
	Rep(i,l,R[bel[l]]) ans += ((val[find(i)] - del[bel[i]]) == x);
	Rep(i,L[bel[r]],r) ans += ((val[find(i)] - del[bel[i]]) == x);
	Rep(i,bel[l]+1,bel[r]-1){
		if(x+del[i]<=100000){
			if(val[pos[i][x+del[i]]] - del[i] != x){
				puts("q234rty");
				exit(0);
			}
//			assert(val[pos[i][x+del[i]]] - del[i] == x);
			ans += size[pos[i][x + del[i]]];
		}
	}
	return ans;
}

int main(){
//	freopen("1.in","r",stdin);
	n = rd(),m = rd();
	Rep(i,1,n){
		val[i] = rd();fa[i] = i;
		bel[i] = (i-1) / unit + 1;
		if(!L[bel[i]]) L[bel[i]] = i;
		R[bel[i]] = i;
	}
	Rep(i,1,bel[n]) build(i);
	Rep(i,1,m){
		int opt = rd();
		int l = rd(),r = rd(),x = rd();
		if(opt == 1){
			modify(l,r,x);
		} else{
			writeln(query(l,r,x));
		}
	}
	return 0;
}