#include <bits/stdc++.h>
using namespace std;
namespace IO {
int len = 0;
char ibuf[(1 << 20) + 10], *iS, *iT, out[(1 << 20) + 10];
inline int read() {
  static char ch =
      (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, (1 << 20) + 1, stdin),
       (iS == iT ? EOF : *iS++) : *iS++);
  register int x = 0;
  while (!isdigit(ch))
    ch = (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, (1 << 20) + 1, stdin),
          (iS == iT ? EOF : *iS++) : *iS++);
  while (isdigit(ch))
    x = x * 10 + ch - '0',
    ch = (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, (1 << 20) + 1, stdin),
          (iS == iT ? EOF : *iS++) : *iS++);
  return x;
}
inline void write(int x) {
  if (x > 9) write(x / 10);
  out[len++] = x % 10 + '0';
}
}  // namespace IO
using namespace IO;
const int N = 1e5 + 10, BL = 3e2 + 30;
int n, m;
int a[N], val[N], bel[N], s[BL], t[BL], fa[N], siz[BL][N], rt[BL][N], mx[N],
    tag[N], L, C;
inline int find(int x) {
  if (fa[x] == x) return x;
  return fa[x] = find(fa[x]);
}
inline void build(int num) {
  mx[num] = tag[num] = 0;
  for (register int i = s[num]; i <= t[num]; i++) {
    bel[i] = num;
    mx[num] = max(mx[num], a[i]);
    if (!rt[num][a[i]])
      fa[i] = rt[num][a[i]] = i, val[i] = a[i];
    else
      fa[i] = rt[num][a[i]];
    siz[num][a[i]]++;
  }
}
inline void init() {
  L = sqrt(n);
  for (int i = 1; i <= n; i += L) {
    s[++C] = i;
    t[C] = min(n, i + L - 1);
    build(C);
  }
}
inline void merge(int num, int x, int y) {
  if (rt[num][y])
    fa[rt[num][x]] = rt[num][y];
  else {
    rt[num][y] = rt[num][x];
    val[rt[num][y]] = y;
  }
  siz[num][y] += siz[num][x];
  rt[num][x] = siz[num][x] = 0;
}
inline void total_update(int num, int x) {
  if (mx[num] - tag[num] > (x << 1)) {
    for (register int i = tag[num] + 1; i <= tag[num] + x; i++)
      if (rt[num][i]) merge(num, i, i + x);
    tag[num] += x;
  } else {
    for (register int i = mx[num]; i > tag[num] + x; i--)
      if (rt[num][i]) merge(num, i, i - x);
    mx[num] = min(mx[num], tag[num] + x);
  }
}
inline void part_update(int num, int l, int r, int x) {
  for (int i = s[num]; i <= t[num]; i++) {
    a[i] = val[find(i)];
    rt[num][a[i]] = siz[num][a[i]] = 0;
    a[i] -= tag[num];
  }
  int nl = max(s[num], l), nr = min(t[num], r);
  for (register int i = s[num]; i <= t[num]; i++) val[i] = 0;
  for (register int i = nl; i <= nr; i++) a[i] -= x * (a[i] > x);
  build(num);
}
inline void update(int l, int r, int x) {
  int nl = bel[l], nr = bel[r];
  part_update(nl, l, r, x);
  part_update(nr, l, r, x);
  for (register int i = nl + 1; i < nr; i++) total_update(i, x);
}
inline int query(int l, int r, int x) {
  int nl = bel[l], nr = bel[r];
  int ans = 0;
  if (nl == nr) {
    for (register int i = l; i <= r; i++)
      if (val[find(i)] - tag[nl] == x) ans++;
    return ans;
  }
  for (register int i = l; i <= t[nl]; i++)
    if (val[find(i)] - tag[nl] == x) ans++;
  for (register int i = s[nr]; i <= r; i++)
    if (val[find(i)] - tag[nr] == x) ans++;
  for (register int i = nl + 1; i < nr; i++)
    if (x + tag[i] <= 5e5) ans += siz[i][x + tag[i]];
  return ans;
}
int main() {
  n = read();
  m = read();
  for (register int i = 1; i <= n; i++) a[i] = read();
  init();
  for (register int i = 1; i <= m; i++) {
    int opt, l, r, x;
    opt = read();
    l = read();
    r = read();
    x = read();
    if (opt == 1)
      update(l, r, x);
    else
      write(query(l, r, x)), out[len++] = '\n';
  }
  fwrite(out, 1, len, stdout);
  return 0;
}
