#include <bits/stdc++.h>
using namespace std;
const int S = 330, INF = 100010 - 1;
int a[100010], bel[100010], mx[S], hd[S][100010], tag[S], beg[S], ed[S],
    fa[100010], sz[100010], tn, n, q;
inline void read(int &x) {
  char ch = x = 0;
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
}
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void update_mx(int x) {
  while (!hd[x][mx[x]]) mx[x]--;
}
void build(int x) {
  static int tmp[100010];
  for (int i = beg[x]; i <= ed[x]; i++) tmp[i] = a[find(i)];
  for (int i = beg[x]; i <= ed[x]; i++) hd[x][a[i] = tmp[i]] = 0;
  for (int i = beg[x]; i <= ed[x]; i++) {
    fa[i] = i, sz[i] = 1;
    if (!hd[x][a[i]])
      hd[x][a[i]] = i;
    else
      fa[i] = hd[x][a[i]], sz[hd[x][a[i]]]++;
  }
  update_mx(x);
}
void brute(int l, int r, int x) {
  build(bel[l]);
  for (int i = beg[bel[l]]; i <= ed[bel[l]]; i++) hd[bel[l]][a[i]] = 0;
  for (int i = l; i <= r; i++) {
    if (a[i] - tag[bel[l]] > x) a[i] -= x, fa[i] = i, sz[i] = 1;
  }
  build(bel[l]);
}
void modify(int l, int r, int x) {
  if (bel[l] == bel[r]) {
    brute(l, r, x);
    return;
  }
  brute(l, ed[bel[l]], x), brute(beg[bel[r]], r, x);
  for (int i = bel[l] + 1; i <= bel[r] - 1; i++) {
    if (2 * x <= mx[i] - tag[i]) {
      for (int j = 1; j <= x && j + tag[i] + x <= mx[i]; j++) {
        if (!hd[i][j + tag[i]]) continue;
        mx[i] = max(mx[i], j + x + tag[i]);
        if (hd[i][j + x + tag[i]])
          fa[hd[i][j + tag[i]]] = hd[i][j + x + tag[i]],
                       sz[hd[i][j + x + tag[i]]] += sz[hd[i][j + tag[i]]];
        else
          a[hd[i][j + x + tag[i]] = hd[i][j + tag[i]]] = j + x + tag[i];
        hd[i][j + tag[i]] = 0;
      }
      tag[i] += x;
    } else {
      for (int j = x + 1; j <= mx[i] - tag[i]; j++) {
        if (!hd[i][j + tag[i]]) continue;
        if (hd[i][j - x + tag[i]])
          fa[hd[i][j + tag[i]]] = hd[i][j - x + tag[i]],
                       sz[hd[i][j - x + tag[i]]] += sz[hd[i][j + tag[i]]];
        else
          a[hd[i][j - x + tag[i]] = hd[i][j + tag[i]]] = j - x + tag[i];
        hd[i][j + tag[i]] = 0, update_mx(i);
      }
    }
  }
}
int br_query(int l, int r, int x) {
  int ret = 0;
  build(bel[l]);
  for (int i = l; i <= r; i++) ret += a[i] - tag[bel[l]] == x;
  return ret;
}
int query(int l, int r, int x) {
  if (bel[l] == bel[r]) return br_query(l, r, x);
  int ret = br_query(l, ed[bel[l]], x) + br_query(beg[bel[r]], r, x);
  for (int i = bel[l] + 1; i <= bel[r] - 1; i++) {
    if (x + tag[i] < 100010) ret += sz[hd[i][x + tag[i]]];
  }
  return ret;
}
int main() {
  read(n), read(q);
  for (int i = 1; i <= n; i++) {
    read(a[i]), bel[i] = (i - 1) / S + 1;
    ed[bel[i]] = i;
    if (!beg[bel[i]]) beg[bel[i]] = i;
  }
  tn = bel[n];
  for (int i = 1; i <= n; i++) fa[i] = i, sz[i] = 1;
  for (int i = 1; i <= tn; i++) mx[i] = INF, build(i);
  for (int i = 1, op, l, r, x; i <= q; i++) {
    read(op), read(l), read(r), read(x);
    if (op == 1) modify(l, r, x);
    if (op == 2) printf("%d\n", query(l, r, x));
  }
  return 0;
}
