/**
 * @Date:   2019-03-26T14:57:49+08:00
 * @Last modified time: 2019-03-26T14:57:50+08:00
 */
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
#include <iostream>
#include <cstdio>
#include <complex>
#include <algorithm>
#define A 100001
#define R register
#define B 317
#define void inline void

using namespace std;
typedef long long ll;
int bl[A], c[B][A], f[B], w[B], n, m, opt, wl[B], wr[B], fa[A], l, r, x, a[A];
int p[A];
int find(int x) {
    if (x == fa[x]) return x;
    else return fa[x] = find(fa[x]);
}
void prepare(int fr) {
    for (R int i = wl[fr]; i <= wr[fr]; i++)
        if (!c[fr][a[i]]) c[fr][a[i]] = i, fa[i] = i, p[c[fr][a[i]]] = 1;
        else fa[i] = c[fr][a[i]], p[c[fr][a[i]]]++;
}
void rebuild(int f1, int f2, int f3) {
    if (!c[f1][f3]) {
        c[f1][f3] = c[f1][f2];
        p[c[f1][f3]] = p[c[f1][f2]];
        a[c[f1][f2]] = f3;
    }
    else {
    	fa[c[f1][f2]] = c[f1][f3];
    	p[c[f1][f3]] += p[c[f1][f2]];
	}
	p[c[f1][f2] = 0] = 0;
}
void work(int l, int r, int val) {
	for (R int i = bl[l]; i <= bl[r]; i++) {
		for (R int j = wl[i]; j <= wr[i]; j++) {
			a[j] = a[find(j)];
			p[c[i][a[j]]] = 0;
			c[i][a[j]] = 0;
		}
		for (R int j = wl[i]; j <= wr[i]; j++) a[j] -= f[i], fa[j] = 0;
		f[i] = 0;
	}
	for (R int i = l; i <= r; i++) if (a[i] > val) a[i] -= val;
	for (R int i = bl[l]; i <= bl[r]; i++) prepare(i);
}
void change(int l, int r, int val) {
	if (bl[l] + 1 >= bl[r]) {
		work(l, r, val);
		return;
	}
	work(l, wr[bl[l]], val); work(wl[bl[r]], r, val);
    for (R int i = bl[l] + 1; i <= bl[r] - 1; i++) {
        if (val >= w[i] - f[i]) continue;
        if (val * 2 > w[i] - f[i]) {
            for (R int j = f[i] + val + 1; j <= w[i]; j++) if (c[i][j]) rebuild(i, j, j - val);
            w[i] = max(w[i] - val, val + f[i]);
        }
        else {
            for (R int j = f[i] + 1; j <= f[i] + val; j++) if (c[i][j]) rebuild(i, j, j + val);
            f[i] += val;
        }
    }
}
int ask(int l, int r, int val, int ans = 0) {
	if (bl[l] + 1 >= bl[r]) {
		for (int i = l; i <= r; i++) if (a[find(i)] - f[bl[i]] == val) ans++;
		return ans;
	}
    for (R int i = l; i <= wr[bl[l]]; i++) if (a[find(i)] - f[bl[i]] == val) ans++;
    for (R int i = wl[bl[r]]; i <= r; i++) if (a[find(i)] - f[bl[i]] == val) ans++;
    for (R int i = bl[l] + 1; i <= bl[r] - 1; i++) if (val + f[i] < A - 10) ans += p[c[i][val + f[i]]];
    return ans;
}
inline char GETCHAR() {
	static char buf[B], *p1 = buf, *p2 = buf;
	return p1 == p2 and (p2 = (p1 = buf) + fread(buf, 1, B, stdin), p1 == p2) ? EOF : *p1++;
}
template<class T> void read(T &x) {
	x = 0; char ch = GETCHAR();
	while (!isdigit(ch)) ch = GETCHAR();
	while (isdigit(ch)) x = x * 10 + ch - 48, ch = GETCHAR();
}
void write(int x) {
	if (x > 9) write(x / 10);
	putchar(x % 10 | '0');
}

int main(int argc, char const *argv[]) {
	read(n); read(m); int kn = sqrt(n) + 1;
    for (R int i = 1; i <= n; i++) {
    	read(a[i]);
        bl[i] = (i - 1) / kn + 1;
        fa[i] = i;
        if (!wl[bl[i]]) wl[bl[i]] = i;
        wr[bl[i]] = i;
        w[bl[i]] = max(w[bl[i]], a[i]);
    }
    for (R int i = 1; i <= bl[n]; i++) prepare(i);
    while (m--) {
        read(opt); read(l); read(r); read(x);
        if (opt == 1) change(l, r, x);
        else write(ask(l, r, x)), puts("");
    }
    return 0;
}