#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 1e4 + 5;
const int MAXM = 1e6 + 5;
struct UpdateQuery {
  int t, l, r, x;
  UpdateQuery() {}
  UpdateQuery(int t, int l, int r, int x) {
    this->t = t;
    this->l = l;
    this->r = r;
    this->x = x;
  }
};
bool isPower[MAXN];
int before[MAXN], sparse[20][MAXN];
int getBack(int x) {
  int parent = x;
  while (true) {
    if (parent + before[parent] == x) return parent;
    if (isPower[parent] == true && parent + before[parent] + 1 == x)
      return parent;
    parent--;
  }
}
void Init() {
  for (int i = 1; i < MAXN; i *= 2) isPower[i] = true;
  before[1] = 0;
  for (int i = 2; i < MAXN; i++) {
    before[i] = before[i - 1] + isPower[i - 1];
  }
  for (int x = 1; x < MAXN; x++) sparse[0][x] = getBack(x);
  for (int i = 1; i <= 15; i++) {
    for (int x = 1; x < MAXN; x++)
      sparse[i][x] = sparse[i - 1][sparse[i - 1][x]];
  }
}
int decreaseLevel(int x, int levels) {
  for (int bit = 0; bit < 13; bit++) {
    if (((levels >> bit) & 1) == 1) x = sparse[bit][x];
  }
  return x;
}
bool seen[MAXM];
stack<int> st;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  Init();
  int n, m;
  cin >> n >> m;
  vector<UpdateQuery> changes;
  while (m--) {
    int type = 1;
    cin >> type;
    if (type == 1) {
      int t, l, r, x;
      cin >> t >> l >> r >> x;
      changes.push_back(UpdateQuery(t, l, r, x));
    } else {
      int t, v;
      cin >> t >> v;
      for (UpdateQuery q : changes) {
        if (q.t < t) continue;
        int l = decreaseLevel(q.l, q.t - t);
        int r = decreaseLevel(q.r, q.t - t);
        if (l <= v && v <= r) {
          if (seen[q.x] == false) {
            seen[q.x] = true;
            st.push(q.x);
          }
        }
      }
      cout << st.size() << '\n';
      while (st.empty() == false) seen[st.top()] = false, st.pop();
    }
  }
}
