#include <bits/stdc++.h>
using namespace std;
template <class C>
void mini(C &a4, C b4) {
  a4 = min(a4, b4);
}
template <class C>
void maxi(C &a4, C b4) {
  a4 = max(a4, b4);
}
template <class TH>
void _dbg(const char *sdbg, TH h) {
  cerr << sdbg << "=" << h << "\n";
}
template <class TH, class... TA>
void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',') cerr << *sdbg++;
  cerr << "=" << h << ",";
  _dbg(sdbg + 1, a...);
}
template <class T>
ostream &operator<<(ostream &os, vector<T> V) {
  os << "[";
  for (auto vv : V) os << vv << ",";
  return os << "]";
}
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
const int maxN = 1e5;
struct fu {
  vector<int> f;
  vector<int> root2Number;
  vector<int> root;
  vector<int> rootSizes;
  fu(vector<int> &inp) {
    int n = ((int)(inp).size());
    f.resize(n);
    root2Number.resize(n, -1);
    rootSizes.resize(n, 1);
    root.resize(maxN + 1, -1);
    for (int i = (0); i <= ((int)(n)-1); i++) f[i] = i;
    for (int i = (0); i <= ((int)(((int)(inp).size())) - 1); i++) {
      un2(i, inp[i]);
    }
  }
  void reinit(vector<int> &inp) {
    int n = ((int)(inp).size());
    for (int i = (0); i <= ((int)(n)-1); i++) {
      rootSizes[i] = 1;
      if (root2Number[i] != -1) {
        root[root2Number[i]] = -1;
      }
      root2Number[i] = -1;
      f[i] = i;
    }
    for (int i = (0); i <= ((int)(((int)(inp).size())) - 1); i++) {
      un2(i, inp[i]);
    }
  }
  int fi(int a) { return f[a] == a ? a : f[a] = fi(f[a]); }
  void oldUn(int a, int b) {
    int tmp1 = fi(a);
    int tmp2 = fi(b);
    int sa = rootSizes[tmp1];
    int sb = rootSizes[tmp2];
    rootSizes[tmp1] = 0;
    rootSizes[tmp2] = sa + sb;
    f[tmp1] = tmp2;
  }
  void un2(int a, int b) {
    if (root2Number[a] == b) return;
    if (root2Number[a] != -1) {
      root[root2Number[a]] = -1;
    }
    if (root[b] == -1) {
      root[b] = a;
      root2Number[a] = b;
    } else {
      oldUn(a, root[b]);
    }
  }
  void un(int a, int b) {
    if (root[a] == -1) return;
    un2(root[a], b);
  }
  int get(int a) { return root2Number[fi(a)]; }
  int getSize(int a) {
    if (a > maxN) {
      return 0;
    }
    if (root[a] == -1) {
      return 0;
    }
    return rootSizes[root[a]];
  }
  bool exists(int a) { return root[a] != -1; }
};
int counter = 0;
void update(int l, int r, int x, fu &fUnion, vector<int> &part, int &off,
            pair<int, int> interval, pair<int, int> &range) {
  if (interval.first >= l && interval.second <= r) {
    if (2 * x >= range.second - off) {
      for (int i = x + off + 1; i <= range.second; i++) {
        fUnion.un(i, i - x);
      }
      mini(range.second, off + x);
      mini(range.first, range.second);
    } else {
      for (int i = off + x; i >= off + 1; i--) {
        fUnion.un(i, i + x);
      }
      maxi(range.first, off + x);
      maxi(range.second, range.first);
      off += x;
    }
    return;
  }
  if (interval.first >= r || interval.second <= l) {
    return;
  }
  counter++;
  for (int i = (0); i <= ((int)(((int)(part).size())) - 1); i++) {
    part[i] = fUnion.get(i) - off;
  }
  l = max(0, l - interval.first);
  r = min(((int)(part).size()), r - interval.first);
  for (int i = l; i < r; i++) {
    if (part[i] > x) {
      part[i] -= x;
    }
  }
  fUnion.reinit(part);
  off = 0;
  range = {*min_element((part).begin(), (part).end()),
           *max_element((part).begin(), (part).end())};
}
int getAns(int l, int r, int x, fu &fUnion, const vector<int> &part,
           const int &off, pair<int, int> interval) {
  x += off;
  if (interval.first >= l && interval.second <= r) {
    return fUnion.getSize(x);
  }
  if (interval.first >= r || interval.second <= l) {
    return 0;
  }
  l = max(0, l - interval.first);
  r = min(((int)(part).size()), r - interval.first);
  int co = 0;
  for (int i = l; i < r; i++) {
    co += fUnion.get(i) == x;
  }
  return co;
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(11);
  if (0) cout << fixed << setprecision(6);
  int n, m;
  cin >> n >> m;
  vector<int> inp(n);
  int partSize = sqrt(n);
  for (int i = (0); i <= ((int)(n)-1); i++) {
    cin >> inp[i];
  }
  vector<fu> fUnions;
  vector<vector<int> > parts;
  vector<pair<int, int> > interval;
  vector<pair<int, int> > range;
  vector<int> off;
  for (auto it = inp.begin(); it != inp.end();) {
    parts.push_back({});
    for (int i = (0); i <= ((int)(partSize)-1); i++) {
      if (it == inp.end()) break;
      parts.back().push_back(*it++);
    }
    fUnions.push_back(fu(parts.back()));
    off.push_back(0);
    interval.push_back(
        {it - ((int)(parts.back()).size()) - inp.begin(), it - inp.begin()});
    range.emplace_back(
        *min_element((parts.back()).begin(), (parts.back()).end()),
        *max_element((parts.back()).begin(), (parts.back()).end()));
  }
  for (int i = (0); i <= ((int)(m)-1); i++) {
    int t, l, r, x;
    cin >> t >> l >> r >> x;
    l--;
    if (t == 1) {
      for (int j = (0); j <= ((int)(((int)(parts).size())) - 1); j++) {
        update(l, r, x, fUnions[j], parts[j], off[j], interval[j], range[j]);
      }
    } else {
      int sc = 0;
      for (int j = (0); j <= ((int)(((int)(parts).size())) - 1); j++) {
        sc += getAns(l, r, x, fUnions[j], parts[j], off[j], interval[j]);
      }
      cout << sc << "\n";
    }
    (off);
    (range);
  }
  (counter);
}
