#include <bits/stdc++.h>
using namespace std;
void RI(int& x) {
  x = 0;
  char c = getchar();
  while (!(c >= '0' && c <= '9' || c == '-')) c = getchar();
  bool flag = 1;
  if (c == '-') {
    flag = 0;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  if (!flag) x = -x;
}
void RII(int& x, int& y) { RI(x), RI(y); }
void RIII(int& x, int& y, int& z) { RI(x), RI(y), RI(z); }
void RC(char& c) {
  c = getchar();
  while (c == ' ' || c == '\n') c = getchar();
}
char RC() {
  char c = getchar();
  while (c == ' ' || c == '\n') c = getchar();
  return c;
}
const long long mod = 1e9 + 7;
const long long LINF = 1e18;
const int INF = 1e9;
const double EPS = 1e-8;
const int N = 7005;
struct Level {
  int l, r, val;
  Level(int l, int r, int val) : l(l), r(r), val(val) {}
};
vector<Level> g[N];
vector<int> vec;
int n;
bool calsum(int sl, int sr, int tl, int tr, long long val) {
  tl = max(tl, sl);
  tr = min(tr, sr);
  return tl <= tr;
}
int calson(int n) {
  int num = upper_bound((vec).begin(), (vec).end(), n) - vec.begin();
  return num + n;
}
set<int> sset;
void cal(int level, int l, int r) {
  if (level > n) return;
  long long ans = 0;
  for (int i = 0; i <= (int)g[level].size() - 1; i++) {
    if (calsum(l, r, g[level][i].l, g[level][i].r, g[level][i].val)) {
      sset.insert(g[level][i].val);
    }
  }
  cal(level + 1, calson(l - 1) + 1, calson(r));
}
int main() {
  vec.push_back(1);
  for (int i = 1; i <= 30; i++) {
    vec.push_back(vec.back() * 2);
  }
  int m;
  cin >> n >> m;
  while (m--) {
    int op;
    cin >> op;
    if (op == 1) {
      int level, l, r;
      long long val;
      cin >> level >> l >> r >> val;
      g[level].push_back(Level(l, r, val));
    } else {
      int t, v;
      sset.clear();
      cin >> t >> v;
      cal(t, v, v);
      cout << (int)sset.size() << endl;
    }
  }
}
