#include <bits/stdc++.h>
using namespace std;
int n, m, block_size;
struct block {
  int a[320], l, r, lz, mx, f[320], h[100005], val[320], sz[320];
  block() {
    l = r = lz = mx = 0;
    memset(a, 0, sizeof(a));
    memset(f, 0, sizeof(f));
    memset(h, 0, sizeof(h));
    memset(val, 0, sizeof(val));
    memset(sz, 0, sizeof(sz));
  }
  int fd(int x) {
    if (f[x] != x) f[x] = fd(f[x]);
    return f[x];
  }
  void get_mx() {
    while (!h[mx]) mx--;
  }
  void build() {
    int len = r - l + 1;
    for (int i = 1; i <= len; i++) {
      a[i] = val[fd(i)];
      h[a[i]] = 0;
    }
    for (int i = 1; i <= len; i++) {
      f[i] = i;
      sz[i] = 1;
    }
    for (int i = 1; i <= len; i++)
      if (!h[a[i]])
        h[val[i] = a[i]] = i;
      else
        sz[f[i] = h[a[i]]] += sz[i];
    get_mx();
  }
  void chg_part(int ll, int rr, int x) {
    int len = r - l + 1;
    for (int i = 1; i <= len; i++) a[i] = val[fd(i)];
    for (int i = 1; i <= len; i++) {
      f[i] = i;
      val[i] = a[i];
    }
    for (int i = ll; i <= rr; i++) {
      h[a[i]] = 0;
      if (a[i] - lz > x) a[i] -= x;
      val[i] = a[i];
    }
    build();
  }
  void chg_all(int x) {
    if (x * 2 <= mx - lz) {
      for (int i = lz + 1; i <= lz + x; i++)
        if (h[i])
          if (h[i + x]) {
            f[h[i]] = h[i + x];
            sz[h[i + x]] += sz[h[i]];
            sz[h[i]] = 0;
            h[i] = 0;
          } else {
            h[i + x] = h[i];
            val[h[i + x]] = i + x;
            h[i] = 0;
          }
      lz += x;
    } else {
      for (int i = lz + x + 1; i <= mx; i++)
        if (h[i])
          if (h[i - x]) {
            f[h[i]] = h[i - x];
            sz[h[i - x]] += sz[h[i]];
            sz[h[i]] = 0;
            h[i] = 0;
          } else {
            h[i - x] = h[i];
            val[h[i - x]] = i - x;
            h[i] = 0;
          }
      get_mx();
    }
  }
  int get_part(int l, int r, int x) {
    int ans = 0;
    for (int i = l; i <= r; i++) {
      a[i] = val[fd(i)];
      if (a[i] - lz == x) ans++;
    }
    return ans;
  }
  int get_all(int x) {
    if (x + lz <= 100000 && h[x + lz])
      return sz[h[x + lz]];
    else
      return 0;
  }
} a[320];
void chg(int l, int r, int x) {
  int bl = l / block_size, br = r / block_size;
  if (bl == br) {
    a[bl].chg_part(l - a[bl].l + 1, r - a[bl].l + 1, x);
    return;
  }
  a[bl].chg_part(l - a[bl].l + 1, a[bl].r - a[bl].l + 1, x);
  a[br].chg_part(1, r - a[br].l + 1, x);
  for (int i = bl + 1; i < br; i++) a[i].chg_all(x);
}
int get(int l, int r, int x) {
  int bl = l / block_size, br = r / block_size;
  if (bl == br) return a[bl].get_part(l - a[bl].l + 1, r - a[bl].l + 1, x);
  int ans = a[bl].get_part(l - a[bl].l + 1, a[bl].r - a[bl].l + 1, x) +
            a[br].get_part(1, r - a[br].l + 1, x);
  for (int i = bl + 1; i < br; i++) ans += a[i].get_all(x);
  return ans;
}
void print() {
  int bn = n / block_size;
  for (int i = 0; i <= bn; i++) {
    printf("l:%d r:%d mx:%d lz:%d\n", a[i].l, a[i].r, a[i].mx, a[i].lz);
    for (int j = 1; j <= a[i].r - a[i].l + 1; j++)
      printf("%d %d %d\n", a[i].a[j], a[i].f[j], a[i].val[j]);
    puts("");
    for (int j = 1; j <= 128; j++)
      printf("%d %d\n", a[i].h[j], a[i].sz[a[i].h[j]]);
    puts("");
  }
}
int main() {
  scanf("%d%d", &n, &m);
  block_size = lround(floor(sqrt(n)));
  for (int i = 1; i <= n; i++) {
    int bl = i / block_size;
    if (!a[bl].l) a[bl].l = i;
    a[bl].r = max(a[bl].r, i);
  }
  for (int i = 1; i <= n; i++) {
    int bl = i / block_size;
    int pos = i - a[bl].l + 1;
    scanf("%d", &a[bl].a[pos]);
    a[bl].val[pos] = a[bl].a[pos];
    a[bl].f[pos] = pos;
  }
  int bn = n / block_size;
  for (int i = 0; i <= bn; i++) {
    a[i].mx = 100004;
    a[i].build();
  }
  while (m--) {
    int op, l, r, x;
    scanf("%d%d%d%d", &op, &l, &r, &x);
    if (op == 1)
      chg(l, r, x);
    else
      printf("%d\n", get(l, r, x));
  }
}
