#include <bits/stdc++.h>
inline int read() {
  int j;
  char c;
  for (c = getchar(); !isdigit(c); c = getchar())
    ;
  for (j = 0; isdigit(c); j = (j << 1) + (j << 3) + (c ^ 48), c = getchar())
    ;
  return j;
}
inline void write(int x) {
  if (x > 9) {
    write(x / 10);
  }
  putchar(x % 10 + '0');
}
inline int max(int x, int y) { return x > y ? x : y; }
inline int min(int x, int y) { return x < y ? x : y; }
const int N = 1e6 + 10;
const int M = 5e5 + 10;
struct Node {
  int opt, l, r, x;
} q[M];
int n, m, block, cnt, tag, maxn;
int a[N], pos[N], l[N], r[N], f[N], v[N], g[N], tot[N], ans[M];
inline int find(int x) {
  while (x != f[x]) {
    f[x] = f[f[x]];
    x = f[x];
  }
  return x;
}
inline void Marry(int x, int y) {
  if (v[y]) {
    f[v[x]] = v[y];
  } else {
    v[y] = v[x];
    g[v[y]] = y;
  }
  tot[y] += tot[x];
  tot[x] = v[x] = 0;
}
inline void Build(int x) {
  maxn = tag = 0;
  memset(v, 0, sizeof v);
  memset(tot, 0, sizeof tot);
  for (register int i = l[x]; i <= r[x]; i++) {
    maxn = max(maxn, a[i]);
    if (v[a[i]]) {
      f[i] = v[a[i]];
    } else {
      f[i] = v[a[i]] = i;
      g[i] = a[i];
    }
    tot[a[i]]++;
  }
}
inline void Modify(int x) {
  if (maxn - tag >= (x << 1)) {
    for (register int i = tag + 1; i <= tag + x; i++) {
      if (v[i]) {
        Marry(i, i + x);
      }
    }
    tag += x;
  } else {
    for (register int i = x + tag + 1; i <= maxn; i++) {
      if (v[i]) {
        Marry(i, i - x);
      }
    }
    maxn = min(maxn, x + tag);
  }
}
inline void ReBuild(int x, int j) {
  for (register int i = l[x]; i <= r[x]; i++) {
    a[i] = g[find(i)];
    tot[a[i]] = v[a[i]] = 0;
    a[i] -= tag;
  }
  for (register int i = l[x]; i <= r[x]; i++) {
    g[i] = 0;
  }
  int qr = min(r[x], q[j].r);
  for (register int i = max(l[x], q[j].l); i <= qr; i++) {
    if (a[i] > q[j].x) {
      a[i] -= q[j].x;
    }
  }
  maxn = tag = 0;
  for (register int i = l[x]; i <= r[x]; i++) {
    maxn = max(maxn, a[i]);
    if (v[a[i]]) {
      f[i] = v[a[i]];
    } else {
      f[i] = v[a[i]] = i;
      g[i] = a[i];
    }
    tot[a[i]]++;
  }
}
inline void query(int x, int j) {
  if (l[x] >= q[j].l && r[x] <= q[j].r) {
    ans[j] += tot[q[j].x + tag];
  } else {
    int qr = min(r[x], q[j].r);
    for (register int i = max(l[x], q[j].l); i <= qr; i++) {
      if (g[find(i)] == q[j].x + tag) {
        ans[j]++;
      }
    }
  }
}
signed main() {
  n = read();
  m = read();
  block = std::sqrt(n);
  cnt = n / block + (n % block != 0);
  for (register int i = 1; i <= n; i++) {
    a[i] = read();
    pos[i] = (i - 1) / block + 1;
  }
  for (register int i = 1; i <= cnt; i++) {
    l[i] = (i - 1) * block + 1;
    r[i] = i * block;
  }
  r[cnt] = n;
  for (register int i = 1; i <= m; i++) {
    q[i].opt = read();
    q[i].l = read();
    q[i].r = read();
    q[i].x = read();
  }
  for (register int i = 1; i <= cnt; i++) {
    Build(i);
    for (register int j = 1; j <= m; j++) {
      if (q[j].r < l[i] || q[j].l > r[i]) {
        continue;
      }
      if (q[j].opt == 1) {
        if (l[i] >= q[j].l && r[i] <= q[j].r) {
          Modify(q[j].x);
        } else {
          ReBuild(i, j);
        }
      } else {
        query(i, j);
      }
    }
  }
  for (register int i = 1; i <= m; i++) {
    if (q[i].opt == 2) {
      write(ans[i]);
      putchar('\n');
    }
  }
  return 0;
}
