#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("avx")
#pragma GCC diagnostic ignored "-Wunused-result"
#pragma GCC diagnostic ignored "-Wunused-function"
using namespace std;
namespace {
namespace shik {
inline int read_char() {
  static char buf[1 << 16], *ptr = buf, *end_ptr = buf;
  if (ptr == end_ptr) {
    int len = fread(buf, 1, sizeof(buf), stdin);
    if (len <= 0) return EOF;
    ptr = buf;
    end_ptr = buf + len;
  }
  return *ptr++;
}
inline int read_int() {
  int sg = +1, ch;
  do {
    ch = read_char();
    if (ch == '-') sg = -1;
  } while (ch < '0' || ch > '9');
  int x = ch - '0';
  while (true) {
    ch = read_char();
    if (ch < '0' || ch > '9') break;
    x = x * 10 + ch - '0';
  }
  return sg * x;
}
void _R(int &x) { x = read_int(); }
void R() {}
template <class T, class... U>
void R(T &head, U &...tail) {
  _R(head);
  R(tail...);
}
template <class T>
void _W(const T &x) {
  cout << x;
}
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%" PRId64, x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T>
void _W(const vector<T> &x) {
  for (auto i = x.begin(); i != x.end(); _W(*i++))
    if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &...tail) {
  _W(head);
  putchar(sizeof...(tail) ? ' ' : '\n');
  W(tail...);
}
template <class T, class F = less<T>>
void sort_uniq(vector<T> &v, F f = F()) {
  sort(begin(v), end(v), f);
  v.resize(unique(begin(v), end(v)) - begin(v));
}
template <class T>
inline T bit(T x, int i) {
  return (x >> i) & 1;
}
template <class T>
inline bool chkmax(T &a, const T &b) {
  return b > a ? a = b, true : false;
}
template <class T>
inline bool chkmin(T &a, const T &b) {
  return b < a ? a = b, true : false;
}
template <class T>
using MaxHeap = priority_queue<T>;
template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;
template <class T, T x1, T x2, T x3, int y1, int y2, int y3>
struct PRNG {
  using S = typename make_signed<T>::type;
  T s;
  PRNG(T _s = 0) : s(_s) {}
  T next() {
    T z = (s += x1);
    z = (z ^ (z >> y1)) * x2;
    z = (z ^ (z >> y2)) * x3;
    return z ^ (z >> y3);
  }
  T next(T n) { return next() % n; }
  S next(S l, S r) { return l + next(r - l + 1); }
  T operator()() { return next(); }
  T operator()(T n) { return next(n); }
  S operator()(S l, S r) { return next(l, r); }
  static T gen(T s) { return PRNG(s)(); }
  template <class U>
  void shuffle(U first, U last) {
    size_t n = last - first;
    for (size_t i = 0; i < n; i++) swap(first[i], first[next(i + 1)]);
  }
};
using R32 = PRNG<uint32_t, 0x9E3779B1, 0x85EBCA6B, 0xC2B2AE35, 16, 13, 16>;
R32 r32;
using R64 = PRNG<uint64_t, 0x9E3779B97F4A7C15, 0xBF58476D1CE4E5B9,
                 0x94D049BB133111EB, 30, 27, 31>;
R64 r64;
const int N = 1e5 + 10;
int n, m;
float __attribute__((aligned(32))) a[N];
void main() {
  n = read_int();
  m = read_int();
  for (int i = (1); i <= int(n); i++) a[i] = read_int();
  for (int mi = 0; mi < int(m); mi++) {
    int op, l, r, x;
    op = read_int();
    l = read_int();
    r = read_int();
    x = read_int();
    if (op == 1) {
      for (int i = (l); i <= int(r); i++)
        if (a[i] > x) a[i] -= x;
    } else {
      int ans = 0;
      for (int i = (l); i <= int(r); i++)
        if (a[i] == x) ans++;
      W(ans);
    }
  }
}
}  // namespace shik
}  // namespace
int main() {
  shik::main();
  return 0;
}
