#include <bits/stdc++.h>
using namespace std;
inline unsigned myrand() {
  static unsigned x = 998244353;
  return x += x << 2 | 1;
}
inline int getint() {
  static char c;
  while ((c = getchar()) < '0' || c > '9')
    ;
  int res = c - '0';
  while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
  return res;
}
const int NDir = 4;
const int MaxN = 5001;
const int MaxQ = 100001;
const int MaxM = 400001;
const int MaxLogM = 19;
const int MaxTN = MaxM * MaxLogM >> 2;
int n, nQu, m = 0, nQuery = 0;
int ans[MaxQ];
struct operation {
  int type, lab;
  int x, y, dir;
  friend inline bool operator<(const operation &lhs, const operation &rhs) {
    if (lhs.x != rhs.x) return lhs.x < rhs.x;
    return lhs.type <= rhs.type;
  }
  inline void set(const int &t, const int &l, const int &_x, const int &_y,
                  const int &d) {
    type = t, lab = l;
    x = _x, y = _y, dir = d;
  }
};
operation q[MaxM], p[MaxM];
struct treap_node {
  treap_node *lc, *rc;
  int val, size;
  unsigned pri;
  inline void update() {
    size = 1;
    if (lc) size += lc->size;
    if (rc) size += rc->size;
  }
};
treap_node pool[MaxTN], *tail = pool;
inline treap_node *newnode() {
  treap_node *x = tail++;
  x->lc = x->rc = NULL;
  x->pri = myrand(), x->size = 1;
  return x;
}
inline void treap_zig(treap_node *&x) {
  treap_node *y = x->lc;
  x->lc = y->rc;
  y->rc = x;
  x->update();
  x = y;
}
inline void treap_zag(treap_node *&x) {
  treap_node *y = x->rc;
  x->rc = y->lc;
  y->lc = x;
  x->update();
  x = y;
}
void treap_insert(treap_node *&x, const int &val) {
  if (x == NULL) {
    x = newnode(), x->val = val;
    return;
  }
  if (val <= x->val) {
    treap_insert(x->lc, val);
    if (x->pri < x->lc->pri) treap_zig(x);
  } else {
    treap_insert(x->rc, val);
    if (x->pri < x->rc->pri) treap_zag(x);
  }
  x->update();
}
inline int treap_query(treap_node *x, const int &val) {
  int rank = 0;
  while (x) {
    if (val > x->val)
      x = x->rc;
    else {
      int r = x->rc ? x->rc->size : 0;
      rank += r + 1;
      x = x->lc;
    }
  }
  return rank;
}
treap_node *bit[NDir][MaxN];
inline void bit_update(treap_node **b, const int &x, const int &val) {
  for (int i = x; i <= n; i += i & -i) treap_insert(b[i], val);
}
inline int bit_query(treap_node **b, const int &x, const int &val) {
  int res = 0;
  for (int i = x; i; i ^= i & -i) res += treap_query(b[i], val);
  return res;
}
inline void bit_reinit(treap_node **b, const int &x) {
  for (int i = x; i <= n && b[i]; i += i & -i) b[i] = NULL;
}
void solve(const int &l, const int &r) {
  if (l == r) return;
  int mid = l + r >> 1;
  solve(l, mid);
  solve(mid + 1, r);
  int i = l, j = mid + 1;
  for (int t = l; t <= r; ++t) {
    if (j > r || (i <= mid && q[i] < q[j])) {
      p[t] = q[i++];
      if (p[t].type == 0) bit_update(bit[p[t].dir], p[t].y, p[t].lab);
    } else {
      p[t] = q[j++];
      if (p[t].type == 1) {
        int len = p[t].x + p[t].y;
        ans[p[t].lab] += bit_query(bit[p[t].dir], p[t].y, len);
      }
    }
  }
  tail = pool;
  for (i = l; i <= r; ++i) {
    q[i] = p[i];
    if (q[i].type == 0) bit_reinit(bit[q[i].dir], q[i].y);
  }
}
int main() {
  n = getint(), nQu = getint();
  while (nQu--) {
    int type = getint();
    if (type == 1) {
      int dir = getint();
      int x = getint(), y = getint(), l = getint();
      if (dir == 2 || dir == 4) y = n - y + 1;
      if (dir == 3 || dir == 4) x = n - x + 1;
      q[++m].set(0, l + x + y, x, y, --dir);
    } else {
      int x = getint(), y = getint();
      q[++m].set(1, ++nQuery, x, y, 0);
      q[++m].set(1, nQuery, x, n - y + 1, 1);
      q[++m].set(1, nQuery, n - x + 1, y, 2);
      q[++m].set(1, nQuery, n - x + 1, n - y + 1, 3);
    }
  }
  solve(1, m);
  for (int i = 1; i <= nQuery; ++i) printf("%d\n", ans[i]);
  return 0;
}
