#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, SIZE = 1e4 + 10;
int he[N], las[N], L[SIZE], R[SIZE];
int f[SIZE], siz[SIZE], ans[N * 10];
int a[N * 10], b[SIZE], Max = 0, num = 0, lent = 0, del = 0;
int cnt = 0;
int n, m;
struct ques {
  int opt;
  int l, r, x;
} Q[N * 10];
inline int Find(int x) {
  if (x == f[x]) return x;
  return f[x] = Find(f[x]);
}
inline void add(int x, int y) {
  int f1 = Find(x);
  f[y] = f1;
  siz[f1] += siz[y];
}
inline void Merge(int x, int y) {
  if (he[y] == 0) {
    he[y] = he[x];
    b[he[y]] = y;
  } else {
    f[he[x]] = he[y];
    siz[he[y]] += siz[he[x]];
    siz[he[x]] = 0;
  }
  he[x] = 0;
}
inline void Pre(int l, int r, int u) {
  if (u != 1)
    for (int i = 1; i <= r - l + 1; i++) he[b[Find(i)]] = 0;
  Max = del = 0;
  for (int i = 1; i <= r - l + 1; i++) {
    f[i] = i;
    siz[i] = 1;
    b[i] = a[i + L[u] - 1];
    Max = max(Max, b[i]);
  }
  for (int i = l; i <= r; i++) {
    if (!las[a[i]]) {
      he[a[i]] = i - l + 1;
      las[a[i]] = true;
    } else
      add(he[a[i]], i - l + 1);
    Max = max(Max, a[i]);
  }
  for (int i = l; i <= r; i++) {
    las[a[i]] = 0;
  }
}
inline void Modify(int u, int x) {
  if (Max >= (x << 1) + del) {
    for (int i = del + 1; i <= x + del; i++) {
      if (he[i]) {
        Max = max(Max, i + x);
        Merge(i, i + x);
      }
    }
    del += x;
  } else {
    for (int i = del + x + 1; i <= Max; i++) {
      if (he[i]) Merge(i, i - x);
    }
    if (Max > del + x) Max = del + x;
  }
}
inline void Part(int ll, int rr, int l, int r, int u, int x) {
  for (int i = ll; i <= rr; i++) {
    cnt = Find(i - L[u] + 1);
    if (b[cnt] > x + del)
      a[i] = b[cnt] - x;
    else
      a[i] = b[cnt];
  }
  for (int i = l; i < ll; i++) a[i] = b[Find(i - L[u] + 1)];
  for (int i = rr + 1; i <= r; i++) a[i] = b[Find(i - L[u] + 1)];
  Max = 0;
  for (int i = 1; i <= r - l + 1; i++) {
    f[i] = i;
    siz[i] = 1;
    he[b[Find(i)]] = 0;
    b[i] = a[i + L[u] - 1] - del;
    Max = max(Max, b[i]);
  }
  del = 0;
  for (int i = l; i <= r; i++) {
    if (!las[a[i]])
      he[a[i]] = i - l + 1, las[a[i]] = true;
    else
      add(las[a[i]], i - l + 1);
    Max = max(Max, a[i]);
  }
  for (int i = l; i <= r; i++) {
    las[a[i]] = 0;
  }
}
inline int ask(int l, int r, int u, int val) {
  if (val + del > N - 10) return 0;
  if (l <= L[u] && r >= R[u]) {
    return siz[he[val + del]];
  } else {
    cnt = 0;
    l = max(l, L[u]), r = min(r, R[u]);
    for (int i = l; i <= r; i++) {
      cnt += (b[Find(i - L[u] + 1)] == val + del);
    }
    return cnt;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  cin >> n >> m;
  num = sqrt(n - 1) + 1, lent = sqrt(n);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= m; i++) {
    int opt, x, l, r;
    cin >> opt >> l >> r >> x;
    Q[i] = (ques){opt, l, r, x};
  }
  for (int i = 1; i <= n; i += lent) {
    L[++cnt] = i, R[cnt] = i + lent - 1;
  }
  if (R[cnt] > n) R[cnt] = n;
  for (int i = 1; i <= num; i++) {
    Pre(L[i], R[i], i);
    for (int j = 1; j <= m; j++) {
      if (Q[j].l > R[i] || Q[j].r < L[i]) continue;
      if (Q[j].opt == 2) {
        ans[j] += ask(Q[j].l, Q[j].r, i, Q[j].x);
      } else {
        if (Q[j].l <= L[i] && Q[j].r >= R[i])
          Modify(i, Q[j].x);
        else
          Part(max(L[i], Q[j].l), min(R[i], Q[j].r), L[i], R[i], i, Q[j].x);
      }
    }
  }
  for (int i = 1; i <= m; i++) {
    if (Q[i].opt == 2) cout << ans[i] << '\n';
  }
  return 0;
}
