#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200500, B = 323;
int bel[MAXN], lazy[B], maxx[B], pa[B][MAXN], a[MAXN];
int bll;
int find(int x) { return pa[bll][x] > 0 ? pa[bll][x] = find(pa[bll][x]) : x; }
inline int find(int bl, int x) {
  bll = bl;
  return find(x);
}
inline void onion(int bl, int x, int y) {
  int xx = find(bl, x), yy = find(bl, y);
  if (xx != yy) {
    pa[bl][yy] += pa[bl][xx];
    pa[bl][xx] = yy;
  }
}
int n, m;
inline void change(int pos, int x) {
  int bl = bel[pos], cur = find(bl, a[pos]);
  if (cur - lazy[bl] > x) {
    a[pos] = cur - x;
    pa[bl][cur]++;
    pa[bl][find(cur - x)]--;
  }
}
inline int query(int pos) {
  int bl = bel[pos];
  return find(bl, a[pos]) - lazy[bl];
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n + n; i++) bel[i] = i / B;
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    pa[bel[i]][a[i]]--;
    maxx[bel[i]] = max(maxx[bel[i]], a[i]);
  }
  int t, l, r, x;
  for (int q = 1; q <= m; q++) {
    scanf("%d%d%d%d", &t, &l, &r, &x);
    l--, r--;
    if (t == 1) {
      if (bel[l] == bel[r]) {
        for (int i = l; i <= r; i++) {
          change(i, x);
        }
        int tmp = 0;
        for (int i = bel[l] * B; i < bel[l] * B + B; i++) {
          tmp = max(tmp, query(i));
        }
        maxx[bel[l]] = tmp;
      } else {
        for (int i = l; i < (bel[l] + 1) * B; i++) {
          change(i, x);
        }
        int tmp = 0;
        for (int i = bel[l] * B; i < bel[l] * B + B; i++) {
          tmp = max(tmp, query(i));
        }
        maxx[bel[l]] = tmp;
        for (int i = (bel[r]) * B; i <= r; i++) {
          change(i, x);
        }
        tmp = 0;
        for (int i = bel[r] * B; i < bel[r] * B + B; i++) {
          tmp = max(tmp, query(i));
        }
        maxx[bel[r]] = tmp;
      }
      for (int bl = bel[l] + 1; bl < bel[r]; bl++) {
        if (maxx[bl] >= 2 * x) {
          for (int i = 1; i <= x; i++) {
            if (i + x + lazy[bl] > 100000) break;
            onion(bl, i + lazy[bl], i + x + lazy[bl]);
          }
          lazy[bl] += x;
          maxx[bl] -= x;
        } else if (maxx[bl] > x) {
          for (int i = x + 1; i <= maxx[bl]; i++) {
            if (i + lazy[bl] > 100000) break;
            onion(bl, i + lazy[bl], i + lazy[bl] - x);
          }
          maxx[bl] = x;
        }
      }
    } else {
      int ans = 0;
      if (bel[l] == bel[r]) {
        for (int i = l; i <= r; i++) {
          ans += (query(i) == x);
        }
      } else {
        for (int i = l; i < (bel[l] + 1) * B; i++) {
          ans += (query(i) == x);
        }
        for (int i = (bel[r]) * B; i <= r; i++) {
          ans += (query(i) == x);
        }
      }
      for (int bl = bel[l] + 1; bl < bel[r]; bl++) {
        ans += -pa[bl][find(bl, x + lazy[bl])];
      }
      printf("%d\n", ans);
    }
  }
  return 0;
}
