#include <bits/stdc++.h>
using namespace std;
const int INF = 1000 * 1000 * 1000;
const int PANDA = 7000 + 7;
int N, M;
struct segment {
  int lf, rg, val;
  segment(int lf, int rg, int val) : lf(lf), rg(rg), val(val) {}
};
vector<segment> A[PANDA];
inline int calc(int x) {
  int ret = x;
  while (x > 0) {
    x >>= 1;
    ++ret;
  }
  return ret;
}
int vs[4], nvs[4];
int query(int v, int level) {
  set<int> res;
  int vsz = 0;
  if ((v & (v - 1)) == 0) {
    vs[vsz++] = calc(v - 1) + 1;
    vs[vsz++] = calc(v - 1) + 2;
  } else {
    vs[vsz++] = calc(v - 1) + 1;
  }
  for (auto seg : A[level]) {
    if (v < seg.lf || v > seg.rg) {
      continue;
    }
    res.insert(seg.val);
  }
  for (;;) {
    if (level == N) {
      break;
    }
    ++level;
    int lf = vs[0], rg = vs[vsz - 1];
    for (auto seg : A[level]) {
      if (rg < seg.lf || lf > seg.rg) {
        continue;
      }
      res.insert(seg.val);
    }
    int nvsz = 0;
    for (int i = 0; i < vsz; ++i) {
      int nv = vs[i];
      if ((nv & (nv - 1)) == 0) {
        nvs[nvsz++] = calc(nv - 1) + 1;
        nvs[nvsz++] = calc(nv - 1) + 2;
      } else {
        nvs[nvsz++] = calc(nv - 1) + 1;
      }
    }
    vsz = 0;
    vs[vsz++] = nvs[0];
    if (nvsz > 1) {
      vs[vsz++] = nvs[nvsz - 1];
    }
  }
  return (int)res.size();
}
int main() {
  scanf("%d%d", &N, &M);
  while (M--) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int level, lf, rg, val;
      scanf("%d%d%d%d", &level, &lf, &rg, &val);
      A[level].push_back(segment(lf, rg, val));
    }
    if (type == 2) {
      int level, pos;
      scanf("%d%d", &level, &pos);
      printf("%d\n", query(pos, level));
    }
  }
  return 0;
}
