#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-10;
const double PI = acos(-1.0);
template <typename T>
void read(istream& in, vector<T>& list, size_t n) {
  for (size_t i = 0; i < n; ++i) {
    T value;
    in >> value;
    list.push_back(value);
  }
};
template <typename T, typename INDEX_T = int>
struct indexed_value {
  T value;
  INDEX_T index;
};
template <typename T>
void read(istream& in, vector<indexed_value<T> >& list, size_t n) {
  for (size_t i = 0; i < n; ++i) {
    indexed_value<T> v;
    in >> v.value;
    v.index = i;
    list.push_back(v);
  }
}
enum {
  TYPE_ADD,
  TYPE_DUMP,
};
struct op_t {
  int type;
  union {
    struct {
      int level;
      long long left, right;
      int value;
    } info1;
    struct {
      int level;
      long long pos;
    } info2;
  } d;
};
struct problem_t {
  int n;
  int m;
  vector<op_t> op_list;
  friend istream& operator>>(istream& in, problem_t& o) {
    in >> o.n >> o.m;
    for (int i = 0; i < o.m; ++i) {
      op_t op;
      int type;
      in >> type;
      if (type == 1) {
        op.type = TYPE_ADD;
        in >> op.d.info1.level >> op.d.info1.left >> op.d.info1.right >>
            op.d.info1.value;
      } else {
        op.type = TYPE_DUMP;
        in >> op.d.info2.level >> op.d.info2.pos;
      }
      o.op_list.push_back(op);
    }
    return in;
  }
  friend ostream& operator<<(ostream& out, const problem_t& o) {
    out << o.n << " " << o.m << endl;
    for (int i = 0; i < o.m; ++i) {
      op_t op = o.op_list[i];
      out << (op.type == TYPE_ADD ? 1 : 2) << " ";
      if (op.type == TYPE_ADD) {
        out << op.d.info1.level << " " << op.d.info1.left << " "
            << op.d.info1.right << " " << op.d.info1.value << endl;
      } else {
        out << op.d.info2.level << " " << op.d.info2.pos << endl;
      }
    }
    return out;
  }
};
struct range_t {
  long long left;
  long long right;
  int value;
};
bool is_power_of_2(long long value) {
  while (value > 1) {
    if (value % 2 == 0) {
      value /= 2;
    } else {
      return false;
    }
  }
  return value == 1;
}
long long power_of_2_num_less_than(long long value) {
  long long count = 0;
  for (long long n = 1; n < value; n *= 2) {
    ++count;
  }
  return count;
}
void solve(problem_t& p, ostream& out) {
  vector<vector<range_t> > range_list(p.n);
  vector<int> result;
  for (size_t i = 0; i < p.op_list.size(); ++i) {
    op_t op = p.op_list[i];
    if (op.type == TYPE_ADD) {
      range_t info;
      info.left = op.d.info1.left;
      info.right = op.d.info1.right;
      info.value = op.d.info1.value;
      range_list[op.d.info1.level - 1].push_back(info);
    } else {
      long long pos = op.d.info2.pos;
      long long left = pos, right = pos;
      set<int> values;
      for (int level = op.d.info2.level - 1; level < p.n; ++level) {
        for (size_t i = 0; i < range_list[level].size(); ++i) {
          range_t info = range_list[level][i];
          if ((left <= info.left && info.left <= right) ||
              (left <= info.right && info.right <= right) ||
              (info.left <= left && left <= info.right) ||
              (info.right <= right && right <= info.right)) {
            values.insert(info.value);
          }
        }
        long long left_offset = (2 * (left - 1)) -
                                ((left - 1) - power_of_2_num_less_than(left)) +
                                1;
        left = left_offset;
        long long right_offset =
            (2 * (right - 1)) -
            ((right - 1) - power_of_2_num_less_than(right)) + 1;
        if (is_power_of_2(right)) {
          right = right_offset + 1;
        } else {
          right = right_offset;
        }
      }
      out << values.size() << endl;
      out << "                    " << endl << endl;
    }
  }
}
int main(int argc, char* argv[]) {
  problem_t p;
  cin >> p;
  solve(p, cout);
  return 0;
}
