#include <bits/stdc++.h>
using namespace std;
const int POS = 2e5;
struct Query {
  int t;
  bool send;
  int level;
  int start;
  int finish;
  int value;
  bool operator<(const Query& other) const {
    return level < other.level || level == other.level && !send && other.send;
  }
};
struct Answer {
  int t;
  int start;
  int finish;
  unordered_set<int> values;
  Answer(int curTime, int curPos) {
    t = curTime;
    start = finish = curPos;
  }
  bool operator<(const Answer& other) const { return t < other.t; }
};
int n, q;
int trans[POS];
vector<Query> queries;
vector<Answer> answers;
void read() {
  cin >> n >> q;
  for (int i = 0; i < q; ++i) {
    int k;
    cin >> k;
    Query query;
    query.t = i;
    cin >> query.level;
    cin >> query.start;
    if (k == 1) {
      query.send = true;
      cin >> query.finish;
      cin >> query.value;
    } else {
      query.send = false;
    }
    queries.push_back(query);
  }
  sort(queries.begin(), queries.end());
}
void build() {
  for (int i = 1; i < POS; ++i) {
    trans[i] = i + (int)log2(i) + 1;
  }
}
void solve() {
  int nextQuery = 0;
  for (int i = 1; i <= n; ++i) {
    for (Answer& a : answers) {
      a.start = trans[a.start - 1] + 1;
      a.finish = trans[a.finish];
    }
    while (nextQuery < q && queries[nextQuery].level == i) {
      Query& query = queries[nextQuery++];
      if (!query.send) {
        answers.push_back(Answer(query.t, query.start));
      } else {
        for (Answer& a : answers) {
          if (query.finish < a.start || query.start > a.finish ||
              query.t > a.t) {
            continue;
          }
          a.values.insert(query.value);
        }
      }
    }
  }
  sort(answers.begin(), answers.end());
}
void write() {
  for (const Answer& a : answers) {
    cout << a.values.size() << '\n';
  }
}
void solveTest() {
  read();
  build();
  solve();
  write();
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  solveTest();
  return 0;
}
