#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
int n, m, f[100005], h[325][100005], cnt[100005], tag[325], v[100005],
    a[100005], mx[325];
int block, l[325], r[325], bel[100005];
inline char nc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline int read() {
  char ch = nc();
  int sum = 0, w = 1;
  while (!(ch >= '0' && ch <= '9')) {
    if (ch == '-') w = -1;
    ch = nc();
  }
  while (ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = nc();
  return sum * w;
}
inline int get(int x) {
  int w, y = x;
  while (y ^ f[y]) {
    y = f[y];
  }
  while (f[x] ^ y) {
    w = x;
    x = f[x];
    f[w] = y;
  }
  return y;
}
inline void getmx(int id) {
  while (!h[id][mx[id]]) {
    mx[id]--;
  }
}
inline void build(int id) {
  register int i;
  for (i = l[id]; i <= r[id]; ++i) {
    a[i] = v[get(i)];
    h[id][a[i]] = 0;
  }
  for (i = l[id]; i <= r[id]; ++i) {
    cnt[i] = 1;
    f[i] = i;
  }
  for (i = l[id]; i <= r[id]; ++i) {
    if (h[id][a[i]]) {
      cnt[h[id][a[i]]] += cnt[i];
      f[i] = h[id][a[i]];
    } else {
      h[id][a[i]] = i;
      v[i] = a[i];
    }
  }
  getmx(id);
}
inline void change(int id, int L, int R, int x) {
  register int i, j;
  for (i = l[id]; i <= r[id]; ++i) {
    a[i] = v[get(i)];
  }
  for (i = l[id]; i <= r[id]; ++i) {
    h[id][a[i]] = 0;
  }
  for (i = L; i <= R; ++i) {
    if (a[i] - tag[id] > x) a[i] -= x;
  }
  for (i = l[id]; i <= r[id]; ++i) {
    v[i] = a[i];
    f[i] = i;
  }
  build(id);
}
inline void modify(int L, int R, int x) {
  register int i, j;
  if (bel[L] == bel[R]) {
    change(bel[L], L, R, x);
    return;
  }
  change(bel[L], L, r[bel[L]], x);
  change(bel[R], l[bel[R]], R, x);
  for (i = bel[L] + 1; i < bel[R]; ++i) {
    if ((x << 1) <= mx[i] - tag[i]) {
      for (j = tag[i] + 1; j <= x + tag[i]; ++j) {
        if (h[i][j]) {
          if (!h[i][j + x]) {
            h[i][j + x] = h[i][j];
            v[h[i][j]] = x + j;
            h[i][j] = 0;
          } else {
            cnt[h[i][j + x]] += cnt[h[i][j]];
            f[h[i][j]] = h[i][j + x];
            h[i][j] = 0;
          }
        }
      }
      tag[i] += x;
    } else {
      for (j = x + tag[i] + 1; j <= mx[i]; ++j) {
        if (h[i][j]) {
          if (!h[i][j - x]) {
            h[i][j - x] = h[i][j];
            v[h[i][j]] = j - x;
            h[i][j] = 0;
          } else {
            cnt[h[i][j - x]] += cnt[h[i][j]];
            f[h[i][j]] = h[i][j - x];
            h[i][j] = 0;
          }
        }
      }
      getmx(i);
    }
  }
}
inline int query(int L, int R, int x) {
  int ans = 0;
  register int i;
  if (bel[L] == bel[R]) {
    for (i = L; i <= R; ++i) {
      if (v[get(i)] - tag[bel[L]] == x) {
        ans++;
      }
    }
    return ans;
  }
  for (i = L; i <= r[bel[L]]; ++i) {
    if (v[get(i)] - tag[bel[L]] == x) {
      ans++;
    }
  }
  for (i = l[bel[R]]; i <= R; ++i) {
    if (v[get(i)] - tag[bel[R]] == x) {
      ans++;
    }
  }
  for (i = bel[L] + 1; i < bel[R]; ++i) {
    if (x + tag[i] <= 100000) {
      ans += cnt[h[i][x + tag[i]]];
    }
  }
  return ans;
}
int main() {
  n = read(), m = read();
  block = sqrt(n);
  register int i;
  for (i = 1; i <= n; ++i) {
    bel[i] = (i - 1) / block + 1;
    f[i] = i;
  }
  for (i = 1; i <= bel[n]; ++i) {
    l[i] = (i - 1) * block + 1;
    r[i] = i * block < n ? i * block : n;
  }
  for (i = 1; i <= n; ++i) {
    v[i] = a[i] = read();
    mx[bel[i]] = a[i] > mx[bel[i]] ? a[i] : mx[bel[i]];
  }
  for (i = 1; i <= bel[n]; ++i) {
    build(i);
  }
  for (i = 1; i <= m; ++i) {
    int opt = read(), L = read(), R = read(), x = read();
    if (opt == 1) {
      modify(L, R, x);
    } else {
      printf("%d\n", query(L, R, x));
    }
  }
  return 0;
}
