#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

typedef unsigned u32;

inline u32 myrand()
{
	static u32 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;
	u32 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() // orz myh
{
	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;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

typedef unsigned u32;

inline u32 myrand()
{
	static u32 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 >> 1;

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;
	u32 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;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

typedef unsigned u32;

inline u32 myrand()
{
	static u32 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;
	u32 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() // orz myh
{
	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;
	}

	++x->size;
	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);
	}
}

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() - 1;
			int x = getint(), y = getint(), l = getint();
			if (dir == 1 || dir == 3)
				y = n - y + 1;
			if (dir == 2 || dir == 3)
				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;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

typedef unsigned int u32;
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define PER(i, a, b) for (int i = (a); i > (b); --i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)

inline int read()
{
    static char ch;
    while (ch = getchar(), ch < '0' || ch > '9');
    int res = ch - 48;
    while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - 48;
    return res;
}

inline u32 Rand()
{
    static u32 x = 998666131;
    return x += x << 2 | 1;
}

const int N = 5001, T = 2e6;
int n, Q;

struct node
{
    node *lc, *rc;
    int val, sze;
    u32 pri;

    inline void Update()
    {
        sze = (lc ? lc->sze : 0) + (rc ? rc->sze : 0) + 1;
    }
} used[T], *pool = used, *rt1[N][N], *rt2[N][N], *rt3[N][N], *rt4[N][N];

inline void Zig(node *&u)
{
    node *v = u->lc;
    u->lc = v->rc;
    v->rc = u;
    v->sze = u->sze;
    u->Update();
    u = v;
}

inline void Zag(node *&u)
{
    node *v = u->rc;
    u->rc = v->lc;
    v->lc = u;
    v->sze = u->sze;
    u->Update();
    u = v;
}

inline void Insert(node *&u, const int &val)
{
    if (!u)
    {
        u = pool++;
        u->val = val; u->sze = 1;
        u->pri = Rand();
        return ;
    }
    ++u->sze;
    if (val <= u->val)
    {
        Insert(u->lc, val);
        if (u->lc->pri < u->pri)
            Zig(u);
    }
    else
    {
        Insert(u->rc, val);
        if (u->rc->pri < u->pri)
            Zag(u);
    }
}

inline int moreQuery(node *u, const int &val)
{
    if (!u) return 0;
    if (u->val < val)
        return moreQuery(u->rc, val);
    return (u->rc ? u->rc->sze + 1 : 1) + moreQuery(u->lc, val);
}

inline void add1(const int &x, const int &y, const int &val)
{
    for (int i = x; i <= n; i += i & -i)
        for (int j = y; j <= n; j += j & -j)
            Insert(rt1[i][j], val);
}

inline void add2(const int &x, const int &y, const int &val)
{
    for (int i = x; i <= n; i += i & -i)
        for (int j = y; j <= n; j += j & -j)
            Insert(rt2[i][j], val);
}

inline void add3(const int &x, const int &y, const int &val)
{
    for (int i = x; i <= n; i += i & -i)
        for (int j = y; j <= n; j += j & -j)
            Insert(rt3[i][j], val);
}

inline void add4(const int &x, const int &y, const int &val)
{
    for (int i = x; i <= n; i += i & -i)
        for (int j = y; j <= n; j += j & -j)
            Insert(rt4[i][j], val);
}

inline int Query1(const int &x, const int &y, const int &val)
{
    int res = 0;
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res += moreQuery(rt1[i][j], val);
    /*for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res -= moreQuery(rt1[i][j], val);
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res -= moreQuery(rt1[i][j], val);
    for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res += moreQuery(rt1[i][j], val);*/
    return res;
}

inline int Query2(const int &x, const int &y, const int &val)
{
    int res = 0;
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res += moreQuery(rt2[i][j], val);
    /*for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res -= moreQuery(rt2[i][j], val);
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res -= moreQuery(rt2[i][j], val);
    for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res += moreQuery(rt2[i][j], val);*/
    return res;
}

inline int Query3(const int &x, const int &y, const int &val)
{
    int res = 0;
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res += moreQuery(rt3[i][j], val);
    /*for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res -= moreQuery(rt3[i][j], val);
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res -= moreQuery(rt3[i][j], val);
    for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res += moreQuery(rt3[i][j], val);*/
    return res;
}

inline int Query4(const int &x, const int &y, const int &val)
{
    int res = 0;
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res += moreQuery(rt4[i][j], val);
    /*for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            res -= moreQuery(rt4[i][j], val);
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res -= moreQuery(rt4[i][j], val);
    for (int i = x - 1; i > 0; i -= i & -i)
        for (int j = y - 1; j > 0; j -= j & -j)
            res += moreQuery(rt4[i][j], val);*/
    return res;
}

int main()
{
    n = read(); Q = read();

    int op, x, y, len, dir;
    while (Q--)
    {
        op = read();
        if (op == 1)
        {
            dir = read(), x = read(), y = read(), len = read();
            if (dir == 1) add1(x, y, x + y + len);
            else if (dir == 2) add2(x, n - y + 1, x + len + (n - y + 1));
            else if (dir == 3) add3(n - x + 1, y, (n - x + 1) + y + len);
            else add4(n - x + 1, n - y + 1, (n - x + 1) + (n - y + 1) + len);
        }
        else
        {
            x = read(), y = read();
            printf("%d\n", Query1(x, y, x + y) + Query2(x, n - y + 1, x + (n - y + 1)) +
                           Query3(n - x + 1, y, (n - x + 1) + y) + Query4(n - x + 1, n - y + 1, (n - x + 1) + (n - y + 1)));
        }
    }
    return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

typedef unsigned int u32;
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define PER(i, a, b) for (int i = (a); i > (b); --i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)

inline int read()
{
    static char ch;
    while (ch = getchar(), ch < '0' || ch > '9');
    int res = ch - 48;
    while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - 48;
    return res;
}

inline u32 Rand()
{
    static u32 x = 998666131;
    return x += x << 2 | 1;
}

const int N = 5001, M = 1e5 + 5, T = 2e6;
int n, m, Q, ans[M];
bool vis[M];

struct QueryT
{
    int op, x, y, dir, len, lab;
    inline void Reset1(const int &_op, const int &_dir, const int &_x, const int &_y, const int &_len)
    {
        op = _op;
        dir = _dir;
        x = _x;
        y = _y;
        len = _len;
    }
    inline void Reset2(const int &_op, const int &_dir, const int &_x, const int &_y, const int &_lab)
    {
        op = _op;
        dir = _dir;
        x = _x;
        y = _y;
        lab = _lab;
        len = x + y;
    }
    inline bool operator <= (const QueryT &rhs)
    {
        if (x != rhs.x)
            return x < rhs.x;
        return op <= rhs.op;
    }
} qry[M * 4], tmp[M * 4];

struct node
{
    node *lc, *rc;
    int val, sze;
    u32 pri;

    inline void Update()
    {
        sze = (lc ? lc->sze : 0) + (rc ? rc->sze : 0) + 1;
    }
} used[T], *pool = used, *unused[T], **top = unused;
node *rt[5][N];

inline node* new_node()
{
    node *res;
    if (top != unused)
        res = *--top;
    else res = pool++;
    res->lc = res->rc = NULL;
    return res;
}

inline void del_node(node *&u)
{
    if (!u) return ;
    del_node(u->lc);
    del_node(u->rc);
    *top++ = u;
    u = NULL;
}

inline void Zig(node *&u)
{
    node *v = u->lc;
    u->lc = v->rc;
    v->rc = u;
    v->sze = u->sze;
    u->Update();
    u = v;
}

inline void Zag(node *&u)
{
    node *v = u->rc;
    u->rc = v->lc;
    v->lc = u;
    v->sze = u->sze;
    u->Update();
    u = v;
}

inline void Insert(node *&u, const int &val)
{
    if (!u)
    {
        u = new_node();
        u->val = val; u->sze = 1;
        u->pri = Rand();
        return ;
    }
    ++u->sze;
    if (val <= u->val)
    {
        Insert(u->lc, val);
        if (u->lc->pri < u->pri)
            Zig(u);
    }
    else
    {
        Insert(u->rc, val);
        if (u->rc->pri < u->pri)
            Zag(u);
    }
}

inline int moreQuery(node *u, const int &val)
{
    if (!u) return 0;
    if (u->val < val)
        return moreQuery(u->rc, val);
    return (u->rc ? u->rc->sze + 1 : 1) + moreQuery(u->lc, val);
}

inline void add(node **R, int x, const int &val)
{
    for (; x <= n; x += x & -x)
        Insert(R[x], val);
}

inline int Query(node **R, int x, const int &val)
{
    int res = 0;
    for (; x > 0; x -= x & -x)
        res += moreQuery(R[x], val);
    return res;
}

inline void Clear(node **R, int x)
{
    for (; x <= n; x += x & -x)
        del_node(R[x]);
}

inline void cdqSolve(const int &l, const int &r)
{
    if (l == r) return ;
    int mid = l + r >> 1;
    cdqSolve(l, mid); cdqSolve(mid + 1, r);

    int ql = l, qr = mid + 1;
    FOR(i, l, r)
    {
        if (qr > r || (ql <= mid && qry[ql] <= qry[qr]))
        {
            tmp[i] = qry[ql++];
            if (tmp[i].op == 1)
                add(rt[tmp[i].dir], tmp[i].y, tmp[i].len);
        }
        else
        {
            tmp[i] = qry[qr++];
            if (tmp[i].op == 2)
                ans[tmp[i].lab] += Query(rt[tmp[i].dir], tmp[i].y, tmp[i].len);
        }
    }
    FOR(i, l, r)
    {
        qry[i] = tmp[i];
        if (qry[i].op == 1)
            Clear(rt[qry[i].dir], qry[i].y);
    }
}

int main()
{
    n = read(); Q = read();

    int op, x, y, len, dir;
    FOR(i, 1, Q)
    {
        op = read();
        if (op == 1)
        {
            dir = read(), x = read(), y = read(), len = read();
            if (dir == 2) y = n - y + 1;
            if (dir == 3) x = n - x + 1;
            if (dir == 4) x = n - x + 1, y = n - y + 1;
            len += x + y;
            qry[++m].Reset1(op, dir, x, y, len);
        }
        else
        {
            x = read(), y = read();
            qry[++m].Reset2(op, 1, x, y, i);
            qry[++m].Reset2(op, 2, x, n - y + 1, i);
            qry[++m].Reset2(op, 3, n - x + 1, y, i);
            qry[++m].Reset2(op, 4, n - x + 1, n - y + 1, i);
            vis[i] = true;
        }
    }

    cdqSolve(1, m);
    FOR(i, 1, Q) if (vis[i])
        printf("%d\n", ans[i]);
    return 0;
}


/*
 * Problem :
 * Author : Hwhitetooth
 * Date :
 * Result :
 */

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstring>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <algorithm>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;

const int N = 5000 + 10;
const int Q = 100000 + 10;

struct Item {
	int x, y, key, type, id;

	Item() {
	}

	Item(int _x, int _y, int _key, int _type, int _id) : x(_x), y(_y), key(_key), type(_type), id(_id) {
	}

	int operator <(const Item &that) const {
		return key > that.key || (key == that.key && type < that.type);
	}
} a[Q];
int dir[Q], x[Q], y[Q], len[Q], ans[Q];
int bit[N][N];
int n, q;

vector<Item> vec;

void ins(int x, int y, int delta) {
	for (; x <= n; x += x & -x) {
		for (int _y = y; _y <= n; _y += _y & -_y) {
			bit[x][_y] += delta;
		}
	}
}

int ask(int x, int y) {
	int ret = 0;
	for (; x > 0; x -= x & -x) {
		for (int _y = y; _y > 0; _y -= _y & -_y) {
			ret += bit[x][_y];
		}
	}
	return ret;
}

void solve(int l, int r) {
	if (r - l <= 1) {
		return;
	}
	int m = l + r >> 1;
	solve(l, m);
	solve(m, r);
	vec.clear();
	int cnt0 = 0, cnt1 = 0;
	for (int i = l; i < m; ++i) {
		if (a[i].type == 0) {
			vec.push_back(a[i]);
			++cnt0;
		}
	}
	for (int i = m; i < r; ++i) {
		if (a[i].type == 1) {
			vec.push_back(a[i]);
			++cnt1;
		}
	}
	if (cnt0 == 0 || cnt1 == 0) {
		return;
	}
	sort(vec.begin(), vec.end());
	for (int i = 0; i < (int)vec.size(); ++i) {
		if (vec[i].type == 0) {
			ins(vec[i].x, vec[i].y, 1);
		}
		else {
			ans[vec[i].id] += ask(vec[i].x, vec[i].y);
		}
	}
	for (int i = 0; i < (int)vec.size(); ++i) {
		if (vec[i].type == 0) {
			ins(vec[i].x, vec[i].y, -1);
		}
	}
}

void solve(int direction) {
	int tot = 0;
	for (int i = 0; i < q; ++i) {
		if (!dir[i] || dir[i] == direction) {
			static int _x, _y;
			switch (direction) {
				case 1:
					_x = x[i];
					_y = y[i];
					break;
				case 2:
					_x = x[i];
					_y = n + 1 - y[i];
					break;
				case 3:
					_x = n + 1 - x[i];
					_y = y[i];
					break;
				case 4:
					_x = n + 1 - x[i];
					_y = n + 1 - y[i];
					break;
			}
			a[tot++] = Item(_x, _y, _x + _y + len[i], !dir[i], i);
		}
	}
	solve(0, tot);
}

int main() {
	scanf("%d%d", &n, &q);
	for (int i = 0; i < q; ++i) {
		static int cmd;
		scanf("%d", &cmd);
		if (cmd == 1) {
			scanf("%d%d%d%d", dir + i, x + i, y + i, len + i);
		}
		else {
			scanf("%d%d", x + i, y + i);
		}
	}

	for (int i = 1; i <= 4; ++i) {
		solve(i);
	}

	for (int i = 0; i < q; ++i) {
		if (!dir[i]) {
			printf("%d\n", ans[i]);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORd(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define sz(a) int((a).size())
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
ll gcd(ll a, ll b) {ll r; while (b != 0) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
#define EPS 1e-9
const int mod = 1000000007;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = 2 * acos(0);

const int maxx = 10010;
const int maxy = 5010;
struct Fenwick {
	int fen[maxx][maxy];
	void reset() {ms(fen, 0);}
	void add(int x, int y, int val) {
		while (x < maxx) {
			int y1 = y;
			while (y1 < maxy) {
				fen[x][y1] += val;
				y1 += y1 & -y1;
			}
			x += x & -x;
		}
	}
	int get(int x, int y) {
		int res = 0;
		while (x) {
			int y1 = y;
			while (y1) {
				res += fen[x][y1];
				y1 -= y1 & -y1;
			}
			x -= x & -x;
		}
		return res;
	}
} fw[2];

struct query {
	int type;
	int dir;
	int x, y;
	int len;
};

const int maxq = 100010;
int n, q;
query vq[maxq];
int ans[maxq];

void solve() {
	scanf("%d%d", &n, &q);
	FOR(i, 0, q) {
		scanf("%d", &vq[i].type);
		if (vq[i].type == 1) scanf("%d%d%d%d", &vq[i].dir, &vq[i].x, &vq[i].y, &vq[i].len);
		else scanf("%d%d", &vq[i].x, &vq[i].y);
	}
	FOR(t, 1, 5) {
		FOR(i, 0, 2) fw[i].reset();
		FOR(i, 0, q) {
			int x = vq[i].x, y = vq[i].y;
			if (t == 2 || t == 4) y = n - y + 1;
			if (t == 3 || t == 4) x = n - x + 1;
			if (vq[i].dir == t) {
				fw[0].add(x, y, 1);
				fw[0].add(x, y + vq[i].len + 1, -1);
				fw[1].add(x + y + vq[i].len, y, 1);
				fw[1].add(x + y + vq[i].len, y + vq[i].len + 1, -1);
			}
			else if (vq[i].type == 2) {
				ans[i] += fw[0].get(x, y) - fw[1].get(x + y - 1, y);
			}
		}
	}
	FOR(i, 0, q) if (vq[i].type == 2) printf("%d\n", ans[i]);
}

int main() {
	//ios_base::sync_with_stdio(0); cin.tie(NULL);
#ifdef _LOCAL_
	freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);
#endif
	solve();
#ifdef _LOCAL_
	//printf("\nTime elapsed: %dms", 1000 * clock() / CLOCKS_PER_SEC);
#endif
	return 0;
}


#include <cstdio>
#include <cstring>

void it_add(int n, int it[], int p, int v) {
    for (int i = p; i <= n; i += (i & (-i))) {
        it[i] += v;
    }
}

int it_get(int it[], int p) {
    int res = 0;
    for (int i = p; i > 0; i -= (i & (-i))) {
        res += it[i];
    }
    return res;
}

void it2_add(int n, int m, int it[][5020], int p, int l, int r) {
    for (int i = p; i <= n; i += (i & (-i))) {
        it_add(m, it[i], l, 1);
        it_add(m, it[i], r + 1, -1);
    }
}

int it2_get(int it[][5020], int x, int y) {
    int res = 0;
    for (int i = x; i > 0; i -= (i & (-i))) {
        res += it_get(it[i], y);
    }
    return res;
}

int fl[5020][5020];
int di[10020][5020];

int ans[1 << 17];

int n, q;
int tp[1 << 17], x[1 << 17], y[1 << 17], len[1 << 17], dir[1 << 17];

int rt[] = {0, 1, 3, 2};

void ncor(int d, int ox, int oy, int &nx, int &ny) {
    --d;
    nx = ox;
    ny = oy;
    for (int i = 0; i < rt[d]; ++i) {
        int x, y;
        x = -ny;
        y = nx;

        nx = x + n + 1;
        ny = y;
    }
}

int main() {
    scanf("%d %d", &n, &q);
    for (int i = 0; i < q; ++i) {
        scanf("%d", &tp[i]);
        if (tp[i] == 1) {
            scanf("%d %d %d %d", &dir[i], &x[i], &y[i], &len[i]);
        } else {
            scanf("%d %d", &x[i], &y[i]);
        }
    }

    memset(ans, 0, sizeof(ans));
    for (int dr = 1; dr <= 4; ++dr) {
        memset(fl, 0, sizeof(fl));
        memset(di, 0, sizeof(di));
        for (int i = 0; i < q; ++i) {
            int nx, ny;
            ncor(dr, x[i], y[i], nx, ny);
            if (tp[i] == 1 && dir[i] == dr) {
                it2_add(n, n, fl, nx, ny, ny + len[i]);
                it2_add(n + n, n, di, nx + ny + len[i], ny, ny + len[i]);
            } else {
                ans[i] += it2_get(fl, nx, ny) - it2_get(di, nx + ny - 1, ny);
            }
        }
    }
    for (int i = 0; i < q; ++i) {
        if (tp[i] == 2) {
            printf("%d\n", ans[i]);
        }
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int M=100050;
struct tree {
	int s,fa,l,r,v;
}T[M*60];
int sum;
struct node {
	int tim,x,y,len,k,d;
}a[M],q[M],b[M];
int tot;
int nn,tg,vis[M],root[M];
int ans[M],n,m,tim;
inline void Updata(int k)
{
	T[k].s=T[T[k].l].s+T[T[k].r].s+1;
}
inline void turn(int x)
{
	int y=T[x].fa,z=T[y].fa,b= (T[y].l==x) ? T[x].r : T[x].l;
	T[y].fa=x; T[x].fa=z; if (b) T[b].fa=y;
	(T[z].l==y ? T[z].l : T[z].r) = x;
	if (T[y].l==x) T[x].r=y,T[y].l=b;
	else T[x].l=y,T[y].r=b;
	Updata(y);
	return;
}
inline void splay(int x,int fa,int &rt)
{
	int y,z;
	while (T[x].fa!=fa)
	{
		y=T[x].fa; z=T[y].fa;
		if (z!=fa) {
			if ((T[y].l==x)==(T[z].l==y)) turn(y);
			else turn(x);
		}
		turn(x);
	}
	Updata(x);
	if (!fa) rt=x;
}
inline void Init(int k)
{
	T[k].s=T[k].l=T[k].r=T[k].fa=T[k].v=0;
}
inline void Ins(int &k,int fa,int v)
{
	if (!k) {
		++sum;
		Init(sum);
		T[k=sum].v=v;
		T[k].s=1;
		T[k].fa=fa;
		return;
	}
	if (T[k].v<=v) Ins(T[k].l,k,v);
	else Ins(T[k].r,k,v);
}
inline void Add(node a)
{
	int v=a.x+a.y+a.len;
	//if (a.d==3) cerr<<v<<endl;
	for (int i=a.y;i<=nn;i+=i & (-i)) {
		//if (v==31) cerr<<i<<endl;
		if (vis[i]!=tg) {
			vis[i]=tg;
			Init(root[i]);
			root[i]=0;
		}
		Ins(root[i],0,v);
		splay(sum,0,root[i]);
	}
}
inline int Find(int k,int v)
{
	int g=0;
	while (k) {
		//cerr<<T[k].r<<endl;
		if (T[k].v>=v) {
			g=k;
			k=T[k].r;
		} else {
			k=T[k].l;
		}
	}
	return g;
}
inline int Ask(node a)
{
	//cerr<<T[6].r<<endl;
	int r=0,v=a.x+a.y+a.len,k;
	for (int i=a.y;i;i-=i & (-i))
	{
		//cerr<<i<<endl;
		if (vis[i]==tg) {
			//cerr<<i<<endl;
			k=Find(root[i],v);
			if (k) {
				splay(k,0,root[i]);
				r+=T[T[k].l].s+1;
			}
		}
	}
	return r;
}
inline void cdq_Solve(int l,int r)
{
	if (l==r) return;
	int mid=l+r>>1;
	cdq_Solve(l,mid); cdq_Solve(mid+1,r);
	++tg; sum=0;
	int t=l-1,j=l;
	for (int i=mid+1;i<=r;++i)
	{
		while (j<=mid&&q[j].x<=q[i].x) {
			b[++t]=q[j];
			if (q[j].k==1) Add(q[j]);
			++j;
		}
		//if (l==1&&r==2) cerr<<j<<endl;
		b[++t]=q[i];
		if (q[i].k==2) ans[q[i].tim]+=Ask(q[i]);
	}
	while (j<=mid) { b[++t]=q[j]; ++j; }
	//for (int i=l;i<=mid;++i) Clear(q[i]);
	for (int i=l;i<=r;++i) q[i]=b[i];
	return;
}

int main()
{
	scanf("%d%d",&n,&m);
	nn=n<<1;
	for (int i=1;i<=m;++i)
	{
		scanf("%d",&a[i].k);
		if (a[i].k==1) {
			scanf("%d%d%d%d",&a[i].d,&a[i].x,&a[i].y,&a[i].len);
		} else {
			scanf("%d%d",&a[i].x,&a[i].y);
			a[i].tim=++tim;
		}
	}
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==1) q[++tot]=a[i];
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			//cerr<<a[i].x<<" "<<a[i].y<<endl;
			//cerr<<a[i].x<<endl;
			q[++tot]=a[i];
		}
		else if (a[i].d==3) {
			a[i].x=nn-a[i].x;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		} else if (a[i].d==4) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	for (int i=1;i<=tim;++i)
		printf("%d\n",ans[i]);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int M=100050;
struct tree {
	int s,fa,l,r,v;
}T[M*60];
int sum;
struct node {
	int tim,x,y,len,k,d;
}a[M],q[M],b[M];
int tot;
int nn,tg,vis[M],root[M];
int ans[M],n,m,tim;
inline void Updata(int k)
{
	T[k].s=T[T[k].l].s+T[T[k].r].s+1;
}
inline void turn(int x)
{
	int y=T[x].fa,z=T[y].fa,b= (T[y].l==x) ? T[x].r : T[x].l;
	T[y].fa=x; T[x].fa=z; if (b) T[b].fa=y;
	(T[z].l==y ? T[z].l : T[z].r) = x;
	if (T[y].l==x) T[x].r=y,T[y].l=b;
	else T[x].l=y,T[y].r=b;
	Updata(y);
	return;
}
inline void splay(int x,int fa,int &rt)
{
	int y,z;
	while (T[x].fa!=fa)
	{
		y=T[x].fa; z=T[y].fa;
		if (z!=fa) {
			if ((T[y].l==x)==(T[z].l==y)) turn(y);
			else turn(x);
		}
		turn(x);
	}
	Updata(x);
	if (!fa) rt=x;
}
inline void Init(int k)
{
	T[k].s=T[k].l=T[k].r=T[k].fa=T[k].v=0;
}
inline void Ins(int &k,int fa,int v)
{
	if (!k) {
		++sum;
		Init(sum);
		T[k=sum].v=v;
		T[k].s=1;
		T[k].fa=fa;
		return;
	}
	if (T[k].v<=v) Ins(T[k].l,k,v);
	else Ins(T[k].r,k,v);
}
inline void Add(node a)
{
	int v=a.x+a.y+a.len;
	//if (a.d==3) cerr<<v<<endl;
	for (int i=a.y;i<=nn;i+=i & (-i)) {
		//if (v==31) cerr<<i<<endl;
		if (vis[i]!=tg) {
			vis[i]=tg;
			Init(root[i]);
			root[i]=0;
		}
		Ins(root[i],0,v);
		splay(sum,0,root[i]);
	}
}
inline int Find(int k,int v)
{
	int g=0;
	while (k) {
		//cerr<<T[k].r<<endl;
		if (T[k].v>=v) {
			g=k;
			k=T[k].r;
		} else {
			k=T[k].l;
		}
	}
	return g;
}
inline int Ask(node a)
{
	//cerr<<T[6].r<<endl;
	int r=0,v=a.x+a.y+a.len,k;
	for (int i=a.y;i;i-=i & (-i))
	{
		//cerr<<i<<endl;
		if (vis[i]==tg) {
			//cerr<<i<<endl;
			k=Find(root[i],v);
			if (k) {
				splay(k,0,root[i]);
				r+=T[T[k].l].s+1;
			}
		}
	}
	return r;
}
inline void cdq_Solve(int l,int r)
{
	if (l==r) return;
	int mid=l+r>>1;
	cdq_Solve(l,mid); cdq_Solve(mid+1,r);
	++tg; sum=0;
	int t=l-1,j=l;
	for (int i=mid+1;i<=r;++i)
	{
		while (j<=mid&&q[j].x<=q[i].x) {
			b[++t]=q[j];
			if (q[j].k==1) Add(q[j]);
			++j;
		}
		//if (l==1&&r==2) cerr<<j<<endl;
		b[++t]=q[i];
		if (q[i].k==2) ans[q[i].tim]+=Ask(q[i]);
	}
	while (j<=mid) { b[++t]=q[j]; ++j; }
	//for (int i=l;i<=mid;++i) Clear(q[i]);
	for (int i=l;i<=r;++i) q[i]=b[i];
	return;
}

int main()
{
		freopen("1.in","r",stdin);
	freopen("2.out","w",stdout);
	scanf("%d%d",&n,&m);
	nn=n<<1;
	for (int i=1;i<=m;++i)
	{
		scanf("%d",&a[i].k);
		if (a[i].k==1) {
			scanf("%d%d%d%d",&a[i].d,&a[i].x,&a[i].y,&a[i].len);
		} else {
			scanf("%d%d",&a[i].x,&a[i].y);
			a[i].tim=++tim;
		}
	}
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==1) q[++tot]=a[i];
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			//cerr<<a[i].x<<" "<<a[i].y<<endl;
			//cerr<<a[i].x<<endl;
			q[++tot]=a[i];
		}
		else if (a[i].d==3) {
			a[i].x=nn-a[i].x;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		} else if (a[i].d==4) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	for (int i=1;i<=tim;++i)
		printf("%d\n",ans[i]);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int M=100050;
struct tree {
	int s,fa,l,r,v;
}T[M*30];
int sum;
struct node {
	int tim,x,y,len,k,d;
}a[M],q[M],b[M];
int tot;
int nn,tg,vis[M],root[M];
int ans[M],n,m,tim;
//inline bool cmp(node a,node b)
//{
//	return a.lx<b.lx;
//}
inline void Updata(int k)
{
	T[k].s=T[T[k].l].s+T[T[k].r].s+1;
}
inline void turn(int x)
{
	int y=T[x].fa,z=T[y].fa,b= (T[y].l==x) ? T[x].r : T[x].l;
	T[y].fa=x; T[x].fa=z; if (b) T[b].fa=y;
	(T[z].l==y ? T[z].l : T[z].r) = x;
	if (T[y].l==x) T[x].r=y,T[y].l=b;
	else T[x].l=y,T[y].r=b;
	Updata(y);
	return;
}
inline void splay(int x,int fa,int &rt)
{
	int y,z;
	while (T[x].fa!=fa)
	{
		y=T[x].fa; z=T[y].fa;
		if (z!=fa) {
			if ((T[y].l==x)==(T[z].l==y)) turn(y);
			else turn(x);
		}
		turn(x);
	}
	Updata(x);
	if (!fa) rt=x;
}
inline void Init(int k)
{
	T[k].s=T[k].l=T[k].r=T[k].fa=0;
}
inline void Ins(int &k,int fa,int v)
{
	if (!k) {
		++sum;
		Init(sum);
		T[k=sum].v=v;
		T[k].s=1;
		T[k].fa=fa;
		return;
	}
	if (T[k].v<=v) Ins(T[k].l,k,v);
	else Ins(T[k].r,k,v);
}
inline void Add(node a)
{
	int v=a.x+a.y+a.len;
	//if (a.d==3) cerr<<v<<endl;
	for (int i=a.y;i<=nn;i+=i & (-i)) {
		//if (v==31) cerr<<i<<endl;
		if (vis[i]!=tg) {
			vis[i]=tg;
			Init(root[i]);
			root[i]=0;
		}
		Ins(root[i],0,v);
		splay(sum,0,root[i]);
	}
}
inline int Find(int k,int v)
{
	int g=0;
	while (k) {
		//cerr<<T[k].r<<endl;
		if (T[k].v>=v) {
			g=k;
			k=T[k].r;
		} else {
			k=T[k].l;
		}
	}
	return g;
}
inline int Ask(node a)
{
	//cerr<<T[6].r<<endl;
	int r=0,v=a.x+a.y+a.len,k;
	for (int i=a.y;i;i-=i & (-i))
	{
		//cerr<<i<<endl;
		if (vis[i]==tg) {
			//cerr<<i<<endl;
			k=Find(root[i],v);
			if (k) {
				splay(k,0,root[i]);
				r+=T[T[k].l].s+1;
			}
		}
	}
	return r;
}
inline void cdq_Solve(int l,int r)
{
	if (l==r) return;
	int mid=l+r>>1;
	cdq_Solve(l,mid); cdq_Solve(mid+1,r);
	++tg; sum=0;
	int t=l-1,j=l;
	for (int i=mid+1;i<=r;++i)
	{
		while (j<=mid&&q[j].x<=q[i].x) {
			b[++t]=q[j];
			if (q[j].k==1) Add(q[j]);
			++j;
		}
		//if (l==1&&r==2) cerr<<j<<endl;
		b[++t]=q[i];
		if (q[i].k==2) ans[q[i].tim]+=Ask(q[i]);
	}
	while (j<=mid) { b[++t]=q[j]; ++j; }
	//for (int i=l;i<=mid;++i) Clear(q[i]);
	for (int i=l;i<=r;++i) q[i]=b[i];
	return;
}

int main()
{
	scanf("%d%d",&n,&m);
	nn=n<<1;
	for (int i=1;i<=m;++i)
	{
		scanf("%d",&a[i].k);
		if (a[i].k==1) {
			scanf("%d%d%d%d",&a[i].d,&a[i].x,&a[i].y,&a[i].len);
/*			if (a[i].d==1) {
				a[i].lx=a[i].x+a[i].len;
				//a[i].x1=x; a[i].x2=x+len;
				//a[i].y1=y+len; a[i].y2=y;
			} else if (a[i].d==2) {
				a[i].lx=a[i].x+a[i].len;
				//a[i].x1=x; a[i].x2=x+len;
				//a[i].y1=y-len; a[i].y2=y;
			} else if (a[i].d==3) {
				a[i].lx=x;
				//a[i].x1=x-len; a[i].x2=x;
				//a[i].y1=y; a[i].y2=y+len;
			} else {
				a[i].lx=x;
				//a[i].x1=x-len; a[i].x2=x;
				//a[i].y1=y; a[i].y2=y-len;
			}*/
		} else {
			scanf("%d%d",&a[i].x,&a[i].y);
			a[i].tim=++tim;	//a[i].lx=a[i].x;
		}
	}
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==1) q[++tot]=a[i];
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			//cerr<<a[i].x<<" "<<a[i].y<<endl;
			//cerr<<a[i].x<<endl;
			q[++tot]=a[i];
		}
		else if (a[i].d==3) {
			a[i].x=nn-a[i].x;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		} else if (a[i].d==4) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	for (int i=1;i<=tim;++i)
		printf("%d\n",ans[i]);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int M=100050;
struct tree {
	int s,fa,l,r,v;
}T[M*60];
int sum;
struct node {
	int tim,x,y,len,k,d;
}a[M],q[M],b[M];
int tot;
int nn,tg,vis[M],root[M],N;
int ans[M],n,m,tim;
inline void Updata(int k)
{
	if (!k) return;
	T[k].s=T[T[k].l].s+T[T[k].r].s+1;
}
inline void turn(int x)
{
	int y=T[x].fa,z=T[y].fa,b= (T[y].l==x) ? T[x].r : T[x].l;
	T[y].fa=x; T[x].fa=z; if (b) T[b].fa=y;
	(T[z].l==y ? T[z].l : T[z].r) = x;
	if (T[y].l==x) T[x].r=y,T[y].l=b;
	else T[x].l=y,T[y].r=b;
	Updata(y);
	return;
}
inline void splay(int x,int fa,int &rt)
{
	int y,z;
	while (T[x].fa!=fa)
	{
		y=T[x].fa; z=T[y].fa;
		if (z!=fa) {
			if ((T[y].l==x)==(T[z].l==y)) turn(y);
			else turn(x);
		}
		turn(x);
	}
	Updata(x);
	if (!fa) rt=x;
}
inline void Init(int k)
{
	T[k].s=T[k].l=T[k].r=T[k].fa=T[k].v=0;
}
inline void Ins(int &k,int fa,int v)
{
	if (!k) {
		++sum;
		Init(sum);
		T[k=sum].v=v;
		T[k].s=1;
		T[k].fa=fa;
		return;
	}
	if (T[k].v<=v) Ins(T[k].l,k,v);
	else Ins(T[k].r,k,v);
}
inline void Add(node a)
{
	int v=a.x+a.y+a.len;
	//if (a.d==3) cerr<<v<<endl;
	for (int i=a.y;i<=nn;i+=i & (-i)) {
		//if (tot==18&&a.y==19) cerr<<i<<endl;
		if (vis[i]!=tg) {
			vis[i]=tg;
			//Init(root[i]);
			root[i]=0;
		}
		Ins(root[i],0,v);
		splay(sum,0,root[i]);
		//if (tot==18&&i==25) cerr<<a.x<<endl;
	}
}
inline int Find(int k,int v)
{
	int g=0;
	while (k) {
		//cerr<<T[k].r<<endl;
		if (T[k].v>=v) {
			g=k;
			k=T[k].r;
		} else {
			k=T[k].l;
		}
	}
	return g;
}
inline int Ask(node a)
{
	//cerr<<T[6].r<<endl;
	int r=0,v=a.x+a.y,k;
	for (int i=a.y;i;i-=i & (-i))
	{
		//cerr<<i<<endl;
		if (vis[i]==tg) {
			k=Find(root[i],v);
			if (k) {
				splay(k,0,root[i]);
				r+=T[T[k].l].s+1;
			}
			//if (tot==18&&a.x==7&&a.y==25) cerr<<T[root[i]].v<<endl;
		}
	}
	return r;
}
inline void cdq_Solve(int l,int r)
{
	if (l==r) return;
	int mid=l+r>>1;
	cdq_Solve(l,mid); cdq_Solve(mid+1,r);
//	if (l==1&&r==18&&r==tot)
//	{
		//for (int i=1;i<=tot;++i)
		//	cerr<<q[i].x<<endl;
//	}
	++tg; sum=0;
	int t=l-1,j=l;
	for (int i=mid+1;i<=r;++i)
	{
		while (j<=mid&&q[j].x<=q[i].x) {
			b[++t]=q[j];
			if (q[j].k==1)
			{
				Add(q[j]);
				//if (l==1&&r==tot&&tot==18) cerr<<q[j].y<<" "<<T[1].v<<" "<<sum<<endl;
			}
			++j;
		}
		//if (tot==18&&l==1&&r==tot) cerr<<j<<" "<<T[1].v<<endl;
		b[++t]=q[i];
		if (q[i].k==2) ans[q[i].tim]+=Ask(q[i]);
	}
	while (j<=mid) { b[++t]=q[j]; ++j; }
	//for (int i=l;i<=mid;++i) Clear(q[i]);
	for (int i=l;i<=r;++i) q[i]=b[i];
	//cerr<<ans[8]<<endl;
	return;
}

int main()
{
	scanf("%d%d",&n,&m);
	nn=n<<1;	N=nn*2;
	for (int i=1;i<=m;++i)
	{
		scanf("%d",&a[i].k);
		if (a[i].k==1) {
			scanf("%d%d%d%d",&a[i].d,&a[i].x,&a[i].y,&a[i].len);
		} else {
			scanf("%d%d",&a[i].x,&a[i].y);
			a[i].tim=++tim;
		}
	}
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==1) q[++tot]=a[i];
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2||a[i].d==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			//cerr<<a[i].x<<" "<<a[i].y<<endl;
			//cerr<<a[i].x<<endl;
			q[++tot]=a[i];
		}
		else if (a[i].d==3) {
			a[i].x=nn-a[i].x;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	tot=0;
	for (int i=1;i<=m;++i)
		if (a[i].k==2) {
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		} else if (a[i].d==4) {
			a[i].x=nn-a[i].x;
			a[i].y=nn-a[i].y;
			q[++tot]=a[i];
		}
	cdq_Solve(1,tot);
	for (int i=1;i<=tim;++i)
		printf("%d\n",ans[i]);
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int ck,n,q;
int dir[120000];
int opt[120000];
int ans[120000];
int pos[120000][2];
struct bit
{
	int tag[5200][5200];
	int val[5200][5200];
	inline int query(int x,int y)
	{
	//	printf("%d-%d\n",x,y);
		int ss=0;
		int yy=y;
		while (x!=0)
		{
			y=yy;
			while (y!=0)
			{
				if(tag[x][y]!=ck)
				{
					tag[x][y]=ck;
					val[x][y]=0;
				}
				ss+=val[x][y];
				y-=(y&(-y));
			}
			x-=(x&(-x));
		}//printf("=%d\n",ss);
		return ss;
	}
	inline void edit(int x,int y,int va)
	{
	//	printf("%d=%d\n",x,y);
		int yy=y;
		while (x<=n)
		{
			y=yy;
			while (y<=n)
			{
				if(tag[x][y]!=ck)
				{
					tag[x][y]=ck;
					val[x][y]=0;
				}
				val[x][y]+=va;
				y+=(y&(-y));
			}
			x+=(x&(-x));
		}
	}
}sgt;
struct query
{
	int x,y,type,comp,id;
}qu[120000],tmp[120000];
int tot,ctot;
inline bool cmp(query x,query y)
{
	if(x.comp==y.comp)return x.type<y.type;
	return x.comp>y.comp;
}
inline void solve(int le,int ri)
{
	if(le==ri)return;
	int mi=((le+ri)>>1),c1=0,c2=0;
	solve(le,mi);solve(mi+1,ri);
	ctot=0;
	for (int i=le;i<=mi;i++)
	{
		if(qu[i].type==1)
		{
			c1++;
			ctot++;
			tmp[ctot]=qu[i];
		}
	}
	for (int i=mi+1;i<=ri;i++)
	{
		if(qu[i].type==2)
		{
			c2++;
			ctot++;
			tmp[ctot]=qu[i];
		}
	}
	if(c1*c2==0)return;
	ck++;
//	printf("%d %d ctot:%d\n",le,ri,ctot);
	sort(tmp+1,tmp+ctot+1,cmp);
	for (int i=1;i<=ctot;i++)
	{
		if(tmp[i].type==1)
		{
			sgt.edit(tmp[i].x,tmp[i].y,1);
		}
		else
		{
			ans[tmp[i].id]+=sgt.query(tmp[i].x,tmp[i].y);
		}
	}
}
int lee[120000];
inline void work(int di)
{
//	printf("%d\n",di);
	tot=0;
	for (int i=1;i<=q;i++)
	{
		if(opt[i]==2||dir[i]==di)
		{
			tot++;
			int x1,x2;
			if(di==1)
			{
				x1=pos[i][0];
				x2=pos[i][1];
			}
			else if(di==2)
			{
				x1=pos[i][0];
				x2=n+1-pos[i][1];
			}
			else if(di==3)
			{
				x1=n+1-pos[i][0];
				x2=pos[i][1];
			}
			else
			{
				x1=n+1-pos[i][0];
				x2=n+1-pos[i][1];
			}
			qu[tot].x=x1;
			qu[tot].y=x2;
			qu[tot].type=opt[i];
			qu[tot].id=i;
			if(opt[i]==2)
			{
				qu[tot].comp=x1+x2;
			}
			else
			{
				qu[tot].comp=x1+x2+lee[i];
			}
		//	printf("%d %d %d %d\n",x1,x2,qu[tot].type,qu[tot].comp);
		}
	}
	solve(1,tot);
}
int main()
{
	scanf("%d %d",&n,&q);
	for (int i=1;i<=q;i++)
	{
		scanf("%d",&opt[i]);
		if(opt[i]==1)scanf("%d %d %d %d",&dir[i],&pos[i][0],&pos[i][1],&lee[i]);
		else scanf("%d %d",&pos[i][0],&pos[i][1]);
	}
	for (int i=1;i<=4;i++)
	{
		work(i);
	}
	for (int i=1;i<=q;i++)
	{
		if(opt[i]==2)printf("%d\n",ans[i]);
	}
	return 0;
}


#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<iomanip>
#include<utility>
using namespace std;
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define rg register
#define il inline
#define lch(x) ((x)<<1)
#define rch(x) ((x)<<1^1)
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define rep0(i,n) for(register int i=0;i<(n);++i)
#define rep(i,st,ed) for(register int i=(st);i<=(ed);++i)
#define per(i,ed,st) for(register int i=(ed);i>=(st);--i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double dbl;
typedef long double ldb;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<typename T> il T qmin(const T &a,const T &b){return a<b?a:b;}
template<typename T> il T qmax(const T &a,const T &b){return a>b?a:b;}
template<typename T> il void getmin(T &a,const T &b){if(a>b) a=b;}
template<typename T> il void getmax(T &a,const T &b){if(a<b) a=b;}
il void fileio(string s){
	freopen((s+".in").c_str(),"r",stdin);
	freopen((s+".out").c_str(),"w",stdout);
}

const int inf=(int)1e9+7;
const ll linf=(ll)1e17+7;
const int N=5001;

int n,q;

template<typename T> il void ins(T sum,int x,int y,int v){
	int m=sizeof(sum[0])/sizeof(int)-1;
	for(;x<=n;x+=x&-x){
		for(int cury=y;cury<=m;cury+=cury&-cury){
			sum[x][cury]+=v;
		}
	}
}

template<typename T> il int qsum(T sum,int x,int y){
	int m=sizeof(sum[0])/sizeof(int)-1;
	int ans=0;
	for(;x;x^=x&-x){
		for(int cury=y;cury;cury^=cury&-cury){
			ans+=sum[x][cury];
		}
	}
	return ans;
}

int ori[N][N],up[N][N<<1],down[N][N<<1];
//(x,y) (x,x+y-1) (x,y-x+n)

int main(){
	scanf("%d%d",&n,&q);
	while(q--){
		int type;
		scanf("%d",&type);
		if(type==1){
			int dir,x,y,len;
			scanf("%d%d%d%d",&dir,&x,&y,&len);
			if(dir==1){
				ins(ori,x,y,1);
				ins(ori,x+len+1,y,-1);
				ins(up,x,x+y+len,-1);
				ins(up,x+len+1,x+y+len,1);
			}else if(dir==2){
				ins(down,x,y-len-x+n,1);
				ins(down,x+len+1,y-len-x+n,-1);
				ins(ori,x,y+1,-1);
				ins(ori,x+len+1,y+1,1);
			}else if(dir==3){
				ins(ori,x-len,y,1);
				ins(ori,x+1,y,-1);
				ins(down,x-len,y-(x-len)+n+1,-1);
				ins(down,x+1,y-(x-len)+n+1,1);
			}else if(dir==4){
				ins(up,x-len,x+y-len-1,1);
				ins(up,x+1,x+y-len-1,-1);
				ins(ori,x-len,y+1,-1);
				ins(ori,x+1,y+1,1);
			}else assert(false);
		}else if(type==2){
			int x,y;
			scanf("%d%d",&x,&y);
			printf("%d\n",qsum(ori,x,y)+qsum(up,x,x+y-1)+qsum(down,x,y-x+n));
		}else{
			assert(false);
		}
	}
	return 0;
}


#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>
#include <cassert>
#include <algorithm>

using namespace std;

#define foreach(e,x) for(__typeof((x).begin()) e=(x).begin(); e!=(x).end(); ++e)

const int N = 100000 + 10;
const int M = 5000 + 10;

struct Data
{
	int x, y, comp, tp, id;
	Data() {}
	Data(int x, int y, int comp, int tp, int id) : x(x), y(y), comp(comp), tp(tp), id(id) {}
	int operator < (const Data &that) const {
		return comp > that.comp || (comp == that.comp && tp < that.tp);
	}
};

int n, q, tot;
int x[N], y[N], dir[N], len[N];
int ret[N];
Data a[N];
int flag;
int bit[M][M];
int tag[M][M];

void insert(int x, int y)
{
	for( ; x <= n; x += x & -x) {
		for(int ty = y; ty <= n; ty += ty & -ty) {
			if (tag[x][ty] != flag) {
				tag[x][ty] = flag;
				bit[x][ty] = 0;
			}
			bit[x][ty] ++;
		}
	}
}

int query(int x, int y)
{
	int ret = 0;
	for( ; x; x -= x & -x) {
		for(int ty = y; ty; ty -= ty & -ty) {
			if (tag[x][ty] != flag) {
				tag[x][ty] = flag;
				bit[x][ty] = 0;
			}
			ret += bit[x][ty];
		}
	}
	return ret;
}

void solve(int l, int r)
{
	if (l >= r) return;
	int mid = (l + r) >> 1;
	solve(l, mid); solve(mid + 1, r);
	int cnt0 = 0, cnt1 = 0;
	vector<Data> vec;
	for(int i = l; i <= mid; ++ i) {
		if (a[i].tp == 0) {
			++ cnt0;
			vec.push_back(a[i]);
		}
	}
	for(int i = mid + 1; i <= r; ++ i) {
		if (a[i].tp == 1) {
			++ cnt1;
			vec.push_back(a[i]);
		}
	}
	if (cnt0 == 0 || cnt1 == 0) return;
	sort(vec.begin(), vec.end());
	flag ++;
	for(int i = 0; i < vec.size(); ++ i) {
		if (vec[i].tp == 0) {
			insert(vec[i].x, vec[i].y);
		} else {
			ret[vec[i].id] += query(vec[i].x, vec[i].y);
		}
	}
}

void calcAns(int state)
{
	tot = 0;

	for(int i = 0; i < q; ++ i) {
		int curX = (state & 2) ? n + 1 - x[i] : x[i];
		int curY = (state & 1) ? n + 1 - y[i] : y[i];
		if (curX < 1 || curX > n || curY < 1 || curY > n) continue;
		if (dir[i] < 0) {
			a[tot ++] = Data(curX, curY, curX + curY, 1, i);
		}
		if (dir[i] == state) {
			a[tot ++] = Data(curX, curY, curX + curY + len[i], 0, i);
		}
	}

	solve(0, tot - 1);
}

void solve()
{
	cin >> n >> q;
	int tp;
	for(int i = 0; i < q; ++ i) {
		scanf("%d", &tp);
		if (tp == 2) {
			dir[i] = -1;
			scanf("%d%d", x + i, y + i);
		} else {
			scanf("%d%d%d%d", dir + i, x + i, y + i, len + i);
			dir[i] --;
		}
	}
	for(int i = 0; i < 4; ++ i) {
		calcAns(i);
	}
	for(int i = 0; i < q; ++ i) {
		if (dir[i] < 0) {
			printf("%d\n", ret[i]);
		}
	}
}

int main()
{
	solve();
	return 0;
}


#pragma GCC target ("mmx,sse,sse2")
//    #pragma GCC optimize (3)
#include "immintrin.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <ctime>
#include <cassert>
using namespace std;

typedef __m128i mi;

__m512i haha;

#define M(x) _mm_##x##_si128
#define M16(x) _mm_##x##_epi16
#define M32(x) _mm_##x##_epi32

#define rep(i, from, to) for (int i = from; i < int(to); ++i)
#define trav(a, x) for (auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

struct Counter {
    int N;
    short *xs, *ys, *ups;
    Counter() : N(0) {
        xs = (short*)_mm_malloc(200000, 32);
        ys = (short*)_mm_malloc(200000, 32);
        ups = (short*)_mm_malloc(200000, 32);
    }
    void insert(short x, short y, short len) {
        xs[N] = x;
        ys[N] = y;
        ups[N] = x + y + len;
        N++;
    }
    int count(short x, short y) {
        mi mx = M16(set1)(x);
        mi my = M16(set1)(y);
        mi msum = M16(set1)(x + y);
        int ans = 0;
        int i = 0;
        mi* mxs = (mi*)xs;
        mi* mys = (mi*)ys;
        mi* mups = (mi*)ups;
        int j = 0;
        int res = N;
        mi mres = M16(set1)(0);
        while (i + 8 <= N) {
            mi fails = M(or)(
                M(or)(
                    M16(cmplt)(my, mys[j]),
                    M16(cmplt)(mx, mxs[j])
                ),
                M16(cmplt)(mups[j], msum)
            );
            mres = M16(add)(mres, fails);
            i += 8;
            j++;
        }

        union { unsigned short v[8]; mi m;} u; u.m = mres;
        rep(i,0,8)
            res -= (int)(unsigned short)-u.v[i];

        while (i < N) {
            if (!(ys[i] <= y && xs[i] <= x && x + y <= ups[i]))
                res--;
            ++i;
        }
        return res;
    }
};

int main() {
    cin.sync_with_stdio(false);
    int N, Q;
    cin >> N >> Q;
    Counter d1, d2, d3, d4;
    rep(qi,0,Q) {
        short type;
        cin >> type;
        if (type == 1) {
            short dir, x, y, len;
            cin >> dir >> x >> y >> len;
#ifdef BENCH
            rep(ti,0,10000) {
#endif
            if (dir == 1) d1.insert((short)x, (short)y, len);
            if (dir == 2) d2.insert((short)x, (short)-y, len);
            if (dir == 3) d3.insert((short)-x, (short)y, len);
            if (dir == 4) d4.insert((short)-x, (short)-y, len);
#ifdef BENCH
            }
#endif
        }
        else {
            assert(type == 2);
            short x, y;
            cin >> x >> y;
            int ans = 0;
#ifdef BENCH
            rep(ti,0,10000) {
#endif
            ans += d1.count((short)x, (short)y);
            ans += d2.count((short)x, (short)-y);
            ans += d3.count((short)-x, (short)y);
            ans += d4.count((short)-x, (short)-y);
#ifdef BENCH
            }
#endif
            cout << ans << '\n';
        }
    }
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <ctime>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define inf 1000000007
#define mod 1000000007
#define x first
#define y second
#define pi acos(-1.0)
#define DBG(x) cerr<<(#x)<<"="<<x<<"\n";
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)
#define ull unsigned long long
#define ll long long
#define N 5005

template <class T> inline void Min(T &a,T b){if(a>b)a=b;}
template <class T> inline void Max(T &a,T b){if(a<b)a=b;}

int h[N][N],f[2][N<<1][N];
void upd(int (&f)[N][N],int x,int y,int v){
    for(;x<N;x+=x&-x){
        for(int i=y;i<N;i+=i&-i)f[x][i]+=v;
    }
}
void upd(int (&f)[N<<1][N],int x,int y,int v){
    for(;x<N<<1;x+=x&-x){
        for(int i=y;i<N;i+=i&-i)f[x][i]+=v;
    }
}
int get(int (&f)[N][N],int x,int y){
    int ans=0;
    for(;x>0;x-=x&-x){
        int i=y;
        for(;i>0;i-=i&-i)ans+=f[x][i];
    }
    return ans;
}
int get(int (&f)[N<<1][N],int x,int y){
    int ans=0;
    for(;x>0;x-=x&-x){
        for(int i=y;i>0;i-=i&-i)ans+=f[x][i];
    }
    return ans;
}
int main()
{
    //clock_t start=clock();
    int T,i,j,k,m,n;
    scanf("%d%d",&n,&m);
    int d,x,y,len;
    while(m--){
        scanf("%d",&k);
        if(k==1){
            scanf("%d%d%d%d",&d,&x,&y,&len);
            if(d==1){
                upd(h,x,y,1);
                upd(h,x,y+len+1,-1);
                upd(f[0],x+y+len+1,y,-1);
                upd(f[0],x+y+len+1,y+len+1,1);
            }
            else if(d==2){
                upd(h,x,y-len,1);
                upd(h,x,y+1,-1);
                upd(f[1],n+2+x-y+len,y-len,-1);
                upd(f[1],n+2+x-y+len,y+1,1);
            }
            else if(d==3){
                upd(h,x+1,y,-1);
                upd(h,x+1,y+len+1,1);
                upd(f[1],n+1+x-y-len,y,1);
                upd(f[1],n+1+x-y-len,y+len+1,-1);
            }
            else{
                upd(h,x+1,y-len,-1);
                upd(h,x+1,y+1,1);
                upd(f[0],x+y-len,y-len,1);
                upd(f[0],x+y-len,y+1,-1);
            }
        }
        else{
            scanf("%d%d",&x,&y);
            int ans=get(h,x,y)+get(f[0],x+y,y)+get(f[1],x-y+1+n,y);
            printf("%d\n",ans);
        }
    }
    //cerr<<"total time:"<<(clock()-start)<<"\n";
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <ctime>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define inf 1000000007
#define mod 1000000007
#define x first
#define y second
#define pi acos(-1.0)
#define DBG(x) cerr<<(#x)<<"="<<x<<"\n";
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)
#define ull unsigned long long
#define ll long long
#define N 5005

template <class T> inline void Min(T &a,T b){if(a>b)a=b;}
template <class T> inline void Max(T &a,T b){if(a<b)a=b;}

int h[N][N],f[2][N<<1][N];
void upd(int (&f)[N][N],int n,int x,int y,int v){
    for(;x<=n;x+=x&-x){
        for(int i=y;i<=n;i+=i&-i)f[x][i]+=v;
    }
}
void upd(int (&f)[N<<1][N],int n,int x,int y,int v){
    for(;x<=n;x+=x&-x){
        for(int i=y;i<=n;i+=i&-i)f[x][i]+=v;
    }
}
int get(int (&f)[N][N],int x,int y){
    int ans=0;
    for(;x>0;x-=x&-x){
        int i=y;
        for(;i>0;i-=i&-i)ans+=f[x][i];
    }
    return ans;
}
int get(int (&f)[N<<1][N],int x,int y){
    int ans=0;
    for(;x>0;x-=x&-x){
        for(int i=y;i>0;i-=i&-i)ans+=f[x][i];
    }
    return ans;
}
int main()
{
    //clock_t start=clock();
    int T,i,j,k,m,n;
    scanf("%d%d",&n,&m);
    int d,x,y,len;
    while(m--){
        scanf("%d",&k);
        if(k==1){
            scanf("%d%d%d%d",&d,&x,&y,&len);
            if(d==1){
                upd(h,n,x,y,1);
                upd(h,n,x,y+len+1,-1);
                upd(f[0],n*2+1,x+y+len+1,y,-1);
                upd(f[0],n*2+1,x+y+len+1,y+len+1,1);
            }
            else if(d==2){
                upd(h,n,x,y-len,1);
                upd(h,n,x,y+1,-1);
                upd(f[1],2*n+1,n+2+x-y+len,y-len,-1);
                upd(f[1],2*n+1,n+2+x-y+len,y+1,1);
            }
            else if(d==3){
                upd(h,n,x+1,y,-1);
                upd(h,n,x+1,y+len+1,1);
                upd(f[1],2*n+1,n+1+x-y-len,y,1);
                upd(f[1],2*n+1,n+1+x-y-len,y+len+1,-1);
            }
            else{
                upd(h,n,x+1,y-len,-1);
                upd(h,n,x+1,y+1,1);
                upd(f[0],n*2+1,x+y-len,y-len,1);
                upd(f[0],n*2+1,x+y-len,y+1,-1);
            }
        }
        else{
            scanf("%d%d",&x,&y);
            int ans=get(h,x,y)+get(f[0],x+y,y)+get(f[1],x-y+1+n,y);
            printf("%d\n",ans);
        }
    }
    //cerr<<"total time:"<<(clock()-start)<<"\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
struct BinaryIndexTree {
	int n, a[MAXN];
	void init(int x) {
		n = x;
		memset(a, 0, sizeof(a));
	}
	void modify(int x, int d) {
		for (int i = x; i <= n; i += i & -i)
			a[i] += d;
	}
	int query(int x) {
		int ans = 0;
		for (int i = x; i >= 1; i -= i & -i)
			ans += a[i];
		return ans;
	}
} BIT[3];
int n, q, ans[MAXN];
struct info {int x, y, val, type; } a[MAXN];
struct event {int type, x, d, timer; } b[MAXN * 5];
bool cmp(event x, event y) {
	if (x.timer == y.timer) return x.type < y.type;
	else return x.timer < y.timer;
}
void add(int &tot, int l, int r, int type, int x, int d) {
	b[++tot] = (event) {-type, x, d, l};
	b[++tot] = (event) {-type, x, -d, r + 1};
}
void solve(int l, int r) {
	if (l == r) return;
	int mid = (l + r) / 2, tot = 0;
	solve(l, mid), solve(mid + 1, r);
	for (int i = l; i <= mid; i++)
		if (a[i].type) {
			int x = a[i].x, y = a[i].y, len = a[i].val;
			if (a[i].type == 1) {
				add(tot, x, x + len, 0, y, 1);
				add(tot, x, x + len, 1, x + y + len + 1, -1);
			}
			if (a[i].type == 2) {
				add(tot, x, x + len, 2, y - x + n - len, 1);
				add(tot, x, x + len, 0, y + 1, -1);
			}
			if (a[i].type == 3) {
				add(tot, x - len, x, 0, y, 1);
				add(tot, x - len, x, 2, y - x + n + len + 1, -1);
			}
			if (a[i].type == 4) {
				add(tot, x - len, x, 1, x + y - len, 1);
				add(tot, x - len, x, 0, y + 1, -1);
			}
		}
	for (int i = mid + 1; i <= r; i++)
		if (a[i].type == 0) b[++tot] = (event) {a[i].val, a[i].y, 0, a[i].x};
	sort(b + 1, b + tot + 1, cmp);
	for (int i = 1; i <= tot; i++) {
		if (b[i].type <= 0) BIT[-b[i].type].modify(b[i].x, b[i].d);
		else {
			int home = b[i].type, x = b[i].timer, y = b[i].x;
			ans[home] += BIT[0].query(y);
			ans[home] += BIT[1].query(x + y);
			ans[home] += BIT[2].query(y - x + n);
		}
	}
}
int main() {
	read(n), read(q);
	BIT[0].init(n * 2);
	BIT[1].init(n * 2);
	BIT[2].init(n * 2);
	for (int i = 1; i <= q; i++) {
		int opt; read(opt);
		if (opt == 1) {
			read(a[i].type), read(a[i].x);
			read(a[i].y), read(a[i].val);
		} else {
			read(a[i].x), read(a[i].y);
			a[i].type = 0, a[i].val = i;
		}
	}
	solve(1, q);
	for (int i = 1; i <= q; i++)
		if (a[i].type == 0) printf("%d\n", ans[i]);
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <cctype>
#include <cstring>
#include <vector>
using namespace std;

namespace zyt
{
	template<typename T>
	inline bool read(T &x)
	{
		char c;
		bool f = false;
		x = 0;
		do
			c = getchar();
		while (c != EOF && c != '-' && !isdigit(c));
		if (c == EOF)
			return false;
		if (c == '-')
			f = true, c = getchar();
		do
			x = x * 10 + c - '0', c = getchar();
		while (isdigit(c));
		if (f)
			x = -x;
		return true;
	}
	template<typename T>
	inline void write(T x)
	{
		static char buf[20];
		char *pos = buf;
		if (x < 0)
			putchar('-'), x = -x;
		do
			*pos++ = x % 10 + '0';
		while (x /= 10);
		while (pos > buf)
			putchar(*--pos);
	}
	const int N = 1e4 + 10, Q = 1e5 + 10;
	int data[N][N], ans[Q];
	struct _mdf
	{
		int dir, x, y, len;
	}arr[Q];
	namespace Tree_Array
	{
		inline int lowbit(const int x)
		{
			return x & (-x);
		}
		int query(int x, int y)
		{
			int ans = 0;
			if (!x || !y)
				return 0;
			x = N - x, y = N - y;
			for (int i = x; i; i -= lowbit(i))
				for (int j = y; j; j -= lowbit(j))
					ans += data[i][j];
			return ans;
		}
		void add(int x, int y, const int v)
		{
			if (!x || !y)
				return;
			x = N - x, y = N - y;
			for (int i = x; i < N; i += lowbit(i))
				for (int j = y; j < N; j += lowbit(j))
					data[i][j] += v;
		}
		void clear()
		{
			memset(data, 0, sizeof(data));
		}
	}
	int n, q;
	void rotate(const int x)
	{
		const static bool dx[5] = {0, 0, 0, 1, 1};
		const static bool dy[5] = {0, 0, 1, 0, 1};
		for (int i = 1; i <= q; i++)
		{
			if (dx[x])
				arr[i].x = 5000 - arr[i].x + 1;
			if (dy[x])
				arr[i].y = 5000 - arr[i].y + 1;
		}
	}
	void solve(const int x)
	{
		using namespace Tree_Array;
		rotate(x);
		for (int i = 1; i <= q; i++)
		{
			if (arr[i].dir == x)
				Tree_Array::add(arr[i].x + arr[i].y + arr[i].len, 1, 1);
			else if (arr[i].dir == 5)
				ans[i] += Tree_Array::query(arr[i].x + arr[i].y, 1);
		}
		clear();
		for (int i = 1; i <= q; i++)
		{
			if (arr[i].dir == x)
				Tree_Array::add(arr[i].x + arr[i].y + arr[i].len, arr[i].x - 1, -1);
			else if (arr[i].dir == 5)
				ans[i] += Tree_Array::query(arr[i].x + arr[i].y + arr[i].len, arr[i].x);
		}
		clear();
		for (int i = 1; i <= q; i++)
		{
			if (arr[i].dir == x)
				Tree_Array::add(arr[i].x + arr[i].y + arr[i].len, arr[i].y - 1, -1);
			else if (arr[i].dir == 5)
				ans[i] += Tree_Array::query(arr[i].x + arr[i].y + arr[i].len, arr[i].y);
		}
		clear();
		for (int i = 1; i <= q; i++)
		{
			if (arr[i].dir == x)
				Tree_Array::add(arr[i].x - 1, arr[i].y - 1, 1);
			else if (arr[i].dir == 5)
				ans[i] += Tree_Array::query(arr[i].x, arr[i].y);
		}
		clear();
		rotate(x);
	}
	int work()
	{
		using namespace Tree_Array;
		read(n), read(q);
		for (int i = 1; i <= q; i++)
		{
			int opt;
			read(opt);
			if (opt == 1)
				read(arr[i].dir), read(arr[i].x), read(arr[i].y), read(arr[i].len);
			else
				arr[i].dir = 5, read(arr[i].x), read(arr[i].y);
		}
		for (int i = 1; i < 5; i++)
			solve(i);
		for (int i = 1; i <= q; i++)
			if (arr[i].dir == 5)
				write(ans[i]), putchar('\n');
		return 0;
	}
}
int main()
{
	return zyt::work();
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5005,M=100005;
int read(){
	int f=1,g=0;
	char ch=getchar();
	for (;!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
	for (;isdigit(ch);ch=getchar()) g=g*10+ch-'0';
	return f*g;
}
int n,q,ans[M];
struct node{int typ,x,y,t;}que[M];
struct BIT{
	int f[N*2];
	inline int lowbit(int x){return x&(-x);}
	void clear(){memset(f,0,sizeof(f));}
	void add(int x,int v){for (;x<n*2;x+=lowbit(x)) f[x]+=v;}
	void modify(int l,int r,int v){add(l,v);add(r+1,-v);}
	int query(int x){
		int t=0;
		for (;x;x-=lowbit(x)) t+=f[x];
		return t;
	}
}a,b;
struct BIT2{
	BIT f[N];
	inline int lowbit(int x){return x&(-x);}
	void clear(){memset(f,0,sizeof(f));}
	void add(int x,int l,int r,int v){for (;x<=n;x+=lowbit(x))f[x].modify(l,r,v);}
	void modify(int l,int r,int fl,int fr,int v){add(l,fl,fr,v);add(r,fl,fr,-v);}
	int query(int x,int y){
		int t=0;
		for (;x;x-=lowbit(x)) t+=f[x].query(y);
		return t;
	}
}f;
int main(){
	n=read();q=read();
	for (int i=1;i<=q;i++)
	if (read()==1){
		int dir=read(),x=read(),y=read(),t=read();
		que[i]=(node){dir,x,y,t};
		if (dir==1) a.modify(x+y,x+y+t,1);
		else if (dir==2) b.modify(x+n-y+1,x+n-(y-t)+1,1);
		else if (dir==3) b.modify(x+n-(y+t)+1,x+n-y+1,1);
		else a.modify(x+y-t,x+y,1);
	}
	else{
		int x=read(),y=read();
		que[i]=(node){0,x,y,0};
		ans[i]=a.query(x+y)+b.query(x+n-y+1);
	}

	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==1) f.modify(1,x-1,x+y,x+y+t,-1);
		else if (dir==4) f.modify(x+1,n,x+y-t,x+y,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(x,x+y);
	}
	f.clear();
	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==1) f.modify(1,y-1,x+y,x+y+t,-1);
		else if (dir==4) f.modify(y+1,n,x+y-t,x+y,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(y,x+y);
	}
	f.clear();

	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==2) f.modify(1,x-1,x+n-y+1,x+n-(y-t)+1,-1);
		else if (dir==3) f.modify(x+1,n,x+n-(y+t)+1,x+n-y+1,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(x,x+n-y+1);
	}
	f.clear();
	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==2) f.modify(y+1,n,x+n-y+1,x+n-(y-t)+1,-1);
		else if (dir==3) f.modify(1,y-1,x+n-(y+t)+1,x+n-y+1,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(y,x+n-y+1);
	}
	f.clear();

	for (int i=1;i<=q;i++)
	if (!que[i].typ) printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5005,M=100005;
int read(){
	int f=1,g=0;
	char ch=getchar();
	for (;!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
	for (;isdigit(ch);ch=getchar()) g=g*10+ch-'0';
	return f*g;
}
int n,q,ans[M];
struct node{int typ,x,y,t;}que[M];
struct BIT{
	int f[N*2];
	inline int lowbit(int x){return x&(-x);}
	void clear(){memset(f,0,sizeof(f));}
	void add(int x,int v){for (;x<n*2;x+=lowbit(x)) f[x]+=v;}
	void modify(int l,int r,int v){add(l,v);add(r+1,-v);}
	int query(int x){
		int t=0;
		for (;x;x-=lowbit(x)) t+=f[x];
		return t;
	}
}a,b;
struct BIT2{
	BIT f[N];
	inline int lowbit(int x){return x&(-x);}
	void clear(){memset(f,0,sizeof(f));}
	void add(int x,int l,int r,int v){for (;x<=n;x+=lowbit(x))f[x].modify(l,r,v);}
	void modify(int l,int r,int fl,int fr,int v){
		if ((l>r)||(fl>fr)) return;
		add(l,fl,fr,v);add(r+1,fl,fr,-v);
	}
	int query(int x,int y){
		int t=0;
		for (;x;x-=lowbit(x)) t+=f[x].query(y);
		return t;
	}
}f;
int main(){
	n=read();q=read();
	for (int i=1;i<=q;i++)
	if (read()==1){
		int dir=read(),x=read(),y=read(),t=read();
		que[i]=(node){dir,x,y,t};
		if (dir==1) a.modify(x+y,x+y+t,1);
		else if (dir==2) b.modify(x+n-y+1,x+n-(y-t)+1,1);
		else if (dir==3) b.modify(x+n-(y+t)+1,x+n-y+1,1);
		else a.modify(x+y-t,x+y,1);
	}
	else{
		int x=read(),y=read();
		que[i]=(node){0,x,y,0};
		ans[i]=a.query(x+y)+b.query(x+n-y+1);
	}

	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==1) f.modify(1,x-1,x+y,x+y+t,-1);
		else if (dir==4) f.modify(x+1,n,x+y-t,x+y,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(x,x+y);
	}
	f.clear();
	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==1) f.modify(1,y-1,x+y,x+y+t,-1);
		else if (dir==4) f.modify(y+1,n,x+y-t,x+y,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(y,x+y);
	}
	f.clear();

	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==2) f.modify(1,x-1,x+n-y+1,x+n-(y-t)+1,-1);
		else if (dir==3) f.modify(x+1,n,x+n-(y+t)+1,x+n-y+1,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(x,x+n-y+1);
	}
	f.clear();
	for (int i=1;i<=q;i++)
	if (que[i].typ){
		int dir=que[i].typ,x=que[i].x,y=que[i].y,t=que[i].t;
		if (dir==2) f.modify(y+1,n,x+n-y+1,x+n-(y-t)+1,-1);
		else if (dir==3) f.modify(1,y-1,x+n-(y+t)+1,x+n-y+1,-1);
	}
	else{
		int x=que[i].x,y=que[i].y;
		ans[i]+=f.query(y,x+n-y+1);
	}
	f.clear();

	for (int i=1;i<=q;i++)
	if (!que[i].typ) printf("%d\n",ans[i]);
	return 0;
}


#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
#define REP(i,s,t) for(int i=s;i<=t;i++)
using namespace std;
const int maxn=1e6+5;
int n,inp[maxn][5],ans[maxn],Q;
struct BIT{
    int c[maxn];
    void _modify(int x,int v){for(;x<=n*2;x+=lowbit(x)) c[x]+=v;}
    void modify(int l,int r,int v){_modify(l,v); _modify(r+1,-v);}
    int query(int x){
        int ret=0;
        for(;x;x-=lowbit(x)) ret+=c[x];
        return ret;
    }
}t1,t2;
struct rec{int p1,p2,p3,p4;}qry[maxn],pro[maxn];
bool cmp(rec a,rec b){
    int k1=a.p1==-1?a.p2+a.p4:a.p2,k2=b.p1==-1?b.p2+b.p4:b.p2;
    if(k1!=k2) return k1<k2;
    if(a.p1==0) k1=1;
    else if(a.p1==-1) k1=3;
    else k1=2;
    if(b.p1==0) k2=1;
    else if(b.p1==-1) k2=3;
    else k2=2;
    return k1<k2;
}
void solve(int nl,int nr){
    if(nl>=nr) return;
    int mid=nl+nr>>1,cnt=0;
    REP(i,nl,mid) if(!qry[i].p1) pro[++cnt]=qry[i],pro[++cnt]=qry[i],pro[cnt].p1=-1;
    REP(i,mid+1,nr) if(qry[i].p1) pro[++cnt]=qry[i];
    sort(pro+1,pro+1+cnt,cmp);
    REP(i,1,cnt){
        if(pro[i].p1==0) t1.modify(1,pro[i].p2+pro[i].p3+pro[i].p4,1),t2.modify(1,pro[i].p3-1,1);
        if(pro[i].p1==-1) t1.modify(1,pro[i].p2+pro[i].p3+pro[i].p4,-1),t2.modify(1,pro[i].p3-1,-1);
        if(pro[i].p1>0) ans[pro[i].p1]+=t1.query(pro[i].p2+pro[i].p3)-t2.query(pro[i].p3);
    }
    solve(nl,mid); solve(mid+1,nr);
}
int main(){
#ifdef LOCAL
    freopen("ex_frontier4.in","r",stdin);
    freopen("frontier.out","w",stdout);
#endif
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int query_cnt=0; cin>>n>>Q;
    REP(i,1,Q){
        int op; cin>>op;
        if(op==1){
            cin>>inp[i][1]>>inp[i][2]>>inp[i][3]>>inp[i][4];
        }else{
            inp[i][0]=++query_cnt;
            cin>>inp[i][1]>>inp[i][2];
        }
    }
    int cnt=0;
    REP(i,1,Q) if(inp[i][0]) qry[++cnt]=(rec){inp[i][0],inp[i][1],inp[i][2]};
        else if(inp[i][1]==1) qry[++cnt]=(rec){0,inp[i][2],inp[i][3],inp[i][4]};
    solve(1,cnt);
    cnt=0;
    REP(i,1,Q) if(inp[i][0]) qry[++cnt]=(rec){inp[i][0],n+1-inp[i][2],inp[i][1]};
        else if(inp[i][1]==2) qry[++cnt]=(rec){0,n+1-inp[i][3],inp[i][2],inp[i][4]};
    solve(1,cnt);
    cnt=0;
    REP(i,1,Q) if(inp[i][0]) qry[++cnt]=(rec){inp[i][0],inp[i][2],n+1-inp[i][1]};
        else if(inp[i][1]==3) qry[++cnt]=(rec){0,inp[i][3],n+1-inp[i][2],inp[i][4]};
    solve(1,cnt);
    cnt=0;
    REP(i,1,Q) if(inp[i][0]) qry[++cnt]=(rec){inp[i][0],n+1-inp[i][1],n+1-inp[i][2]};
        else if(inp[i][1]==4) qry[++cnt]=(rec){0,n+1-inp[i][2],n+1-inp[i][3],inp[i][4]};
    solve(1,cnt);
    REP(i,1,query_cnt) cout<<ans[i]<<'\n';
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int n, q, t1[5005][5005], t2[10005][5005], t3[10005][5005];

template <typename T>
void update(T t, int xup, int x, int y, int v) {
	for (int i = x; i <= xup; i += i & -i)
		for (int j = y; j <= n; j += j & -j)
			t[i][j] += v;
}
template <typename T>
int query(T t, int x, int y) {
	int s = 0;
	for (int i = x; i > 0; i &= i - 1)
		for (int j = y; j > 0; j &= j - 1)
			s += t[i][j];
	return s;
}

template <typename T>
void rect(T t, int xup, int x1, int x2, int y1, int y2, int v) {
	update(t, xup, x1, y1, v);
	update(t, xup, x1, y2 + 1, -v);
	update(t, xup, x2 + 1, y1, -v);
	update(t, xup, x2 + 1, y2 + 1, v);
}

void dir1(int a, int b, int len, int v) {
	rect(t2, 2 * n, 1, a + b + len, b, b + len, v);
	rect(t1, n, 1, a - 1, b, b + len, -v);
}
void dir2(int a, int b, int len, int v) {
	rect(t3, 2 * n, 1, a + len - b + n, b - len, b, v);
	rect(t1, n, 1, a - 1, b - len, b, -v);
}

int main() {
	scanf("%d%d", &n, &q);
	while (q--) {
		int op;
		scanf("%d", &op);
		if (op == 1) {
			int dir, a, b, len;
			scanf("%d%d%d%d", &dir, &a, &b, &len);
			if (dir == 1) dir1(a, b, len, 1);
			else if (dir == 2) dir2(a, b, len, 1);
			else if (dir == 3) rect(t1, n, a - len, a, b, b + len, 1), dir2(a - len, b + len, len - 1, -1);
			else rect(t1, n, a - len, a, b - len, b, 1), dir1(a - len, b - len, len - 1, -1);
		} else {
			int x, y;
			scanf("%d%d", &x, &y);
			printf("%d\n", query(t1, x, y) + query(t2, x + y, y) + query(t3, x - y + n, y));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define N 5005
#define M 75
using namespace std;

int n,m,cnt,pos[N],lf[N],rg[N];
struct bit{
	int a[N],b[M];
	void ins(int x,int t){
		a[x]+=t; b[pos[x]]+=t;
	}
	int getsum(int x){
		if (x<0) return 0; if (x>n) x=n;
		int t=0,i;
		for (i=1; i<pos[x]; i++) t+=b[i];
		for (i=lf[pos[x]]; i<=x; i++) t+=a[i];
		return t;
	}
}blk[M][3],c[N];
int qry(int x,int y){
	int z=pos[x];
	return blk[z][0].getsum(y+x-lf[z])+blk[z][1].getsum(y-(x-lf[z]))+blk[z][2].getsum(y)+c[x].getsum(y);
}
void ins(int l,int r,int x,int y,int u,int v,bool w){
	int i;
	if (pos[l]==pos[r]){
		for (i=l; i<=r; i++){
			c[i].ins(x,y); c[i].ins((w)?u+i-l:u-(i-l),v);
		}
		return;
	}
	for (i=pos[l]+1; i<pos[r]; i++){
		blk[i][2].ins(x,y); blk[i][w].ins((w)?u+lf[i]-l:u-(lf[i]-l),v);
	}
	for (i=l; i<=rg[pos[l]]; i++){
		c[i].ins(x,y); c[i].ins((w)?u+i-l:u-(i-l),v);
	}
	for (i=lf[pos[r]]; i<=r; i++){
		c[i].ins(x,y); c[i].ins((w)?u+i-l:u-(i-l),v);
	}
}
int main(){
	scanf("%d%d",&n,&m); n++;
	int op,k,x,y,z,i,j;
	cnt=(int)sqrt(n);
	for (i=1; i<=cnt; i++){
		lf[i]=rg[i-1]+1; rg[i]=rg[i-1]+cnt;
	}
	rg[cnt]=n;
	for (i=1; i<=cnt; i++)
		for (j=lf[i]; j<=rg[i]; j++) pos[j]=i;
	while (m--){
		scanf("%d",&op);
		if (op==1){
			scanf("%d%d%d%d",&k,&x,&y,&z);
			if (k==1) ins(x,x+z,y,1,y+z+1,-1,0); else
			if (k==2) ins(x,x+z,y+1,-1,y-z,1,1); else
			if (k==3) ins(x-z,x,y,1,y+1,-1,1); else
			if (k==4) ins(x-z,x,y+1,-1,y,1,0);
		} else{
			scanf("%d%d",&x,&y);
			printf("%d\n",qry(x,y));
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10005;
const int M=N*350;
int n,q,ls[M],rs[M],sum[M],tot;
struct seg{
	int rt[N];
	void modify(int &x,int l,int r,int ql,int qr,int v){
		if(!x)x=++tot;
		if(l>=ql&&r<=qr){sum[x]+=v;return;}
		int mid=l+r>>1;
		if(ql<=mid)modify(ls[x],l,mid,ql,qr,v);
		if(qr>mid)modify(rs[x],mid+1,r,ql,qr,v);
	}
	int query(int x,int l,int r,int p){
		if(!x||l==r)return sum[x];
		int mid=l+r>>1,res=sum[x];
		if(p<=mid)res+=query(ls[x],l,mid,p);
		else res+=query(rs[x],mid+1,r,p);
		return res;
	}
	void modify(int x,int y1,int y2,int v){
		while(x)
			modify(rt[x],1,n,y1,y2,v),x^=x&-x;
	}
	int query(int x,int y){
		int res=0;
		while(x<N)
			res+=query(rt[x],1,n,y),x+=x&-x;
		return res;
	}
}A,B,C;
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1,op,x,y,z;i<=q;++i){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d%d",&op,&x,&y,&z);
			if(op==1)
				B.modify(x+y+z,x,x+z,1),A.modify(y-1,x,x+z,-1);
			if(op==2)
				C.modify(y-x-z-1+5002,x,x+z,-1),A.modify(y,x,x+z,1);
			if(op==3)
				C.modify(y-x+z+5002,x-z,x,1),A.modify(y-1,x-z,x,-1);
			if(op==4)
				B.modify(x+y-z-1,x-z,x,-1),A.modify(y,x-z,x,1);
		}else{
			scanf("%d%d",&x,&y);
			printf("%d\n",A.query(y,x)+B.query(y+x,x)+C.query(y-x+5002,x));
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10005;
const int M=N*200;
int n,q,ls[M],rs[M],sum[M],tot;
struct seg{
	int rt[N];
	void modify(int &x,int l,int r,int ql,int qr,int v){
		if(!x)x=++tot;
		if(l>=ql&&r<=qr){sum[x]+=v;return;}
		int mid=l+r>>1;
		if(ql<=mid)modify(ls[x],l,mid,ql,qr,v);
		if(qr>mid)modify(rs[x],mid+1,r,ql,qr,v);
	}
	int query(int x,int l,int r,int p){
		if(!x||l==r)return sum[x];
		int mid=l+r>>1,res=sum[x];
		if(p<=mid)res+=query(ls[x],l,mid,p);
		else res+=query(rs[x],mid+1,r,p);
		return res;
	}
	void modify(int x,int y1,int y2,int v){
		while(x)
			modify(rt[x],1,n,y1,y2,v),x^=x&-x;
	}
	int query(int x,int y){
		int res=0;
		while(x<N)
			res+=query(rt[x],1,n,y),x+=x&-x;
		return res;
	}
}A,B,C;
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1,op,x,y,z;i<=q;++i){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d%d",&op,&x,&y,&z);
			if(op==1)
				B.modify(x+y+z,x,x+z,1),A.modify(y-1,x,x+z,-1);
			if(op==2)
				C.modify(y-x-z-1+5002,x,x+z,-1),A.modify(y,x,x+z,1);
			if(op==3)
				C.modify(y-x+z+5002,x-z,x,1),A.modify(y-1,x-z,x,-1);
			if(op==4)
				B.modify(x+y-z-1,x-z,x,-1),A.modify(y,x-z,x,1);
		}else{
			scanf("%d%d",&x,&y);
			printf("%d\n",A.query(y,x)+B.query(y+x,x)+C.query(y-x+5002,x));
		}
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10005;
const int M=N*3500;
int n,q,ls[M],rs[M],sum[M],tot;
struct seg{
	int rt[N];
	void modify(int &x,int l,int r,int ql,int qr,int v){
		if(!x)x=++tot;
		if(l>=ql&&r<=qr){sum[x]+=v;return;}
		int mid=l+r>>1;
		if(ql<=mid)modify(ls[x],l,mid,ql,qr,v);
		if(qr>mid)modify(rs[x],mid+1,r,ql,qr,v);
	}
	int query(int x,int l,int r,int p){
		if(!x||l==r)return sum[x];
		int mid=l+r>>1,res=sum[x];
		if(p<=mid)res+=query(ls[x],l,mid,p);
		else res+=query(rs[x],mid+1,r,p);
		return res;
	}
	void modify(int x,int y1,int y2,int v){
		while(x)
			modify(rt[x],1,n,y1,y2,v),x^=x&-x;
	}
	int query(int x,int y){
		int res=0;
		while(x<N)
			res+=query(rt[x],1,n,y),x+=x&-x;
		return res;
	}
}A,B,C;
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1,op,x,y,z;i<=q;++i){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d%d",&op,&x,&y,&z);
			if(op==1)
				B.modify(x+y+z,x,x+z,1),A.modify(y-1,x,x+z,-1);
			if(op==2)
				C.modify(y-x-z-1+5002,x,x+z,-1),A.modify(y,x,x+z,1);
			if(op==3)
				C.modify(y-x+z+5002,x-z,x,1),A.modify(y-1,x-z,x,-1);
			if(op==4)
				B.modify(x+y-z-1,x-z,x,-1),A.modify(y,x-z,x,1);
		}else{
			scanf("%d%d",&x,&y);
			printf("%d\n",A.query(y,x)+B.query(y+x,x)+C.query(y-x+5002,x));
		}
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<ctime>
#include<set>
#include<queue>
#include<bitset>
#define sqr(x) ((x)*(x))
#define fz1(i,n) for ((i)=1;(i)<=(n);++(i))
#define fd1(i,n) for ((i)=(n);(i)>=1;--(i))
#define fz0g(i,n) for ((i)=0;(i)<=(n);++(i))
#define fd0g(i,n) for ((i)=(n);(i)>=0;--(i))
#define fz0k(i,n) for ((i)=0;(i)<(n);++(i))
#define fd0k(i,n) for ((i)=(long long)((n)-1);(i)>=0;--(i))
#define fz(i,x,y) for ((i)=(x);(i)<=(y);++(i))
#define fd(i,y,x) for ((i)=(y);(i)>=(x);--(i))
#define ff(c,itr) for (__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
#define rdst(st,len){static char ss[len];scanf(" %s",ss);(st)=ss;}
using namespace std;
int n,m,wid,cnt,i,j,ans[100005],op[100005],px[100005],py[100005],pl[100005],a[5005][5005],b[5005][10005];
int lowbit(int x)
{
	return x&(-x);
}
void insa(int x,int y,int z)
{
	int i,j;
	for(i=x;i<=wid;i+=lowbit(i)){
		for(j=y;j<=wid;j+=lowbit(j)){
			a[i][j]+=z;
		}
	}
}
void insb(int x,int y,int z)
{
	int i,j;
	for(i=x;i<=wid;i+=lowbit(i)){
		for(j=y;j<=wid+wid;j+=lowbit(j)){
			b[i][j]+=z;
		}
	}
}
int qrya(int x,int y)
{
	int i,j,s=0;
	for(i=x;i;i-=lowbit(i)){
		for(j=y;j;j-=lowbit(j)){
			s+=a[i][j];
		}
	}
	return s;
}
int qryb(int x,int y)
{
	int i,j,s=0;
	for(i=x;i;i-=lowbit(i)){
		for(j=y;j;j-=lowbit(j)){
			s+=b[i][j];
		}
	}
	return s;
}
int main()
{
	scanf("%d%d",&wid,&n);
	fz1(i,n){
		scanf("%d",&op[i]);
		if(op[i]==2){
			op[i]=0;
			scanf("%d%d",&px[i],&py[i]);
		}
		else{
			scanf("%d",&op[i]);
			scanf("%d%d%d",&px[i],&py[i],&pl[i]);
		}
	}
	fz1(j,4){
		fz1(i,n){
			if((j-1)&2) px[i]=wid-px[i]+1;
			if((j-1)&1) py[i]=wid-py[i]+1;
		}

		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		fz1(i,n){
			if(op[i]==j){
				insa(px[i],py[i],1);
				insa(px[i]+pl[i]+1,py[i],-1);
				insb(px[i],px[i]+py[i]+pl[i]+1,1);
				insb(px[i]+pl[i]+1,px[i]+py[i]+pl[i]+1,-1);
				/*a[px[i]][py[i]]++;
				a[px[i]+pl[i]+1][py[i]]--;
				b[px[i]][px[i]+py[i]+pl[i]+1]++;
				b[px[i]+pl[i]+1][px[i]+py[i]+pl[i]+1]--;*/
			}
			if(op[i]==0){
				ans[i]+=qrya(px[i],py[i])-qryb(px[i],px[i]+py[i]);
			}
		}

		fz1(i,n){
			if((j-1)&2) px[i]=wid-px[i]+1;
			if((j-1)&1) py[i]=wid-py[i]+1;
		}
	}

	fz1(i,n)if(op[i]==0){
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
constexpr int N = 5000, Q = 100000;
int n, q;
int fen[2 * N + 1][N + 1];
int dir[Q], x[Q], y[Q], len[Q], ans[Q];
void add(int x, int y, int v) {
    for (int i = x; i <= 2 * N; i += i & -i)
        for (int j = y; j <= N; j += j & -j)
            fen[i][j] += v;
}
int sum(int x, int y) {
    int result = 0;
    for (int i = x; i > 0; i -= i & -i)
        for (int j = y; j > 0; j -= j & -j)
            result += fen[i][j];
    return result;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    for (int i = 0; i < q; ++i) {
        int op;
        cin >> op;
        if (op == 1) {
            cin >> dir[i] >> x[i] >> y[i] >> len[i];
        } else {
            cin >> x[i] >> y[i];
        }
    }
    // (x, y) -> (x, y)
    for (int i = 0; i < q; ++i) {
        if (dir[i] == 1) {
            add(x[i], y[i], 1);
            add(x[i], y[i] + len[i] + 1, -1);
        } else if (dir[i] == 2) {
            add(x[i], y[i] - len[i], 1);
            add(x[i], y[i] + 1, -1);
        } else if (dir[i] == 3) {
            add(x[i] + 1, y[i], -1);
            add(x[i] + 1, y[i] + len[i] + 1, 1);
        } else if (dir[i] == 4) {
            add(x[i] + 1, y[i] - len[i], -1);
            add(x[i] + 1, y[i] + 1, 1);
        } else {
            ans[i] += sum(x[i], y[i]);
        }
    }
    memset(fen, 0, sizeof(fen));
    // (x, y) -> (x - y + n + 1, y)
    for (int i = 0; i < q; ++i) {
        if (dir[i] == 2) {
            add(x[i] - y[i] + len[i] + n + 2, y[i] - len[i], -1);
            add(x[i] - y[i] + len[i] + n + 2, y[i] + 1, 1);
        } else if (dir[i] == 3) {
            add(x[i] - len[i] - y[i] + n + 1, y[i], 1);
            add(x[i] - len[i] - y[i] + n + 1, y[i] + len[i] + 1, -1);
        } else if (dir[i] == 0) {
            ans[i] += sum(x[i] - y[i] + n + 1, y[i]);
        }
    }
    memset(fen, 0, sizeof(fen));
    // (x, y) -> (x + y, n - y + 1)
    for (int i = 0; i < q; ++i) {
        if (dir[i] == 1) {
            add(x[i] + y[i] + len[i] + 1, n - y[i] - len[i] + 1, -1);
            add(x[i] + y[i] + len[i] + 1, n - y[i] + 2, 1);
        } else if (dir[i] == 4) {
            add(x[i] - len[i] + y[i], n - y[i] + 1, 1);
            add(x[i] - len[i] + y[i], n - y[i] + len[i] + 2, -1);
        } else if (dir[i] == 0) {
            ans[i] += sum(x[i] + y[i], n - y[i] + 1);
        }
    }
    for (int i = 0; i < q; ++i)
        if (dir[i] == 0)
            cout << ans[i] << "\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=15010;
const int M=33000010;

int gi() {
	int x=0,o=1;char ch=getchar();
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') o=-1,ch=getchar();
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*o;
}

int n,m,tt,ls[M],rs[M],sum[M],q;

struct tree {

	int rt[N];

	void modify(int &x,int l,int r,int L,int R,int v) {
		if(!x) x=++tt;
		if(L<=l&&r<=R) { sum[x]+=v;return; }
		int mid=(l+r)>>1;
		if(L<=mid) modify(ls[x],l,mid,L,R,v);
		if(R>mid) modify(rs[x],mid+1,r,L,R,v);
	}

	int query(int x,int l,int r,int p) {
		if(!x) return 0;
		if(l==r) return sum[x];
		int mid=(l+r)>>1;
		return (p<=mid?query(ls[x],l,mid,p):query(rs[x],mid+1,r,p))+sum[x];
	}

	void modify(int x1,int x2,int y,int v) {
		//cerr<<x1<<' '<<x2<<' '<<y<<endl;
		y+=n+1,x1+=n+1,x2+=n+1;
		while(y) modify(rt[y],1,m,x1,x2,v),y-=y&-y;
	}

	int query(int x,int y) {
		//cerr<<x<<' '<<y<<endl;
		x+=n+1,y+=n+1;int ret=0;
		while(y<=m) ret+=query(rt[y],1,m,x),y+=y&-y;
		return ret;
	}

} A,B,C;

void add_tri(int x,int y,int len,int v) {
	int x1,x2;
	if(v==1) {
		x1=x,x2=x+len;
		B.modify(x1,x2,y+x2,1);
		A.modify(x1,x2,y-1,-1);
	}
	else if(v==2) {
		x1=x,x2=x+len;
		A.modify(x1,x2,y,1);
		C.modify(x1,x2,y-len-1-x1,-1);
	}
	else if(v==3) {
		x1=x-len,x2=x;
		C.modify(x1,x2,y-x1,1);
		A.modify(x1,x2,y-1,-1);
	}
	else {
		x1=x-len,x2=x;
		A.modify(x1,x2,y,1);
		B.modify(x1,x2,y-len-1+x2,-1);
	}
}

int query(int x,int y) {
	return A.query(x,y)+B.query(x,x+y)+C.query(x,y-x);
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=gi(),m=3*n-1,q=gi();
	while(q--) {
		int op=gi(),d,x,y,len;
		if(op==1) d=gi(),x=gi(),y=gi(),len=gi(),add_tri(x,y,len,d);
		else x=gi(),y=gi(),cout<<query(x,y)<<'\n';
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000, maxm = 2e4, maxq = 1e5;
int n, q, all, d[maxq + 10], x[maxq + 10], y[maxq + 10];
int len[maxq + 10], op[maxq + 10], ans[maxq + 10];

namespace bit {
	int a[maxn + 10][maxn + 10];

	void init() {
		memset(a, 0, sizeof a);
	}

	void modify(int x, int y, int v) {
		for (int i = x; i <= maxn; i += i & -i)
			for (int j = y; j <= maxn; j += j & -j)
				a[i][j] += v;
	}

	int query(int x, int y) {
		int ans = 0;
		for (int i = x; i; i -= i & -i)
			for (int j = y; j; j -= j & -j)
				ans += a[i][j];
		return ans;
	}
}

namespace bits {
	int c[maxm + 10];

	void init() {
		memset(c, 0, sizeof c);
	}

	void modify(int p, int v) {
		for (; p <= maxm; p += p & -p) c[p] += v;
	}

	int query(int p) {
		int ans = 0;
		for (; p; p -= p & -p) ans += c[p];
		return ans;
	}
};

void modrec(int lx, int rx, int ly, int ry) {
	bit::modify(lx, ly, 1);
	bit::modify(lx, ry + 1, -1);
	bit::modify(rx + 1, ly, -1);
	bit::modify(rx + 1, ry + 1, 1);
}

void modseg(int l, int r) {
	bits::modify(l, 1);
	bits::modify(r + 1, -1);
}

void rot() {
	for (int i = 1; i <= q; ++i) {
		swap(x[i], y[i]); x[i] = n + 1 - x[i];
	}
}

void solve(int s) {
	bit::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modrec(1, x[i] - 1, 1, y[i] - 1);
		else if (op[i] == 2) ans[i] += bit::query(x[i], y[i]);

	bit::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modrec(y[i], maxn, 1, x[i] + y[i] + len[i]);
		else if (op[i] == 2) ans[i] += bit::query(y[i], x[i] + y[i]);

	bit::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modrec(x[i], maxn, 1, x[i] + y[i] + len[i]);
		else if (op[i] == 2) ans[i] += bit::query(x[i], x[i] + y[i]);

	bits::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modseg(1, x[i] + y[i] + len[i]);
		else if (op[i] == 2) ans[i] -= bits::query(x[i] + y[i]);
}

int main() {
	scanf("%d%d", &n, &q);
	for (int i = 1; i <= q; ++i) {
		scanf("%d", &op[i]);
		if (op[i] == 1) scanf("%d%d%d%d", &d[i], &x[i], &y[i], &len[i]);
		else scanf("%d%d", &x[i], &y[i]);
	}
	solve(1);
	rot(); solve(2);
	rot(); solve(4);
	rot(); solve(3);
	for (int i = 1; i <= q; ++i)
		if (op[i] == 2) printf("%d\n", ans[i]);
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000, maxm = 2e4;
int n, q, all;

namespace bit {
	int a[maxn + 10][maxn + 10];

	void modify(int x, int y, int v) {
		for (int i = x; i <= n; i += i & -i)
			for (int j = y; j <= n; j += j & -j)
				a[i][j] += v;
	}

	int query(int x, int y) {
		int ans = 0;
		for (int i = x; i; i -= i & -i)
			for (int j = y; j; j -= j & -j)
				ans += a[i][j];
		return ans;
	}
}

struct bits {
	int c[maxm + 10];

	void modify(int p, int v) {
		for (; p <= maxm; p += p & -p) c[p] += v;
	}

	int query(int p) {
		int ans = 0;
		for (; p; p -= p & -p) ans += c[p];
		return ans;
	}
}a, b;

void modrec(int lx, int ly, int rx, int ry) {
	bit::modify(lx, ly, 1);
	bit::modify(lx, ry + 1, -1);
	bit::modify(rx + 1, ly, -1);
	bit::modify(rx + 1, ry + 1, 1);
}

void modline1(int l, int r) {
	a.modify(l, 1); a.modify(r + 1, -1);
}

void modline2(int l, int r) {
	b.modify(l, 1); b.modify(r + 1, -1);
}

int main() {
	scanf("%d%d", &n, &q);
	while (q--) {
		int op; scanf("%d", &op);
		if (op == 1) {
			int d, x, y, len;
			scanf("%d%d%d%d", &d, &x, &y, &len);
			if (d == 1) {
				modrec(x, y, n, n);
				modline1(1, x + len + y);
			} else if (d == 2) {
				modrec(x, 1, n, y);
				modline2(1, x + len - y + n);
			} else if (d == 3) {
				modrec(1, y, x, n);
				modline2(x - len - y + n, maxm);
			} else if (d == 4) {
				modrec(1, 1, x, y);
				modline1(x - len + y, maxm);
			}
			++all;
		} else if (op == 2) {
			int x, y; scanf("%d%d", &x, &y);
			printf("%d\n", bit::query(x, y) + a.query(x + y) + b.query(x - y + n) - all);
		}
	}
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000, maxm = 2e4, maxq = 1e5;
int n, q, all, d[maxq + 10], x[maxq + 10], y[maxq + 10];
int len[maxq + 10], op[maxq + 10], ans[maxq + 10];

namespace bit {
	int a[maxn + 10][maxn + 10];

	void init() {
		memset(a, 0, sizeof a);
	}

	void modify(int x, int y, int v) {
		for (int i = x; i <= maxn; i += i & -i)
			for (int j = y; j <= maxn; j += j & -j)
				a[i][j] += v;
	}

	int query(int x, int y) {
		int ans = 0;
		for (int i = x; i; i -= i & -i)
			for (int j = y; j; j -= j & -j)
				ans += a[i][j];
		return ans;
	}
}

namespace bits {
	int c[maxm + 10];

	void init() {
		memset(c, 0, sizeof c);
	}

	void modify(int p, int v) {
		for (; p <= maxm; p += p & -p) c[p] += v;
	}

	int query(int p) {
		int ans = 0;
		for (; p; p -= p & -p) ans += c[p];
		return ans;
	}
};

void modrec(int lx, int rx, int ly, int ry) {
	bit::modify(lx, ly, 1);
	bit::modify(lx, ry + 1, -1);
	bit::modify(rx + 1, ly, -1);
	bit::modify(rx + 1, ry + 1, 1);
}

void modseg(int l, int r) {
	bits::modify(l, 1);
	bits::modify(r + 1, -1);
}

void rot() {
	for (int i = 1; i <= q; ++i) {
		swap(x[i], y[i]); x[i] = n + 1 - x[i];
	}
}

void solve(int s) {
	bit::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modrec(1, x[i] - 1, 1, y[i] - 1);
	for (int i = 1; i <= q; ++i)
		if (op[i] == 2) ans[i] += bit::query(x[i], y[i]);

	bit::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modrec(y[i], maxn, 1, x[i] + y[i] + len[i]);
	for (int i = 1; i <= q; ++i)
		if (op[i] == 2) ans[i] += bit::query(y[i], x[i] + y[i]);

	bit::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modrec(x[i], maxn, 1, x[i] + y[i] + len[i]);
	for (int i = 1; i <= q; ++i)
		if (op[i] == 2) ans[i] += bit::query(x[i], x[i] + y[i]);

	bits::init();
	for (int i = 1; i <= q; ++i)
		if (op[i] == 1 && d[i] == s)
			modseg(1, x[i] + y[i] + len[i]);
	for (int i = 1; i <= q; ++i)
		if (op[i] == 2) ans[i] -= bits::query(x[i] + y[i]);
}

int main() {
	scanf("%d%d", &n, &q);
	for (int i = 1; i <= q; ++i) {
		scanf("%d", &op[i]);
		if (op[i] == 1) scanf("%d%d%d%d", &d[i], &x[i], &y[i], &len[i]);
		else scanf("%d%d", &x[i], &y[i]);
	}
	solve(1);
	rot(); solve(2);
	rot(); solve(4);
	rot(); solve(3);
	for (int i = 1; i <= q; ++i)
		if (op[i] == 2) printf("%d\n", ans[i]);
}


#include <bits/stdc++.h>

inline int read() {
    char c; int x; for (c = getchar(); !isdigit(c); c = getchar());
    for (x = 0; isdigit(c); c = getchar()) { x = x * 10 + c - '0'; } return x;
}

const int N = 5e3 + 5, M = 1e6 + 5;

int n, q, ans[M];

struct Action {
    int opt, dir, x, y, len;
} a[M];

struct FenwickTree {
    int n, m, f[N][N * 2];

    void reset(int _n, int _m) {
        n = _n; m = _m;
        for (int i = 1; i <= n; i++) {
            memset(f[i], 0, (m + 1) * 4);
        }
    }
    void modify(int u, int v, int x) {
        u = std::min(u, n);
        v = std::min(v, m);
        for (int i = u; i >= 1; i ^= i & -i) {
            for (int j = v; j >= 1; j ^= j & -j) {
                f[i][j] += x;
            }
        }
    }
    int query(int u, int v) {
        int res = 0;
        for (int i = u; i <= n; i += i & -i) {
            for (int j = v; j <= m; j += j & -j) {
                res += f[i][j];
            }
        }
        return res;
    }
} tr;

int main() {
    n = read(); q = read();
    for (int i = 0; i < q; i++) {
        a[i].opt = read();
        if (a[i].opt == 1) {
            a[i].dir = read(); a[i].dir--;
            a[i].x = read(); a[i].y = read(); a[i].len = read();
        } else {
            a[i].x = read(); a[i].y = read();
        }
    }
    for (int d = 0; d < 4; d++) {
        for (int i = 0; i < q; i++) {
            if (d == 1) { a[i].y = n + 1 - a[i].y; }
            if (d == 2) { a[i].x = n + 1 - a[i].x; a[i].y = n + 1 - a[i].y; }
            if (d == 3) { a[i].y = n + 1 - a[i].y; }
        }
        tr.reset(n, n * 2);
        for (int i = 0; i < q; i++) {
            if (a[i].opt == 1) {
                if (a[i].dir != d) { continue; }
                tr.modify(n, a[i].x + a[i].y + a[i].len, 1);
                tr.modify(a[i].x - 1, a[i].x + a[i].y + a[i].len, -1);
            } else {
                ans[i] += tr.query(a[i].x, a[i].x + a[i].y);
            }
        }
        tr.reset(n, n * 2);
        for (int i = 0; i < q; i++) {
            if (a[i].opt == 1) {
                if (a[i].dir != d) { continue; }
                tr.modify(a[i].y - 1, a[i].x + a[i].y + a[i].len, -1);
            } else {
                ans[i] += tr.query(a[i].y, a[i].x + a[i].y);
            }
        }
        tr.reset(n, n);
        for (int i = 0; i < q; i++) {
            if (a[i].opt == 1) {
                if (a[i].dir != d) { continue; }
                tr.modify(a[i].x - 1, a[i].y - 1, 1);
            } else {
                ans[i] += tr.query(a[i].x, a[i].y);
            }
        }
    }
    for (int i = 0; i < q; i++) {
        if (a[i].opt == 2) { printf("%d\n", ans[i]); }
    }
    return 0;
}


#include <bits/stdc++.h>
#define il inline
#define ri register int
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define mid ((l+r)>>1)
#define MAXN 10050
#define MAXM
#define mod
#define inf (1<<30)
#define eps (1e-6)
#define alpha 0.75
#define rep(i, x, y) for(ri i = x; i <= y; ++i)
#define repd(i, x, y) for(ri i = x; i >= y; --i)
#define file(s) freopen(s".in", "r", stdin), freopen(s".my", "w", stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, int> pli;
typedef pair <int, ll> pil;
typedef pair <ll, ll> pll;
template <typename T> il bool chkmin(T &x, T y) {return x > y ? x = y, 1 : 0;}
template <typename T> il bool chkmax(T &x, T y) {return x < y ? x = y, 1 : 0;}
template <typename T> il void read(T &x) {
	char ch = getchar(); int f = 1; x = 0;
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') x = x*10+ch-'0', ch = getchar();
	x *= f;
}
template <typename T, typename... Args> il void read(T &x, Args &...args) {
	char ch = getchar(); int f = 1; x = 0;
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') x = x*10+ch-'0', ch = getchar();
	x *= f;
	read(args...);
}
int n, m, q;
struct BIT {
	int a[MAXN][MAXN];
	void add(int x, int y, int w) {
		for(ri i = x; i <= m; i += i & -i)
			for(ri j = y; j <= m; j += j & -j)
				a[i][j] += w;
	}
	int query(int x, int y) {
		int ret = 0;
		for(ri i = x; i; i -= i & -i)
			for(ri j = y; j; j -= j & -j)
				ret += a[i][j];
		return ret;
	}
	void add(int x1, int x2, int y1, int y2, int w) {
//		cout<<"add: "<<x1<<' '<<x2<<' '<<y1<<' '<<y2<<' '<<w<<endl;
		add(x1, y1, w), add(x2+1, y1, -w), add(x1, y2+1, -w), add(x2+1, y2+1, w);
	}
} T[3];
int main() {
	read(n, q), m = n * 2;
	int op, dir, x, y, len;
	while(q--) {
		read(op);
		if(op == 1) {
			read(dir, x, y, len);
			if(dir == 1) T[0].add(x, n, y, y+len, 1), T[1].add(x+y+len+1, n, y, y+len, -1);
			if(dir == 2) T[0].add(x, n, y-len, y, 1), T[2].add(1, y-len+n-x-1, y-len, y, -1);
			if(dir == 3) T[0].add(1, x, y, y+len, 1), T[2].add(y+len+n-x+1, n, y, y+len, -1);
			if(dir == 4) T[0].add(1, x, y-len, y, 1), T[1].add(1, x+y-len-1, y-len, y, -1);
		}
		else read(x, y), printf("%d\n", T[0].query(x, y) + T[1].query(x+y, y) + T[2].query(y+n-x, y));
	}
	return 0;
}