#include <bits/stdc++.h>
using namespace std;
const int N = 100005, BLO = 320;
int n, m, opt, l, r, x, a[N];
class FileInputOutput {
 private:
  char Fin[1 << 21], Fout[1 << 21], *A, *B;
  int Ftop, pt[15];

 public:
  inline void read(int &x) {
    x = 0;
    char ch;
    while (!isdigit(
        ch = (A == B && (B = (A = Fin) + fread(Fin, 1, 1 << 21, stdin), A == B)
                  ? EOF
                  : *A++)))
      ;
    while (
        x = (x << 3) + (x << 1) + (ch & 15),
        isdigit(ch = (A == B && (B = (A = Fin) + fread(Fin, 1, 1 << 21, stdin),
                                 A == B)
                          ? EOF
                          : *A++)))
      ;
  }
  inline void write(int x) {
    if (!x)
      return (void)((Ftop < 1 << 21 ? Fout[Ftop++] = '0'
                                    : (fwrite(Fout, 1, 1 << 21, stdout),
                                       Fout[(Ftop = 0)++] = '0')),
                    (Ftop < 1 << 21 ? Fout[Ftop++] = '\n'
                                    : (fwrite(Fout, 1, 1 << 21, stdout),
                                       Fout[(Ftop = 0)++] = '\n')));
    register int ptop = 0;
    while (x) pt[++ptop] = x % 10, x /= 10;
    while (ptop)
      (Ftop < 1 << 21 ? Fout[Ftop++] = pt[ptop--] + 48
                      : (fwrite(Fout, 1, 1 << 21, stdout),
                         Fout[(Ftop = 0)++] = pt[ptop--] + 48));
    (Ftop < 1 << 21
         ? Fout[Ftop++] = '\n'
         : (fwrite(Fout, 1, 1 << 21, stdout), Fout[(Ftop = 0)++] = '\n'));
  }
  inline void Fend(void) { fwrite(Fout, 1, Ftop, stdout); }
} F;
class Brute_Blocks {
 private:
  int size, blk[N], tag[BLO], mx[BLO], t[N], rt[BLO][N], val[N], fa[N];
  inline int min(int a, int b) { return a < b ? a : b; }
  inline int max(int a, int b) { return a > b ? a : b; }

 public:
  inline int getfa(int x) {
    while (x != fa[x]) x = fa[x] = fa[fa[x]];
    return x;
  }
  inline void set(int id) {
    int lim = min(id * size, n);
    mx[id] = 0;
    for (register int i = (id - 1) * size + 1; i <= lim; ++i) {
      mx[id] = max(mx[id], a[i]);
      t[i] = 1;
      if (rt[id][a[i]])
        fa[i] = rt[id][a[i]], t[rt[id][a[i]]] += t[i];
      else
        val[i] = a[i], fa[i] = i, rt[id][a[i]] = i;
    }
  }
  inline void reset(int id) {
    register int i;
    int lim = min(id * size, n);
    for (i = (id - 1) * size + 1; i <= lim; ++i)
      a[i] = val[getfa(i)], rt[id][a[i]] = 0, a[i] -= tag[id];
    for (i = (id - 1) * size + 1; i <= lim; ++i) fa[i] = 0;
    tag[id] = 0;
  }
  inline void replace(int id, int x, int y) {
    if (rt[id][y])
      fa[rt[id][x]] = rt[id][y], t[rt[id][y]] += t[rt[id][x]];
    else
      rt[id][y] = rt[id][x], val[rt[id][x]] = y;
    rt[id][x] = 0;
  }
  inline void change(int id, int x) {
    if (mx[id] - tag[id] >= 2 * x) {
      for (register int i = tag[id] + 1; i <= tag[id] + x; ++i)
        if (rt[id][i]) replace(id, i, i + x);
      tag[id] += x;
    } else {
      for (register int i = tag[id] + x + 1; i <= mx[id]; ++i)
        if (rt[id][i]) replace(id, i, i - x);
      mx[id] = min(mx[id], tag[id] + x);
    }
  }
  inline int query(int l, int r, int x) {
    register int i;
    int lim = min(blk[l] * size, r), ans = 0;
    for (i = l; i <= lim; ++i)
      if (val[getfa(i)] - tag[blk[l]] == x) ++ans;
    if (blk[l] != blk[r])
      for (i = (blk[r] - 1) * size + 1; i <= r; ++i)
        if (val[getfa(i)] - tag[blk[r]] == x) ++ans;
    for (i = blk[l] + 1; i < blk[r]; ++i)
      if (x + tag[i] < N) ans += t[rt[i][x + tag[i]]];
    return ans;
  }
  inline void modify(int l, int r, int x) {
    register int i;
    int lim = min(blk[l] * size, r);
    reset(blk[l]);
    for (i = l; i <= blk[l] * size; ++i)
      if (a[i] > x) a[i] -= x;
    set(blk[l]);
    if (blk[l] != blk[r]) {
      for (reset(blk[r]), i = (blk[r] - 1) * size + 1; i <= r; ++i)
        if (a[i] > x) a[i] -= x;
      set(blk[r]);
    }
    for (i = blk[l] + 1; i < blk[r]; ++i) change(i, x);
  }
  inline void init(void) {
    register int i;
    size = (int)sqrt(n);
    for (i = 1; i <= n; ++i) blk[i] = (i - 1) / size + 1;
    for (i = 1; i <= blk[n]; ++i) set(i);
  }
} B;
int main() {
  register int i;
  for (F.read(n), F.read(m), i = 1; i <= n; ++i) F.read(a[i]);
  for (B.init(), i = 1; i <= m; ++i) {
    F.read(opt);
    F.read(l);
    F.read(r);
    F.read(x);
    if (opt ^ 1)
      F.write(B.query(l, r, x));
    else
      B.modify(l, r, x);
  }
  return F.Fend(), 0;
}
