#include <bits/stdc++.h>
using namespace std;
int n, m, p, a[100010], opt, ans;
int bl[100010], L[320], R[320];
int Mx[320], lz[320], Num[100010], fa[100010], rt[320][100010], pos[100010];
inline int read() {
  register int tmp = 0;
  register char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9')
    tmp = (tmp << 1) + (tmp << 3) + (c ^ 48), c = getchar();
  return tmp;
}
template <typename T>
inline T Max(const T x, const T y) {
  return x > y ? x : y;
}
template <typename T>
inline T Min(const T x, const T y) {
  return x < y ? x : y;
}
inline int find(int x) {
  while (x != fa[x]) x = fa[x] = fa[fa[x]];
  return x;
}
inline void reset(const int x) {
  Mx[x] = 0;
  for (int i = L[x]; i <= R[x]; i++) {
    Mx[x] = Max(Mx[x], a[i]), Num[i] = 1;
    if (rt[x][a[i]])
      fa[i] = rt[x][a[i]], Num[rt[x][a[i]]] += Num[i];
    else
      pos[i] = a[i], fa[i] = i, rt[x][a[i]] = i;
  }
}
inline void erase(const int x) {
  for (int i = L[x]; i <= R[x]; i++)
    a[i] = pos[find(i)], rt[x][a[i]] = 0, a[i] -= lz[x];
  for (int i = L[x]; i <= R[x]; i++) fa[i] = 0;
  lz[x] = 0;
}
inline void add(const int x, const int val_pre, const int val_now) {
  if (rt[x][val_now])
    fa[rt[x][val_pre]] = rt[x][val_now],
    Num[rt[x][val_now]] += Num[rt[x][val_pre]];
  else
    rt[x][val_now] = rt[x][val_pre], pos[rt[x][val_pre]] = val_now;
  rt[x][val_pre] = 0;
}
inline void Change(const int x, const int w) {
  if (Mx[x] - lz[x] >= w * 2) {
    for (int i = lz[x] + 1; i <= lz[x] + w; i++)
      if (rt[x][i]) add(x, i, i + w);
    lz[x] += w;
  } else {
    for (int i = lz[x] + w + 1; i <= Mx[x]; i++)
      if (rt[x][i]) add(x, i, i - w);
    Mx[x] = Min(Mx[x], lz[x] + w);
  }
}
inline void modify(const int l, const int r, const int w) {
  if (bl[l] == bl[r]) {
    erase(bl[l]);
    for (int i = l; i <= r; i++)
      if (a[i] > w) a[i] -= w;
    reset(bl[l]);
    return;
  }
  erase(bl[l]), erase(bl[r]);
  for (int i = l; i <= R[bl[l]]; i++)
    if (a[i] > w) a[i] -= w;
  for (int i = L[bl[r]]; i <= r; i++)
    if (a[i] > w) a[i] -= w;
  for (int i = bl[l] + 1; i < bl[r]; i++) Change(i, w);
  reset(bl[l]), reset(bl[r]);
  return;
}
inline int query(const int l, const int r, const int w) {
  ans = 0;
  if (bl[l] == bl[r]) {
    for (int i = l; i <= r; i++)
      if (pos[find(i)] == w + lz[bl[i]]) ++ans;
    return ans;
  }
  for (int i = l; i <= R[bl[l]]; i++)
    if (pos[find(i)] == w + lz[bl[l]]) ++ans;
  for (int i = L[bl[r]]; i <= r; i++)
    if (pos[find(i)] == w + lz[bl[r]]) ++ans;
  for (int i = bl[l] + 1; i < bl[r]; i++)
    if (w + lz[i] <= 100000) ans += Num[rt[i][w + lz[i]]];
  return ans;
}
int main() {
  n = read(), m = read(), p = sqrt(n);
  for (int i = 1; i <= n; i++) a[i] = read(), bl[i] = (i - 1) / p + 1;
  for (int i = 1; i <= bl[n]; i++) L[i] = (i - 1) * p + 1, R[i] = i * p;
  R[bl[n]] = n;
  for (int i = 1; i <= bl[n]; i++) reset(i);
  while (m--) {
    opt = read();
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    if (opt == 1)
      modify(x, y, z);
    else
      printf("%d\n", query(x, y, z));
  }
  return 0;
}
