#include <bits/stdc++.h>
using namespace std;
int gi() {
  char cc = getchar();
  int cn = 0, flus = 1;
  while (cc < '0' || cc > '9') {
    if (cc == '-') flus = -flus;
    cc = getchar();
  }
  while (cc >= '0' && cc <= '9') cn = cn * 10 + cc - '0', cc = getchar();
  return cn * flus;
}
const int N = 1e6 + 5;
const int M = 2500;
const int W = 1e6 + 5;
int n, m, mx, cnt, a[N + 5], fa[N + 6], L[M], R[M], Id[N + 7];
struct node {
  int op, l, r, x, ans;
} opt[N + 4];
int Lef, Ret, w[N + 1], rt[W + 2], RT[N + 3];
int fd(int x) { return (fa[x] == x) ? x : fa[x] = fd(fa[x]); }
void merge(int x, int &y, int z) {
  if (!y) {
    y = x;
    RT[x] = z;
  } else {
    int u = fd(x), v = fd(y);
    fa[u] = v, w[v] += w[u];
  }
}
signed main() {
  n = gi(), m = gi();
  for (int i = (1); i <= (n); ++i) a[i] = gi(), mx = max(mx, a[i]);
  cnt = sqrt(1ll * n * m / mx) + 1;
  int idx = 1;
  L[1] = 1;
  for (int i = (1); i <= (n); ++i) {
    Id[i] = idx;
    if (i % cnt == 0) R[idx] = i, L[++idx] = i + 1;
  }
  if (L[idx] > n) --idx;
  R[idx] = n;
  for (int i = (1); i <= (m); ++i)
    opt[i].op = gi(), opt[i].l = gi(), opt[i].r = gi(), opt[i].x = gi();
  for (int x = 1; x <= idx; ++x) {
    int ll = L[x], rr = R[x];
    for (int i = (0); i <= (mx); ++i) w[i] = 0;
    Lef = Ret = 0;
    for (int i = ll; i <= rr; ++i) Ret = max(Ret, a[i]);
    for (int i = (0); i <= (Ret); ++i) rt[i] = 0;
    for (int i = (ll); i <= (rr); ++i)
      fa[i] = i, w[i] = 1, RT[i] = 0, merge(i, rt[a[i]], a[i]);
    for (int i = 1; i <= m; ++i) {
      if (opt[i].r < ll || opt[i].l > rr) continue;
      int Mx = Ret - Lef, z = opt[i].x;
      if (opt[i].l <= ll && rr <= opt[i].r) {
        if (opt[i].op == 1) {
          if (Mx < z) continue;
          if (Mx >= 2 * z) {
            for (int j = Lef; j <= Lef + z; ++j)
              merge(rt[j], rt[j + z], j + z), rt[j] = 0;
            Lef += z;
          } else {
            for (int j = Lef + z + 1; j <= Ret; ++j)
              merge(rt[j], rt[j - z], j - z), rt[j] = 0;
            Ret -= z;
          }
        } else
          opt[i].ans += w[rt[z + Lef]];
      } else {
        for (int j = (ll); j <= (rr); ++j) a[j] = RT[fd(j)] - Lef;
        for (int j = (ll); j <= (rr); ++j)
          if (fd(j) == j) rt[RT[j]] = 0;
        Lef = 0, Ret = 0;
        if (opt[i].op == 1) {
          int l = max(opt[i].l, ll), r = min(opt[i].r, rr);
          for (int j = l; j <= r; ++j)
            if (a[j] > z) a[j] -= z;
        } else {
          int l = max(opt[i].l, ll), r = min(opt[i].r, rr);
          for (int j = l; j <= r; ++j) opt[i].ans += (a[j] == z);
        }
        for (int j = (ll); j <= (rr); ++j) Ret = max(Ret, a[j]);
        for (int j = (ll); j <= (rr); ++j)
          fa[j] = j, w[j] = 1, RT[j] = 0, merge(j, rt[a[j]], a[j]);
      }
    }
  }
  for (int i = (1); i <= (m); ++i)
    if (opt[i].op == 2) printf("%d\n", opt[i].ans);
  return 0;
}
