#include <bits/stdc++.h>
const int N = 100005;
const int bit = 9;
int n, m;
int root[((N) >> bit) + 1][N], a[N], f[N], size[N], tag[((N) >> bit) + 1],
    max[((N) >> bit) + 1];
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
void clear(int block_id) {
  for (int i = ((block_id) << bit); i < ((block_id) + 1 << bit) && i < n; ++i) {
    a[i] = a[find(i)];
    root[block_id][a[i]] = -1;
    a[i] += tag[block_id];
  }
  tag[block_id] = 0;
}
void rebuild(int block_id) {
  for (int i = ((block_id) << bit); i < ((block_id) + 1 << bit) && i < n; ++i) {
    if (~root[block_id][a[i]])
      f[i] = root[block_id][a[i]], ++size[f[i]], size[i] = 0;
    else
      f[i] = root[block_id][a[i]] = i, size[i] = 1;
    max[block_id] = std::max(max[block_id], a[i]);
  }
}
void merge(int block_id, int x, int y) {
  int &rx = root[block_id][x], &ry = root[block_id][y];
  if (!~rx)
    return;
  else {
    if (!~ry)
      a[rx] = y, ry = rx, rx = -1;
    else
      a[rx] = a[ry], std::tie(rx, ry) = std::minmax({rx, ry}),
      size[rx] += size[ry], f[ry] = rx, ry = -1;
  }
}
void modify(int block_id, int x) {
  if (max[block_id] > x + x) {
    for (int i = 1; i <= x; ++i)
      merge(block_id, i - tag[block_id], i + x - tag[block_id]);
    tag[block_id] -= x;
    max[block_id] -= x;
  } else if (max[block_id] > x) {
    for (int i = 1; i <= max[block_id] - x; ++i)
      if (i + x - tag[block_id] < N)
        merge(block_id, i + x - tag[block_id], i - tag[block_id]);
    max[block_id] = x;
  }
}
void modify(int l, int r, int x) {
  int bl = ((l) >> bit), br = ((r) >> bit);
  if (bl == br) {
    clear(bl);
    for (int i = l; i <= r; ++i)
      if (a[i] > x) a[i] -= x;
    return rebuild(bl);
  }
  clear(bl), clear(br);
  for (int i = l; i < ((bl) + 1 << bit); ++i)
    if (a[i] > x) a[i] -= x;
  for (int i = ((br) << bit); i <= r; ++i)
    if (a[i] > x) a[i] -= x;
  rebuild(bl), rebuild(br);
  for (int i = bl + 1; i < br; ++i) modify(i, x);
}
int query(int l, int r, int x) {
  int bl = ((l) >> bit), br = ((r) >> bit), ans = 0;
  if (bl == br) {
    for (int i = l; i <= r; ++i)
      if (a[find(i)] == x - tag[bl]) ++ans;
    return ans;
  }
  for (int i = l; i < ((bl) + 1 << bit); ++i)
    if (a[find(i)] == x - tag[bl]) ++ans;
  for (int i = ((br) << bit); i <= r; ++i)
    if (a[find(i)] == x - tag[br]) ++ans;
  for (int i = bl + 1; i < br; ++i)
    if (x - tag[i] < N && ~root[i][x - tag[i]])
      ans += size[root[i][x - tag[i]]];
  return ans;
}
int main() {
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> n >> m;
  for (int i = 0; i < n; ++i) std::cin >> a[i];
  for (int i = 0; i < n; ++i) f[i] = i, size[i] = 1;
  std::memset(root, -1, sizeof root);
  for (int i = 0; i <= ((n) >> bit); ++i) rebuild(i);
  for (int i = 0; i < m; ++i) {
    int opt, l, r, x;
    std::cin >> opt >> l >> r >> x, --l, --r;
    if (opt == 1)
      modify(l, r, x);
    else
      std::cout << query(l, r, x) << '\n';
  }
  return 0;
}
