The range search problem consists of a set of attributed records S to determine which records from S intersect with a given range.

For n points on a plane, report a set of points which are within in a given range. Note that you do not need to consider insert and delete operations for the set.

Constraints

* 0 ≤ n ≤ 500,000
* 0 ≤ q ≤ 20,000
* -1,000,000,000 ≤ x, y, sx, tx, sy, ty ≤ 1,000,000,000
* sx ≤ tx
* sy ≤ ty
* For each query, the number of points which are within the range is less than or equal to 100.

Input


n
x0 y0
x1 y1
:
xn-1 yn-1
q
sx0 tx0 sy0 ty0
sx1 tx1 sy1 ty1
:
sxq-1 txq-1 syq-1 tyq-1


The first integer n is the number of points. In the following n lines, the coordinate of the i-th point is given by two integers xi and yi.

The next integer q is the number of queries. In the following q lines, each query is given by four integers, sxi, txi, syi, tyi.

Output

For each query, report IDs of points such that sxi ≤ x ≤ txi and syi ≤ y ≤ tyi. The IDs should be reported in ascending order. Print an ID in a line, and print a blank line at the end of output for the each query.

Example

Input

6
2 1
2 2
4 2
6 2
3 3
5 4
2
2 4 0 4
4 10 2 5


Output

0
1
2
4

2
3
5
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

inline int next(void) {
	register int ret = 0;
	register int neg = false;
	register int bit = getchar();
	for (; bit < '0'; bit = getchar())
		if (bit == '-')neg ^= true;
	for (; bit >= '0'; bit = getchar())
		ret = ret * 10 + bit - '0';
	return neg ? -ret : ret;
}

int n, m;

int root;
int cmpk;

struct node {
	int id;
	int pos[2];
	int son[2];
	int min[2];
	int max[2];
	inline friend bool operator < 
		(const node &a, const node &b) {
			return a.pos[cmpk] < b.pos[cmpk];
	}
}tree[500005];

inline void update(int t) {
	for (int k = 0; k < 2; ++k) {
		tree[t].min[k] = tree[t].max[k] = tree[t].pos[k];
		for (int i = 0, s; i < 2; ++i)if (s = tree[t].son[i]) {
			if (tree[t].min[k] > tree[s].min[k])
				tree[t].min[k] = tree[s].min[k];
			if (tree[t].max[k] < tree[s].max[k])
				tree[t].max[k] = tree[s].max[k];
		}
	}
}

int build(int l, int r, int k) {
	int d = (l + r) / 2; cmpk = k;
	nth_element(tree + l, tree + d, tree + r + 1);
	tree[d].son[0] = l == d ? 0 : build(l, d - 1, k ^ 1);
	tree[d].son[1] = r == d ? 0 : build(d + 1, r, k ^ 1);
	return update(d), d;
}

inline void build(void) {
	for (int i = 1; i <= n; ++i) {
		tree[i].id = i - 1;
		tree[i].pos[0] = next();
		tree[i].pos[1] = next();
	}
	root = build(1, n, 0);
}

int st[2], ed[2], ans[500005], tot = 0;

inline bool judge(const node &t) {
	return t.pos[0] >= st[0]
		&& t.pos[0] <= ed[0]
		&& t.pos[1] >= st[1]
		&& t.pos[1] <= ed[1];
}

inline bool check(const node &t) {
	return t.min[0] <= ed[0]
		&& t.max[0] >= st[0]
		&& t.min[1] <= ed[1]
		&& t.max[1] >= st[1];
}

void query(int t) {
	if (judge(tree[t]))ans[tot++] = tree[t].id;
	if (tree[t].son[0] && check(tree[tree[t].son[0]]))query(tree[t].son[0]);
	if (tree[t].son[1] && check(tree[tree[t].son[1]]))query(tree[t].son[1]);
}

inline void query(void) {
	for (int i = 0; i < m; ++i, tot = 0) {
		st[0] = next();
		ed[0] = next();
		st[1] = next();
		ed[1] = next();
		tot = 0;
		query(root);
		sort(ans, ans + tot);
		for (int j = 0; j < tot; ++j)
			printf("%d\n", ans[j]);
		puts("");
	}
}

signed main(void) {
	n = next(); build();
	m = next(); query();
	//system("pause");
}