#include <bits/stdc++.h>
using namespace std;
int N, M, sq, bcnt;
int arr[100010];
vector<int> add, Mx;
vector<vector<int> > cnt;
struct DSU {
  int par[100010];
  void init() {
    for (int i = 0; i < 100010; i++) {
      par[i] = i;
    }
  }
  int f(int u) {
    if (par[u] == u)
      return u;
    else
      return par[u] = f(par[u]);
  }
  void mrg(int u, int v) {
    u = f(u);
    v = f(v);
    if (u == v) return;
    par[v] = u;
  }
};
vector<DSU> dsu;
void upd_block(int l, int r, int x) {
  for (int i = l; i <= r; i++) {
    int v = dsu[l / sq].f(arr[i]);
    if (v + add[l / sq] > x) {
      arr[i] = v - x;
      cnt[l / sq][v]--;
      cnt[l / sq][v - x]++;
    } else {
      arr[i] = v;
    }
  }
  Mx[l / sq] = 0;
  for (int i = l / sq * sq; i < min(N, l / sq * sq + sq); i++) {
    Mx[l / sq] = max(Mx[l / sq], dsu[l / sq].f(arr[i]));
  }
}
void upd(int l, int r, int x) {
  if (l / sq == r / sq) {
    upd_block(l, r, x);
  } else {
    upd_block(l, l / sq * sq + sq - 1, x);
    upd_block(r / sq * sq, r, x);
    for (int i = l / sq + 1; i < r / sq; i++) {
      if (2 * x <= Mx[i] + add[i]) {
        for (int j = x - add[i]; j >= 1 - add[i]; j--) {
          cnt[i][j + x] += cnt[i][j];
          cnt[i][j] = 0;
          dsu[i].mrg(j + x, j);
        }
        add[i] -= x;
      } else {
        for (int j = x + 1 - add[i]; j <= Mx[i]; j++) {
          cnt[i][j - x] += cnt[i][j];
          cnt[i][j] = 0;
          dsu[i].mrg(j - x, j);
        }
        if (Mx[i] + add[i] > x) Mx[i] -= x;
      }
    }
  }
}
int query_block(int l, int r, int x) {
  int ret = 0;
  for (int i = l; i <= r; i++) {
    if (dsu[l / sq].f(arr[i]) + add[l / sq] == x) ret++;
  }
  return ret;
}
int query(int l, int r, int x) {
  if (l / sq == r / sq) {
    return query_block(l, r, x);
  } else {
    int ret = 0;
    ret += query_block(l, l / sq * sq + sq - 1, x);
    ret += query_block(r / sq * sq, r, x);
    for (int i = l / sq + 1; i < r / sq; i++) {
      ret += cnt[i][x - add[i]];
    }
    return ret;
  }
}
int main() {
  scanf("%d %d", &N, &M);
  sq = sqrt(N);
  bcnt = (N + sq - 1) / sq;
  for (int i = 0; i < N; i++) {
    scanf("%d", &arr[i]);
  }
  add = Mx = vector<int>(bcnt, 0);
  cnt = vector<vector<int> >(bcnt, vector<int>(100010, 0));
  dsu.resize(bcnt);
  for (int i = 0; i < N; i += sq) {
    for (int j = i; j < min(N, i + sq); j++) {
      cnt[i / sq][arr[j]]++;
      Mx[i / sq] = max(Mx[i / sq], arr[j]);
    }
    dsu[i / sq].init();
  }
  for (int i = 0; i < M; i++) {
    int t, l, r, x;
    scanf("%d %d %d %d", &t, &l, &r, &x);
    l--;
    r--;
    if (t == 1) {
      upd(l, r, x);
    } else {
      printf("%d\n", query(l, r, x));
    }
  }
}
