#include <bits/stdc++.h>
const int siz = 333, N = 1.3e5;
struct istream {
  template <typename T>
  inline istream& operator>>(T& d) {
    static int c;
    d = 0;
    for (c = getchar(); !isdigit(c); c = getchar())
      ;
    for (; isdigit(c); c = getchar()) d = (d << 3) + (d << 1) + (c ^ '0');
    return *this;
  }
} cin;
int n, m, fa[N], blo, L[siz + 1], R[siz + 1], bel[N], a[N], mx[N], tag[N],
    pos[N];
int val[100011 / siz + 10][N], num[N];
int find(const int& x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void build(int id) {
  mx[id] = 0;
  int* v = val[id];
  for (int i = L[id]; i <= R[id]; ++i) {
    mx[id] = std::max(mx[id], a[i]);
    if (!v[a[i]])
      v[a[i]] = fa[i] = i, pos[i] = a[i];
    else
      fa[i] = v[a[i]];
    ++num[v[a[i]]];
  }
}
inline void change(const int& id) {
  for (int i = L[id]; i <= R[id]; ++i) {
    a[i] = pos[find(i)];
    val[id][a[i]] = num[val[id][a[i]]] = 0;
    a[i] -= tag[id];
  }
  for (int i = L[id]; i <= R[id]; ++i) fa[i] = 0;
  tag[id] = 0;
}
inline void modify2(const int& id, const int& x, const int& to) {
  if (num[val[id][to]]) {
    fa[val[id][x]] = val[id][to];
    num[val[id][to]] += num[val[id][x]];
    num[val[id][x]] = 0;
  } else
    val[id][to] = val[id][x], pos[val[id][x]] = to;
  val[id][x] = 0;
}
void change(const int& id, const int& x) {
  const int* v = val[id];
  if (x << 1 < mx[id] - tag[id]) {
    for (int i = tag[id] + 1; i <= tag[id] + x; ++i)
      if (num[v[i]]) modify2(id, i, i + x);
    tag[id] += x;
  } else {
    for (int i = tag[id] + x + 1; i <= mx[id]; ++i)
      if (num[v[i]]) modify2(id, i, i - x);
    mx[id] = std::min(mx[id], x + tag[id]);
  }
}
void modify(const int& l, const int& r, const int& x) {
  if (bel[l] == bel[r]) {
    change(bel[l]);
    for (int i = l; i <= r; ++i)
      if (a[i] > x) a[i] -= x;
    build(bel[l]);
  } else {
    const int &bl = bel[l], &br = bel[r];
    change(bl), change(br);
    for (int i = l; i <= R[bl]; ++i)
      if (a[i] > x) a[i] -= x;
    for (int i = L[br]; i <= r; ++i)
      if (a[i] > x) a[i] -= x;
    build(bl), build(br);
    for (int i = bl + 1; i < br; ++i) change(i, x);
  }
}
inline int query(int l, int r, int x) {
  int ret = 0;
  if (bel[l] == bel[r]) {
    for (int i = l; i <= r; ++i)
      if (pos[find(i)] == x + tag[bel[l]]) ++ret;
  } else {
    const int &bl = bel[l], &br = bel[r];
    for (int i = l; i <= R[bl]; ++i)
      if (pos[find(i)] == x + tag[bl]) ++ret;
    for (int i = L[br]; i <= r; ++i)
      if (pos[find(i)] == x + tag[br]) ++ret;
    for (int i = bl + 1; i < br; ++i) ret += num[val[i][tag[i] + x]];
  }
  return ret;
}
int main() {
  cin >> n >> m;
  blo = (n - 1) / siz + 1;
  for (int i = 1; i < blo; ++i) L[i] = (i - 1) * siz + 1, R[i] = i * siz;
  L[blo] = (blo - 1) * siz + 1, R[blo] = n;
  for (int i = 1; i <= blo; ++i)
    for (int j = L[i]; j <= R[i]; ++j) bel[j] = i;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  for (int i = 1; i <= blo; ++i) build(i);
  while (m--) {
    int op, l, r, x;
    cin >> op >> l >> r >> x;
    if (op == 1)
      modify(l, r, x);
    else
      printf("%d\n", query(l, r, x));
  }
  return 0;
}
