#include <bits/stdc++.h>
namespace IO {
char ibuf[(1 << 21) + 1], obuf[(1 << 21) + 1], st[11], *iS, *iT,
    *oS = obuf, *oT = obuf + (1 << 21);
char Get() {
  return (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, (1 << 21) + 1, stdin),
                      (iS == iT ? EOF : *iS++))
                   : *iS++);
}
void Flush() { fwrite(obuf, 1, oS - obuf, stdout), oS = obuf; }
void Put(char x) {
  *oS++ = x;
  if (oS == oT) Flush();
}
int read() {
  int x = 0, c = Get();
  while (!isdigit(c)) c = Get();
  while (isdigit(c)) x = x * 10 + c - 48, c = Get();
  return x;
}
void write(int x) {
  int top = 0;
  if (!x) Put('0');
  while (x) st[++top] = (x % 10) + 48, x /= 10;
  while (top) Put(st[top--]);
  Put('\n');
}
}  // namespace IO
using namespace IO;
using std::pair;
const int N = 100007;
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int n, m, B, a[N], b[N], f[N];
pair<int, int> v[N];
struct node {
  int o, l, r, x, ans;
} q[N];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
void merge(int x, int y) {
  v[y].first ? f[v[x].first] = v[y].first : b[v[y].first = v[x].first] = y,
               v[y].second += v[x].second, v[x] = {0, 0};
}
int main() {
  n = read(), m = read();
  int B = 310 + (rand() & 7);
  for (int i = 1; i <= n; ++i) a[i] = read();
  for (int i = 1; i <= m; ++i) q[i] = {read(), read(), read(), read()};
  for (int i = 1;; ++i) {
    int L = i * B - B + 1, R = min(n, i * B), mx, tag = 0;
    if (L > n) break;
    memset(v, 0, sizeof v), mx = 0;
    for (int k = L, x; k <= R; ++k)
      mx = max(mx, x = a[k]),
      v[x].first ? f[k] = v[x].first : (b[v[x].first = f[k] = k] = x),
      ++v[x].second;
    ;
    for (int j = 1; j <= m; ++j) {
      int l = q[j].l, r = q[j].r, x = q[j].x;
      if (r < L || R < l) continue;
      if (q[j].o == 1) {
        if (l <= L && R <= r) {
          if ((x << 1) <= mx - tag) {
            for (int k = tag + 1; k <= tag + x; ++k)
              if (v[k].first) merge(k, k + x);
            tag += x;
          } else {
            for (int k = mx; k > tag + x; --k)
              if (v[k].first) merge(k, k - x);
            mx = min(mx, tag + x);
          }
        } else {
          for (int k = L; k <= R; ++k)
            a[k] = b[find(k)], v[a[k]] = {0, 0}, a[k] -= tag;
          memset(b + L, 0, (R - L + 1) << 2), tag = 0;
          l = max(l, L), r = min(r, R);
          for (int k = l; k <= r; ++k)
            if (a[k] > x) a[k] -= x;
          mx = 0;
          for (int k = L, x; k <= R; ++k)
            mx = max(mx, x = a[k]),
            v[x].first ? f[k] = v[x].first : (b[v[x].first = f[k] = k] = x),
            ++v[x].second;
          ;
        }
      } else {
        if (l <= L && R <= r) {
          if (x + tag <= 100000) q[j].ans += v[x + tag].second;
        } else {
          l = max(l, L), r = min(r, R);
          for (int k = l; k <= r; ++k)
            if (b[find(k)] == tag + x) ++q[j].ans;
        }
      }
    }
  }
  for (int i = 1; i <= m; ++i)
    if (q[i].o == 2) write(q[i].ans);
  return Flush(), 0;
}
