#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

typedef pair <int, int> PII;

const int INF = int(1e9);
const int MAX_N = int(1e5) + 100;
const int MAX_M = 30 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], aux[MAX_M], minimal[MAX_M], tot;
PII key[MAX_M];
int lower[MAX_M], upper[MAX_M];

inline void update(int k) {
	minimal[k] = min(key[k].second, min(minimal[lc[k]], minimal[rc[k]]));
	if (lc[k]) {
		lower[k] = lower[lc[k]];
	} else {
		lower[k] = key[k].first;
	}
	if (rc[k]) {
		upper[k] = upper[rc[k]];
	} else {
		upper[k] = key[k].first;
	}
}

inline void l_rotate(int &x) {
	int y = rc[x];
	rc[x] = lc[y];
	lc[y] = x;
	update(x);
	x = y;
}

inline void r_rotate(int &x) {
	int y = lc[x];
	lc[x] = rc[y];
	rc[y] = x;
	update(x);
	x = y;
}

void insert(int &k, const PII &x) {
	if (!k) {
		k = ++tot;
		key[k] = x;
		aux[k] = rand();
		minimal[k] = x.second;
		lower[k] = upper[k] = x.first;
		return;
	}
	if (x < key[k]) {
		insert(lc[k], x);
		if (aux[lc[k]] < aux[k]) {
			r_rotate(k);
		}
	} else {
		insert(rc[k], x);
		if (aux[rc[k]] < aux[k]) {
			l_rotate(k);
		}
	}
	update(k);
}

void erase(int &k, const PII &x) {
	if (key[k] == x) {
		if (lc[k] == 0 && rc[k] == 0) {
			k = 0;
			return;
		}
		if (aux[lc[k]] < aux[rc[k]]) {
			r_rotate(k);
			erase(rc[k], x);
		} else {
			l_rotate(k);
			erase(lc[k], x);
		}
	} else {
		erase(x < key[k] ? lc[k] : rc[k], x);
	}
	update(k);
}

int find_minimal(int k, int l, int r) {
	if (k == 0 || l > upper[k] || r < lower[k]) {
		return INF;
	}
	if (l <= lower[k] && upper[k] <= r) {
		return minimal[k];
	}
	int ret = INF;
	if (l <= key[k].first && key[k].first <= r) {
		ret = min(ret, key[k].second);
	}
	if (l <= upper[lc[k]]) {
		ret = min(ret, find_minimal(lc[k], l, r));
	}
	if (r >= lower[rc[k]]) {
		ret = min(ret, find_minimal(rc[k], l, r));
	}
	return ret;
}

int tree[MAX_N * 4];

void modify(int k, int s, int t, int p, int x, bool v) {
	if (v) {
		insert(tree[k], make_pair(qs[x][1], x));
	} else {
		erase(tree[k], make_pair(qs[x][1], x));
	}
	if (s == t) {
		return;
	}
	int mid = s + t >> 1;
	if (p <= mid) {
		modify(k << 1, s, mid, p, x, v);
	} else {
		modify(k << 1 | 1, mid + 1, t, p, x, v);
	}
}

int query(int k, int s, int t, int l, int r, int d, int u) {
	if (l > t || r < s) {
		return INF;
	}
	if (l <= s && t <= r) {
		return find_minimal(tree[k], d, u);
	}
	int mid = s + t >> 1, ret = INF;
	if (l <= mid) {
		ret = min(ret, query(k << 1, s, mid, l, r, d, u));
	}
	if (mid < r) {
		ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
	}
	return ret;
}

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
	return mat[i][4] < mat[j][4];
}

int main() {
	srand(time(0));
	minimal[0] = INF;
	aux[0] = INT_MAX;
	upper[0] = -INF, lower[0] = INF;

	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		order[i] = i;
		scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
		//all_x.push_back(mat[i][0]);
		//all_x.push_back(mat[i][2]);
	}
	sort(order, order + n, cmp);
	scanf("%d", &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d", qs[i], qs[i] + 1);
		all_x.push_back(qs[i][0]);
	}
	sort(all_x.begin(), all_x.end());
	all_x.resize(unique(all_x.begin(), all_x.end()) - all_x.begin());
	int l = all_x.size();
	for (int i = 0; i < m; i++) {
		int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
		modify(1, 1, l, p, i, true);
	}
	for (int t = 0; t < n; t++) {
		int i = order[t];
		int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
		int tr = upper_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin();
		int p = query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
		if (p < INF) {
			ans[p] = i + 1;
			int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
			modify(1, 1, l, q, p, false);
		}
	}
	for (int i = 0; i < m; i++) {
		printf("%d\n", ans[i]);
	}
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

const int INF = int(1e9);
const int MAX_N = int(1e5) + 100;
const int MAX_M = 30 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], key[MAX_M], aux[MAX_M], minimal[MAX_M], tot;
int lower[MAX_M], upper[MAX_M];

inline void update(int k) {
	minimal[k] = min(key[k], min(minimal[lc[k]], minimal[rc[k]]));
	if (lc[k]) {
		lower[k] = lower[lc[k]];
	} else {
		lower[k] = qs[key[k]][1];
	}
	if (rc[k]) {
		upper[k] = upper[rc[k]];
	} else {
		upper[k] = qs[key[k]][1];
	}
}

inline void l_rotate(int &x) {
	int y = rc[x];
	rc[x] = lc[y];
	lc[y] = x;
	update(x);
	x = y;
}

inline void r_rotate(int &x) {
	int y = lc[x];
	lc[x] = rc[y];
	rc[y] = x;
	update(x);
	x = y;
}

void insert(int &k, int x) {
	if (!k) {
		k = ++tot;
		key[k] = x;
		aux[k] = rand();
		minimal[k] = x;
		lower[k] = upper[k] = qs[x][1];
		return;
	}
	if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
		insert(lc[k], x);
		if (aux[lc[k]] < aux[k]) {
			r_rotate(k);
		}
	} else {
		insert(rc[k], x);
		if (aux[rc[k]] < aux[k]) {
			l_rotate(k);
		}
	}
	update(k);
}

void erase(int &k, int x) {
	if (key[k] == x) {
		if (lc[k] == 0 && rc[k] == 0) {
			k = 0;
			return;
		}
		if (aux[lc[k]] < aux[rc[k]]) {
			int tk = k;
			r_rotate(k);
			erase(rc[k], x);
		} else {
			l_rotate(k);
			erase(lc[k], x);
		}
	} else {
		if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
			erase(lc[k], x);
		} else {
			erase(rc[k], x);
		}
	}
	update(k);
}

int find_minimal(int k, int l, int r) {
	if (k == 0 || l > upper[k] || r < lower[k]) {
		return INF;
	}
	if (l <= lower[k] && upper[k] <= r) {
		return minimal[k];
	}
	int ret = INF;
	if (l <= qs[key[k]][1] && qs[key[k]][1] <= r) {
		ret = min(ret, key[k]);
	}
	if (l <= upper[lc[k]]) {
		ret = min(ret, find_minimal(lc[k], l, r));
	}
	if (r >= lower[rc[k]]) {
		ret = min(ret, find_minimal(rc[k], l, r));
	}
	return ret;
}

int tree[MAX_N * 4];

void modify(int k, int s, int t, int p, int x, bool v) {
	if (v) {
		insert(tree[k], x);
	} else {
		erase(tree[k], x);
	}
	if (s == t) {
		return;
	}
	int mid = s + t >> 1;
	if (p <= mid) {
		modify(k << 1, s, mid, p, x, v);
	} else {
		modify(k << 1 | 1, mid + 1, t, p, x, v);
	}
}

int query(int k, int s, int t, int l, int r, int d, int u) {
	if (l <= s && t <= r) {
		return find_minimal(tree[k], d, u);
	}
	int mid = s + t >> 1, ret = INF;
	if (l <= mid) {
		ret = min(ret, query(k << 1, s, mid, l, r, d, u));
	}
	if (mid < r) {
		ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
	}
	return ret;
}

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
	return mat[i][4] < mat[j][4];
}

int main() {
	srand(time(0));
	minimal[0] = INF;
	aux[0] = INT_MAX;
	upper[0] = -INF, lower[0] = INF;

	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		order[i] = i;
		scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
		//all_x.push_back(mat[i][0]);
		//all_x.push_back(mat[i][2]);
	}
	sort(order, order + n, cmp);
	scanf("%d", &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d", qs[i], qs[i] + 1);
		all_x.push_back(qs[i][0]);
	}
	sort(all_x.begin(), all_x.end());
	all_x.resize(unique(all_x.begin(), all_x.end()) - all_x.begin());
	int l = all_x.size();
	for (int i = 0; i < m; i++) {
		int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
		modify(1, 1, l, p, i, true);
	}
	for (int t = 0; t < n; t++) {
		int i = order[t];
		int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
		int tr = upper_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin();
		int p = query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
		if (p < INF) {
			ans[p] = i + 1;
			int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
			modify(1, 1, l, q, p, false);
		}
	}
	for (int i = 0; i < m; i++) {
		printf("%d\n", ans[i]);
	}
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

typedef pair <int, int> PII;

const int INF = int(1e9);
const int MAX_N = 4 * int(1e5) + 101;
const int MAX_M = 22 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], key[MAX_M], aux[MAX_M], minimal[MAX_M] = {INF}, tot;
int lower[MAX_M] = {INF}, upper[MAX_M] = {-INF};

inline void update(int k) {
    minimal[k] = min(key[k], min(minimal[lc[k]], minimal[rc[k]]));
    lower[k] = min(qs[key[k]][1], min(lower[lc[k]], lower[rc[k]]));
    upper[k] = max(qs[key[k]][1], max(upper[lc[k]], upper[rc[k]]));
}

void l_rotate(int &x) {
    int y = rc[x];
    rc[x] = lc[y];
    lc[y] = x;
    update(x);
    x = y;
}

void r_rotate(int &x) {
    int y = lc[x];
    lc[x] = rc[y];
    rc[y] = x;
    update(x);
    x = y;
}

void insert(int &k, int x) {
    if (!k) {
        k = ++tot;
        key[k] = x;
        aux[k] = rand();
        minimal[k] = x;
        lower[k] = upper[k] = qs[x][1];
        return;
    }
    if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
        insert(lc[k], x);
        if (aux[lc[k]] < aux[k]) {
            r_rotate(k);
        }
    } else {
        insert(rc[k], x);
        if (aux[rc[k]] < aux[k]) {
            l_rotate(k);
        }
    }
    update(k);
}

int erase(int &k, int x) {
    if (key[k] == x || x == INF && rc[k] == 0) {
        if (!lc[k] || !rc[k]) {
            int ret = key[k];
            k = lc[k] + rc[k];
            return ret;
        }
        key[k] = erase(lc[k], INF);
        update(k);
        return key[k];
    }
    int ret = erase(qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k] ? lc[k] : rc[k], x);
    update(k);
    return ret;
}

int find_minimal(int k, int l, int r) {
    if (k == 0) {
        return INF;
    }
    if (l <= lower[k] && upper[k] <= r) {
        return minimal[k];
    }
    int ret = INF;
    if (l <= qs[key[k]][1] && qs[key[k]][1] <= r) {
        ret = min(ret, key[k]);
    }
    if (l <= upper[lc[k]]) {
        ret = min(ret, find_minimal(lc[k], l, r));
    }
    if (r >= lower[rc[k]]) {
        ret = min(ret, find_minimal(rc[k], l, r));
    }
    return ret;
}

struct IntervalTree {
    int tree[MAX_N * 4];
    void make_use(int n) {
        fill(tree + 1, tree + 1 + (n * 4), 0);
    }
    void modify(int k, int s, int t, int p, int x, bool v) {
        if (v) {
            insert(tree[k], x);
        } else {
            erase(tree[k], x);
        }
        if (s == t) {
            return;
        }
        int mid = s + t >> 1;
        if (p <= mid) {
            modify(k << 1, s, mid, p, x, v);
        } else {
            modify(k << 1 | 1, mid + 1, t, p, x, v);
        }
    }
    int query(int k, int s, int t, int l, int r, int d, int u) {
        if (l <= s && t <= r) {
            return find_minimal(tree[k], d, u);
        }
        int mid = s + t >> 1, ret = INF;
        if (l <= mid) {
            ret = min(ret, query(k << 1, s, mid, l, r, d, u));
        }
        if (mid < r) {
            ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
        }
        return ret;
    }
}T;

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
    return mat[i][4] < mat[j][4];
}

int main() {
    srand(time(0));
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        order[i] = i;
        scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
        all_x.push_back(mat[i][0]);
        all_x.push_back(mat[i][2]);
    }
    sort(order, order + n, cmp);
    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", qs[i], qs[i] + 1);
        all_x.push_back(qs[i][0]);
    }
    sort(all_x.begin(), all_x.end());
    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());
    int l = all_x.size();
    T.make_use(l);
    for (int i = 0; i < m; i++) {
        int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
        T.modify(1, 1, l, p, i, true);
    }
    for (int t = 0; t < n; t++) {
        int i = order[t];
        int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
        int tr = lower_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin() + 1;
        int p = T.query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
        if (p < INF) {
            ans[p] = i + 1;
            int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
            T.modify(1, 1, l, q, p, false);
        }
    }
    for (int i = 0; i < m; i++) {
        printf("%d\n", ans[i]);
    }
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

const int INF = int(1e9);
const int MAX_N = 3 * int(1e5) + 100;
const int MAX_M = 40 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], key[MAX_M], aux[MAX_M], minimal[MAX_M], tot;
int lower[MAX_M], upper[MAX_M];

inline void update(int k) {
	minimal[k] = min(key[k], min(minimal[lc[k]], minimal[rc[k]]));
	if (lc[k]) {
		lower[k] = lower[lc[k]];
	} else {
		lower[k] = qs[key[k]][1];
	}
	if (rc[k]) {
		upper[k] = upper[rc[k]];
	} else {
		upper[k] = qs[key[k]][1];
	}
}

inline void l_rotate(int &x) {
	int y = rc[x];
	rc[x] = lc[y];
	lc[y] = x;
	update(x);
	x = y;
}

inline void r_rotate(int &x) {
	int y = lc[x];
	lc[x] = rc[y];
	rc[y] = x;
	update(x);
	x = y;
}

void insert(int &k, int x) {
	if (!k) {
		k = ++tot;
		key[k] = x;
		aux[k] = rand();
		minimal[k] = x;
		lower[k] = upper[k] = qs[x][1];
		return;
	}
	if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
		insert(lc[k], x);
		if (aux[lc[k]] < aux[k]) {
			r_rotate(k);
		}
	} else {
		insert(rc[k], x);
		if (aux[rc[k]] < aux[k]) {
			l_rotate(k);
		}
	}
	update(k);
}

void erase(int &k, int x) {
	if (key[k] == x) {
		if (lc[k] == 0 && rc[k] == 0) {
			k = 0;
			return;
		}
		if (aux[lc[k]] < aux[rc[k]]) {
			int tk = k;
			r_rotate(k);
			erase(rc[k], x);
		} else {
			l_rotate(k);
			erase(lc[k], x);
		}
	} else {
		if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
			erase(lc[k], x);
		} else {
			erase(rc[k], x);
		}
	}
	update(k);
}

int find_minimal(int k, int l, int r) {
	if (k == 0 || l > upper[k] || r < lower[k]) {
		return INF;
	}
	if (l <= lower[k] && upper[k] <= r) {
		return minimal[k];
	}
	int ret = INF;
	if (l <= qs[key[k]][1] && qs[key[k]][1] <= r) {
		ret = min(ret, key[k]);
	}
	if (l <= upper[lc[k]]) {
		ret = min(ret, find_minimal(lc[k], l, r));
	}
	if (r >= lower[rc[k]]) {
		ret = min(ret, find_minimal(rc[k], l, r));
	}
	return ret;
}

int tree[MAX_N * 4];

void modify(int k, int s, int t, int p, int x, bool v) {
	if (v) {
		insert(tree[k], x);
	} else {
		erase(tree[k], x);
	}
	if (s == t) {
		return;
	}
	int mid = s + t >> 1;
	if (p <= mid) {
		modify(k << 1, s, mid, p, x, v);
	} else {
		modify(k << 1 | 1, mid + 1, t, p, x, v);
	}
}

int query(int k, int s, int t, int l, int r, int d, int u) {
	if (l <= s && t <= r) {
		return find_minimal(tree[k], d, u);
	}
	int mid = s + t >> 1, ret = INF;
	if (l <= mid) {
		ret = min(ret, query(k << 1, s, mid, l, r, d, u));
	}
	if (mid < r) {
		ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
	}
	return ret;
}

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
	return mat[i][4] < mat[j][4];
}

int main() {
	srand(time(0));
	minimal[0] = INF;
	aux[0] = INT_MAX;
	upper[0] = -INF, lower[0] = INF;

	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		order[i] = i;
		scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
		//all_x.push_back(mat[i][0]);
		//all_x.push_back(mat[i][2]);
	}
	sort(order, order + n, cmp);
	scanf("%d", &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d", qs[i], qs[i] + 1);
		all_x.push_back(qs[i][0]);
	}
	sort(all_x.begin(), all_x.end());
	all_x.resize(unique(all_x.begin(), all_x.end()) - all_x.begin());
	int l = all_x.size();
	for (int i = 0; i < m; i++) {
		int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
		modify(1, 1, l, p, i, true);
	}
	for (int t = 0; t < n; t++) {
		int i = order[t];
		int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
		int tr = upper_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin();
		int p = query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
		if (p < INF) {
			ans[p] = i + 1;
			int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
			modify(1, 1, l, q, p, false);
		}
	}
	for (int i = 0; i < m; i++) {
		printf("%d\n", ans[i]);
	}
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

typedef pair <int, int> PII;

const int INF = int(1e9);
const int MAX_N = int(1e5) + 100;
const int MAX_M = 30 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], aux[MAX_M], minimal[MAX_M], tot;
PII key[MAX_M];
int lower[MAX_M], upper[MAX_M];

inline void update(int k) {
	minimal[k] = min(key[k].second, min(minimal[lc[k]], minimal[rc[k]]));
	if (lc[k]) {
		lower[k] = lower[lc[k]];
	} else {
		lower[k] = key[k].second;
	}
	if (rc[k]) {
		upper[k] = upper[rc[k]];
	} else {
		upper[k] = key[k].second;
	}
}

inline void l_rotate(int &x) {
	int y = rc[x];
	rc[x] = lc[y];
	lc[y] = x;
	update(x);
	x = y;
}

inline void r_rotate(int &x) {
	int y = lc[x];
	lc[x] = rc[y];
	rc[y] = x;
	update(x);
	x = y;
}

void insert(int &k, const PII &x) {
	if (!k) {
		k = ++tot;
		key[k] = x;
		aux[k] = rand();
		minimal[k] = x.second;
		lower[k] = upper[k] = x.first;
		return;
	}
	if (x < key[k]) {
		insert(lc[k], x);
		if (aux[lc[k]] < aux[k]) {
			r_rotate(k);
		}
	} else {
		insert(rc[k], x);
		if (aux[rc[k]] < aux[k]) {
			l_rotate(k);
		}
	}
	update(k);
}

void erase(int &k, const PII &x) {
	if (key[k] == x) {
		if (lc[k] == 0 && rc[k] == 0) {
			k = 0;
			return;
		}
		if (aux[lc[k]] < aux[rc[k]]) {
			r_rotate(k);
			erase(rc[k], x);
		} else {
			l_rotate(k);
			erase(lc[k], x);
		}
	} else {
		erase(x < key[k] ? lc[k] : rc[k], x);
	}
	update(k);
}

int find_minimal(int k, int l, int r) {
	if (k == 0 || l > upper[k] || r < lower[k]) {
		return INF;
	}
	if (l <= lower[k] && upper[k] <= r) {
		return minimal[k];
	}
	int ret = INF;
	if (l <= key[k].first && key[k].first <= r) {
		ret = min(ret, key[k].second);
	}
	if (l <= upper[lc[k]]) {
		ret = min(ret, find_minimal(lc[k], l, r));
	}
	if (r >= lower[rc[k]]) {
		ret = min(ret, find_minimal(rc[k], l, r));
	}
	return ret;
}

int tree[MAX_N * 4];

void modify(int k, int s, int t, int p, int x, bool v) {
	if (v) {
		insert(tree[k], make_pair(qs[x][1], x));
	} else {
		erase(tree[k], make_pair(qs[x][1], x));
	}
	if (s == t) {
		return;
	}
	int mid = s + t >> 1;
	if (p <= mid) {
		modify(k << 1, s, mid, p, x, v);
	} else {
		modify(k << 1 | 1, mid + 1, t, p, x, v);
	}
}

int query(int k, int s, int t, int l, int r, int d, int u) {
	if (l > t || r < s) {
		return INF;
	}
	if (l <= s && t <= r) {
		return find_minimal(tree[k], d, u);
	}
	int mid = s + t >> 1, ret = INF;
	if (l <= mid) {
		ret = min(ret, query(k << 1, s, mid, l, r, d, u));
	}
	if (mid < r) {
		ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
	}
	return ret;
}

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
	return mat[i][4] < mat[j][4];
}

int main() {
	srand(time(0));
	minimal[0] = INF;
	aux[0] = INT_MAX;
	upper[0] = -INF, lower[0] = INF;

	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		order[i] = i;
		scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
		//all_x.push_back(mat[i][0]);
		//all_x.push_back(mat[i][2]);
	}
	sort(order, order + n, cmp);
	scanf("%d", &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d", qs[i], qs[i] + 1);
		all_x.push_back(qs[i][0]);
	}
	sort(all_x.begin(), all_x.end());
	all_x.resize(unique(all_x.begin(), all_x.end()) - all_x.begin());
	int l = all_x.size();
	for (int i = 0; i < m; i++) {
		int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
		modify(1, 1, l, p, i, true);
	}
	for (int t = 0; t < n; t++) {
		int i = order[t];
		int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
		int tr = upper_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin();
		int p = query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
		if (p < INF) {
			ans[p] = i + 1;
			int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
			modify(1, 1, l, q, p, false);
		}
	}
	for (int i = 0; i < m; i++) {
		printf("%d\n", ans[i]);
	}
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

typedef pair <int, int> PII;

const int INF = int(1e9);
const int MAX_N = 4 * int(1e5) + 100;
const int MAX_M = 22 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], key[MAX_M], aux[MAX_M], minimal[MAX_M] = {INF}, tot;
int lower[MAX_M] = {INF}, upper[MAX_M] = {-INF};

inline void update(int k) {
    minimal[k] = min(key[k], min(minimal[lc[k]], minimal[rc[k]]));
    lower[k] = min(qs[key[k]][1], min(lower[lc[k]], lower[rc[k]]));
    upper[k] = max(qs[key[k]][1], max(upper[lc[k]], upper[rc[k]]));
}

void l_rotate(int &x) {
    int y = rc[x];
    rc[x] = lc[y];
    lc[y] = x;
    update(x);
    x = y;
}

void r_rotate(int &x) {
    int y = lc[x];
    lc[x] = rc[y];
    rc[y] = x;
    update(x);
    x = y;
}

void insert(int &k, int x) {
    if (!k) {
        k = ++tot;
        key[k] = x;
        aux[k] = rand();
        minimal[k] = x;
        lower[k] = upper[k] = qs[x][1];
        return;
    }
    if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
        insert(lc[k], x);
        if (aux[lc[k]] < aux[k]) {
            r_rotate(k);
        }
    } else {
        insert(rc[k], x);
        if (aux[rc[k]] < aux[k]) {
            l_rotate(k);
        }
    }
    update(k);
}

int erase(int &k, int x) {
    if (key[k] == x || x == INF && rc[k] == 0) {
        if (!lc[k] || !rc[k]) {
            int ret = key[k];
            k = lc[k] + rc[k];
            return ret;
        }
        key[k] = erase(lc[k], INF);
        update(k);
        return key[k];
    }
    int ret = erase(qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k] ? lc[k] : rc[k], x);
    update(k);
    return ret;
}

int find_minimal(int k, int l, int r) {
    if (k == 0) {
        return INF;
    }
    if (l <= lower[k] && upper[k] <= r) {
        return minimal[k];
    }
    int ret = INF;
    if (l <= qs[key[k]][1] && qs[key[k]][1] <= r) {
        ret = min(ret, key[k]);
    }
    if (l <= upper[lc[k]]) {
        ret = min(ret, find_minimal(lc[k], l, r));
    }
    if (r >= lower[rc[k]]) {
        ret = min(ret, find_minimal(rc[k], l, r));
    }
    return ret;
}

struct IntervalTree {
    int tree[MAX_N * 4];
    void make_use(int n) {
        fill(tree + 1, tree + 1 + (n * 4), 0);
    }
    void modify(int k, int s, int t, int p, int x, bool v) {
        if (v) {
            insert(tree[k], x);
        } else {
            erase(tree[k], x);
        }
        if (s == t) {
            return;
        }
        int mid = s + t >> 1;
        if (p <= mid) {
            modify(k << 1, s, mid, p, x, v);
        } else {
            modify(k << 1 | 1, mid + 1, t, p, x, v);
        }
    }
    int query(int k, int s, int t, int l, int r, int d, int u) {
        if (l <= s && t <= r) {
            return find_minimal(tree[k], d, u);
        }
        int mid = s + t >> 1, ret = INF;
        if (l <= mid) {
            ret = min(ret, query(k << 1, s, mid, l, r, d, u));
        }
        if (mid < r) {
            ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
        }
        return ret;
    }
}T;

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
    return mat[i][4] < mat[j][4];
}

int main() {
    srand(time(0));
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        order[i] = i;
        scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
        all_x.push_back(mat[i][0]);
        all_x.push_back(mat[i][2]);
    }
    sort(order, order + n, cmp);
    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", qs[i], qs[i] + 1);
        all_x.push_back(qs[i][0]);
    }
    sort(all_x.begin(), all_x.end());
    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());
    int l = all_x.size();
    T.make_use(l);
    for (int i = 0; i < m; i++) {
        int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
        T.modify(1, 1, l, p, i, true);
    }
    for (int t = 0; t < n; t++) {
        int i = order[t];
        int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
        int tr = lower_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin() + 1;
        int p = T.query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
        if (p < INF) {
            ans[p] = i + 1;
            int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
            T.modify(1, 1, l, q, p, false);
        }
    }
    for (int i = 0; i < m; i++) {
        printf("%d\n", ans[i]);
    }
}


#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <sstream>
#include <bitset>
#include <numeric>
#include <climits>
#include <string>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <cmath>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

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

typedef long long int64;

typedef pair <int, int> PII;

const int INF = int(1e9);
const int MAX_N = 4 * int(1e5) + 101;
const int MAX_M = 20 * int(1e5);

int qs[MAX_N][2];
int lc[MAX_M], rc[MAX_M], key[MAX_M], aux[MAX_M], minimal[MAX_M] = {INF}, tot;
int lower[MAX_M] = {INF}, upper[MAX_M] = {-INF};

inline void update(int k) {
    minimal[k] = min(key[k], min(minimal[lc[k]], minimal[rc[k]]));
    lower[k] = min(qs[key[k]][1], min(lower[lc[k]], lower[rc[k]]));
    upper[k] = max(qs[key[k]][1], max(upper[lc[k]], upper[rc[k]]));
}

void l_rotate(int &x) {
    int y = rc[x];
    rc[x] = lc[y];
    lc[y] = x;
    update(x);
    x = y;
}

void r_rotate(int &x) {
    int y = lc[x];
    lc[x] = rc[y];
    rc[y] = x;
    update(x);
    x = y;
}

void insert(int &k, int x) {
    if (!k) {
        k = ++tot;
        key[k] = x;
        aux[k] = rand();
        minimal[k] = x;
        lower[k] = upper[k] = qs[x][1];
        return;
    }
    if (qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k]) {
        insert(lc[k], x);
        if (aux[lc[k]] < aux[k]) {
            r_rotate(k);
        }
    } else {
        insert(rc[k], x);
        if (aux[rc[k]] < aux[k]) {
            l_rotate(k);
        }
    }
    update(k);
}

int erase(int &k, int x) {
    if (key[k] == x || x == INF && rc[k] == 0) {
        if (!lc[k] || !rc[k]) {
            int ret = key[k];
            k = lc[k] + rc[k];
            return ret;
        }
        key[k] = erase(lc[k], INF);
        update(k);
        return key[k];
    }
    int ret = erase(qs[x][1] < qs[key[k]][1] || qs[x][1] == qs[key[k]][1] && x < key[k] ? lc[k] : rc[k], x);
    update(k);
    return ret;
}

int find_minimal(int k, int l, int r) {
    if (k == 0) {
        return INF;
    }
    if (l <= lower[k] && upper[k] <= r) {
        return minimal[k];
    }
    int ret = INF;
    if (l <= qs[key[k]][1] && qs[key[k]][1] <= r) {
        ret = min(ret, key[k]);
    }
    if (l <= upper[lc[k]]) {
        ret = min(ret, find_minimal(lc[k], l, r));
    }
    if (r >= lower[rc[k]]) {
        ret = min(ret, find_minimal(rc[k], l, r));
    }
    return ret;
}

struct IntervalTree {
    int tree[MAX_N * 4];
    void make_use(int n) {
        fill(tree + 1, tree + 1 + (n * 4), 0);
    }
    void modify(int k, int s, int t, int p, int x, bool v) {
        if (v) {
            insert(tree[k], x);
        } else {
            erase(tree[k], x);
        }
        if (s == t) {
            return;
        }
        int mid = s + t >> 1;
        if (p <= mid) {
            modify(k << 1, s, mid, p, x, v);
        } else {
            modify(k << 1 | 1, mid + 1, t, p, x, v);
        }
    }
    int query(int k, int s, int t, int l, int r, int d, int u) {
        if (l <= s && t <= r) {
            return find_minimal(tree[k], d, u);
        }
        int mid = s + t >> 1, ret = INF;
        if (l <= mid) {
            ret = min(ret, query(k << 1, s, mid, l, r, d, u));
        }
        if (mid < r) {
            ret = min(ret, query(k << 1 | 1, mid + 1, t, l, r, d, u));
        }
        return ret;
    }
}T;

int n, m;
int mat[MAX_N][5], ans[MAX_N];
int order[MAX_N];
vector <int> all_x;

bool cmp(int i, int j) {
    return mat[i][4] < mat[j][4];
}

int main() {
    srand(time(0));
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        order[i] = i;
        scanf("%d%d%d%d%d", mat[i], mat[i] + 2, mat[i] + 1, mat[i] + 3, mat[i] + 4);
        all_x.push_back(mat[i][0]);
        all_x.push_back(mat[i][2]);
    }
    sort(order, order + n, cmp);
    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", qs[i], qs[i] + 1);
        all_x.push_back(qs[i][0]);
    }
    sort(all_x.begin(), all_x.end());
    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());
    int l = all_x.size();
    T.make_use(l);
    for (int i = 0; i < m; i++) {
        int p = lower_bound(all_x.begin(), all_x.end(), qs[i][0]) - all_x.begin() + 1;
        T.modify(1, 1, l, p, i, true);
    }
    for (int t = 0; t < n; t++) {
        int i = order[t];
        int tl = lower_bound(all_x.begin(), all_x.end(), mat[i][0]) - all_x.begin() + 1;
        int tr = lower_bound(all_x.begin(), all_x.end(), mat[i][2]) - all_x.begin() + 1;
        int p = T.query(1, 1, l, tl, tr, mat[i][1], mat[i][3]);
        if (p < INF) {
            ans[p] = i + 1;
            int q = lower_bound(all_x.begin(), all_x.end(), qs[p][0]) - all_x.begin() + 1;
            T.modify(1, 1, l, q, p, false);
        }
    }
    for (int i = 0; i < m; i++) {
        printf("%d\n", ans[i]);
    }
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>

using namespace std;

/*
 * */
#define MAXN 100100
#define INF 0x3f3f3f3f
struct POINT
{
	int x, y, id;
};
struct TARGET
{
	int x1, x2, y1, y2, z, id;
};
struct NODE
{
	int l, r, x, y, x1, x2, y1, y2, id, fa, h;
};
int N, M;
POINT P[MAXN];
TARGET T[MAXN];
NODE tree[MAXN];     //kd-tree
int root, tot, R[MAXN], ans;
bool used[MAXN];
bool cmp(const TARGET &t1, const TARGET &t2)
{
	return t1.z < t2.z;
}
bool xcmp(const POINT &t1, const POINT &t2)
{
	return t1.x < t2.x;
}
bool ycmp(const POINT &t1, const POINT &t2)
{
	return t1.y < t2.y;
}

void update(int rt)
{
	int ll = tree[rt].l, rr = tree[rt].r, mi = tree[tree[rt].h].id;
	if(used[mi])
		mi = INF, tree[rt].h = -1;
	if(!used[tree[rt].id] && tree[rt].id < mi)
		mi = tree[rt].id, tree[rt].h = rt;
	if(ll != -1 && tree[ll].h != -1 && tree[tree[ll].h].id < mi)
		mi = tree[tree[ll].h].id, tree[rt].h = tree[ll].h;
	if(rr != -1 && tree[rr].h != -1 && tree[tree[rr].h].id < mi)
		mi = tree[tree[rr].h].id, tree[rt].h = tree[rr].h;
}

void build(int &rt, int ll, int rr, int x1, int y1, int x2, int y2, int fa, int flag)
{
	if(ll > rr) return;
	int mid = (ll + rr) / 2, x, y;
	rt = tot++;
	tree[rt].fa = fa, tree[rt].l = tree[rt].r = -1, tree[rt].h = rt;
	tree[rt].x1 = x1, tree[rt].x2 = x2, tree[rt].y1 = y1, tree[rt].y2 = y2;
	if(flag)
	{
		nth_element(P + ll, P + mid, P + rr + 1, xcmp);
		tree[rt].id = P[mid].id, x = tree[rt].x = P[mid].x, y = tree[rt].y = P[mid].y;
		build(tree[rt].l, ll, mid - 1, x1, y1, x, y2, rt, 1 - flag);
		build(tree[rt].r, mid + 1, rr, x, y1, x2, y2, rt, 1 - flag);
	}
	else
	{
		nth_element(P + ll, P + mid, P + rr + 1, ycmp);
		tree[rt].id = P[mid].id, x = tree[rt].x = P[mid].x, y = tree[rt].y = P[mid].y;
		build(tree[rt].l, ll, mid - 1, x1, y1, x2, y, rt, 1 - flag);
		build(tree[rt].r, mid + 1, rr, x1, y, x2, y2, rt, 1 - flag);
	}
	update(rt);
	//cout<<rt<<" "<<tree[rt].l<<" "<<tree[rt].r<<" "<<tree[rt].id<<" "<<tree[rt].h<<endl;
	//cout<<tree[rt].x<<" "<<tree[rt].y<<endl;
	//cout<<tree[rt].x1<<" "<<tree[rt].y1<<" "<<tree[rt].x2<<" "<<tree[rt].y2<<endl;
	//cout<<endl;
	return;
}

void query(int rt, int x1, int y1, int x2, int y2, int &res)
{
	if(rt == -1 || x1 > tree[rt].x2 || x2 < tree[rt].x1 || y1 > tree[rt].y2 || y2 < tree[rt].y1) return;
    if(tree[rt].h == -1 || res != -1 && tree[res].id <= tree[tree[rt].h].id) return;

	if(x1 <= tree[rt].x1 && x2 >= tree[rt].x2 && y1 <= tree[rt].y1 && y2 >= tree[rt].y2)
    {
        if(res == -1 || tree[tree[rt].h].id < tree[res].id) res = tree[rt].h;
        return;
    }

	if(!used[tree[rt].id] && tree[rt].x >= x1 && tree[rt].x <= x2 && tree[rt].y >= y1 && tree[rt].y <= y2)
    {
        if(res == -1 || tree[rt].id < tree[res].id) res = rt;
    }
	query(tree[rt].l, x1, y1, x2, y2, res);
	query(tree[rt].r, x1, y1, x2, y2, res);
	return;
}

int main()
{
	//freopen("input.txt", "r", stdin);
	int x1, x2, y1, y2, x, y, z;
	scanf("%d", &N);
	for(int i = 0; i < N; i++)
	{
		scanf("%d%d%d%d%d", &T[i].x1, &T[i].x2, &T[i].y1, &T[i].y2, &T[i].z);
        T[i].id = i;
	}
	sort(T, T + N, cmp);
	scanf("%d", &M);
	x1 = y1 = INF, x2 = y2 = 0;
	for(int i = 0; i < M; i++)
	{
		scanf("%d%d", &P[i].x, &P[i].y);
        P[i].id = i;
		x1 = min(x1, P[i].x);
		x2 = max(x2, P[i].x);
		y1 = min(y1, P[i].y);
		y2 = max(y2, P[i].y);
	}
	//cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
	tot = 0;
	build(root, 0, M - 1, x1, y1, x2, y2, -1, 0);
	memset(used, false, sizeof(used));
	memset(R, 0, sizeof(R));
	for(int i = 0; i < N; i++)
	{
        int res = -1;
		query(root, T[i].x1, T[i].y1, T[i].x2, T[i].y2, res);
		//cout<<res<<endl;
		if(res != -1)
		{
			used[tree[res].id] = true;
			R[tree[res].id] = T[i].id + 1;
			for(; res != -1; res = tree[res].fa)
				update(res);
		}
	}
	//cout<<endl;
	for(int i = 0; i < M; i++)
		printf("%d\n", R[i]);
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int nn=100005;
struct mrx{int x1,x2,y1,y2,z,p;}a[nn];
int n,m,l[nn],r[nn];
void read(int &x){
	char ch=getchar();for(;ch<48;ch=getchar());
	for(x=0;ch>=48;ch=getchar())x=x*10+ch-48;
}
inline bool cmp(const mrx &x,const mrx &y){
	return x.z<y.z;
}
int main(){
	read(n);
	for(int i=1;i<=n;++i){
		read(a[i].x1);read(a[i].x2);
		read(a[i].y1);read(a[i].y2);
		read(a[i].z);a[i].p=i;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;++i)l[i]=i-1,r[i]=i+1;
	r[0]=1;l[0]=n;r[n]=0;
	read(m);
	for(int i=1;i<=m;++i){
		int x,y,j=0;
		read(x);read(y);
		for(j=r[0];j;j=r[j])
			if(x>=a[j].x1&&x<=a[j].x2&&y>=a[j].y1&&y<=a[j].y2){
				r[l[j]]=r[j],l[r[j]]=l[j];
				break;
			}
		printf("%d\n",a[j].p);
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<vector>
#include<utility>
#include<climits>
#include<algorithm>
#include<iostream>
using namespace std;

#define ALL(v) (v).begin(), (v).end()
#define SIZE(v) ((int)(v).size())

const int N = 100000;
const int LOG = 19;

int n, m, x[N][2], y[N][2], z[N], a[N], b[N], answer[N], order[N];
vector<int> values;

bool by_z(int i, int j) {
	return z[i] < z[j];
}

int root[N << 1];

int getID(int l, int r) {
	return l + r | l != r;
}

pair <int, int> key[N * LOG];
int treapCount, weight[N * LOG], minY[N * LOG], maxY[N * LOG], minID[N * LOG], children[N * LOG][2];

void update(int &x) {
	minY[x] = children[x][0] ? minY[children[x][0]] : key[x].first;
	maxY[x] = children[x][1] ? maxY[children[x][1]] : key[x].first;
	minID[x] = min(key[x].second, std::min(minID[children[x][0]], minID[children[x][1]]));
}

void rotate(int &x, int t) {
	int y = children[x][t];
	children[x][t] = children[y][1 ^ t];
	children[y][1 ^ t] = x;
	update(x);
	update(y);
	x = y;
}

void treapInsert(int &x, const pair<int, int> &k) {
	if (x) {
		int t = key[x] < k;
		treapInsert(children[x][t], k);
		if (weight[children[x][t]] < weight[x]) {
			rotate(x, t);
		}
	} else {
		x = treapCount ++;
		key[x] = k;
		weight[x] = rand();
	}
	update(x);
}

void treapDelete(int &x, const pair<int, int> &k) {
	if (key[x] != k) {
		treapDelete(children[x][key[x] < k], k);
	} else {
		if (children[x][0] || children[x][1]) {
			rotate(x, weight[children[x][0]] > weight[children[x][1]]);
			treapDelete(x, k);
		} else {
			x = 0;
			return;
		}
	}
	update(x);
}

int treapQuery(int &x, int y1, int y2) {
	if (!x || y2 < minY[x] || maxY[x] < y1) {
		return INT_MAX;
	}
	if (y1 <= minY[x] && maxY[x] <= y2) {
		return minID[x];
	}
	int ret = min(treapQuery(children[x][0], y1, y2), treapQuery(children[x][1], y1, y2));
	if (y1 <= key[x].first && key[x].first <= y2) {
		ret = min(ret, key[x].second);
	}
	return ret;
}

void segmentTreeInsert(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapInsert(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segmentTreeInsert(l, m, x, y, w);
		segmentTreeInsert(m + 1, r, x, y, w);
	}
}

void segmentTreeDelete(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapDelete(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segmentTreeDelete(l, m, x, y, w);
		segmentTreeDelete(m + 1, r, x, y, w);
	}
}

int segmentTreeQuery(int l, int r, int x1, int x2, int y1, int y2) {
	if (x2 < values[l] || values[r] < x1) {
		return INT_MAX;
	}
	if (x1 <= values[l] && values[r] <= x2) {
		return treapQuery(root[getID(l, r)], y1, y2);
	}
	int m = l + r >> 1;
	return min(segmentTreeQuery(l, m, x1, x2, y1, y2), segmentTreeQuery(m + 1, r, x1, x2, y1, y2));
}

int main() {
	treapCount = 1;
	weight[0] = minY[0] = minID[0] = INT_MAX;
	maxY[0] = INT_MIN;
	memset(children, 0, sizeof(children));
	scanf("%d", &n);
	for (int i = 0; i < n; ++ i) {
		scanf("%d%d%d%d%d", &x[i][0], &x[i][1], &y[i][0], &y[i][1], z + i);
		order[i] = i;
	}
	sort(order, order + n, by_z);
	scanf("%d", &m);
	for (int i = 0; i < m; ++i) {
		scanf("%d%d", a + i, b + i);
		values.push_back(a[i]);
	}
	sort(ALL(values));
	values.erase(unique(ALL(values)), values.end());
	memset(answer, -1, sizeof(answer));
	memset(root, 0, sizeof(root));
	for (int i = 0; i < m; ++ i) {
		segmentTreeInsert(0, SIZE(values) - 1, a[i], b[i], i);
	}
	for (int _ = 0; _ < n; ++ _) {
		int i = order[_];
		int ret = segmentTreeQuery(0, SIZE(values) - 1, x[i][0], x[i][1], y[i][0], y[i][1]);
		if (ret != INT_MAX) {
			answer[ret] = i;
			segmentTreeDelete(0, SIZE(values) - 1, a[ret], b[ret], ret);
		}
	}
	for (int i = 0; i < m; ++i) {
		printf("%d\n", answer[i] + 1);
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<climits>
#include<utility>
using namespace std;

const int N = 100000;
int n, m, x[N][2], y[N][2], z[N], px[N], py[N], ans[N];
vector<int> values;

bool by_z(int i, int j) {
	return z[i] < z[j];
}

int root[N << 1];

int getID(const int l, const int r) {
	return l + r | l != r;
}

const int LOG = 18;
pair<int, int> key[N * LOG];
int treapCount, weight[N * LOG], minY[N * LOG], maxY[N * LOG], minID[N * LOG], children[N * LOG][2];

void update(int x) {
	minY[x] = children[x][0] ? minY[children[x][0]] : key[x].first;
	maxY[x] = children[x][1] ? maxY[children[x][1]] : key[x].first;
	minID[x] = min(key[x].second, min(minID[children[x][0]], minID[children[x][1]]));
}

void rotate(int &x, int t) {
	int y = children[x][t];
	children[x][t] = children[y][1 ^ t];
	children[y][1 ^ t] = x;
	update(x);
	update(y);
	x = y;
}

void treapInsert(int &x, pair<int, int> k) {
	if (x) {
		int t = key[x] < k;
		treapInsert(children[x][t], k);
		if (weight[children[x][t]] < weight[x]) {
			rotate(x, t);
		}
	} else {
		x = treapCount++;
		key[x] = k;
		weight[x] = rand();
	}
	update(x);
}

void treapDelete(int &x, pair<int, int> k) {
	if (key[x] == k) {
		if (children[x][0] || children[x][1]) {
			rotate(x, weight[children[x][0]] > weight[children[x][1]]);
			treapDelete(x, k);
		} else {
			x = 0;
			return;
		}
	} else {
		treapDelete(children[x][key[x] < k], k);
	}
	update(x);
}

int treapQuery(int x, int y1, int y2) {
	if (!x || y2 < minY[x] || maxY[x] < y1) {
		return INT_MAX;
	}
	if (y1 <= minY[x] && maxY[x] <= y2) {
		return minID[x];
	}
	int ret = min(treapQuery(children[x][0], y1, y2), treapQuery(children[x][1], y1, y2));
	if (y1 <= key[x].first && key[x].first <= y2) {
		ret = min(ret, key[x].second);
	}
	return ret;
}

void segInsert(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapInsert(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segInsert(l, m, x, y, w);
		segInsert(m + 1, r, x, y, w);
	}
}

void segDelete(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapDelete(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segDelete(l, m, x, y, w);
		segDelete(m + 1, r, x, y, w);
	}
}

int segQuery(int l, int r, int x1, int x2, int y1, int y2) {
	if (x2 < values[l] || values[r] < x1) {
		return INT_MAX;
	}
	if (x1 <= values[l] && values[r] <= x2) {
		return treapQuery(root[getID(l, r)], y1, y2);
	}
	int m = l + r >> 1;
	return min(segQuery(l, m, x1, x2, y1, y2), segQuery(m + 1, r, x1, x2, y1, y2));
}

int main() {
	treapCount = 1;
	weight[0] = INT_MAX;
	minY[0] = INT_MAX;
	maxY[0] = INT_MIN;
	minID[0] = INT_MAX;
	vector<int> ord;
	memset(children, 0, sizeof(children));

	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d%d", &x[i][0], &x[i][1], &y[i][0], &y[i][1], z + i);
		ord.push_back(i);
	}
	sort(ord.begin(), ord.end(), by_z);
	scanf("%d", &m);
	for (int i = 0; i < m; ++i) {
		scanf("%d%d", px + i, py + i);
		values.push_back(px[i]);
	}
	sort(values.begin(), values.end());
	values.erase(unique(values.begin(), values.end()), values.end());
	memset(ans, -1, sizeof(ans));
	for (int i = 0; i < m; ++i) {
		segInsert(0, values.size() - 1, px[i], py[i], i);
	}
	for (int _ = 0; _ < n; ++_) {
		int i = ord[_];
		int ret = segQuery(0, values.size() - 1, x[i][0], x[i][1], y[i][0], y[i][1]);
		if (ret != INT_MAX) {
			ans[ret] = i;
			segDelete(0, values.size() - 1, px[ret], py[ret], ret);
		}
	}
	for (int i = 0; i < m; ++i) {
		printf("%d\n", ans[i] + 1);
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<climits>
#include<utility>
using namespace std;

const int N = 100000;
int n, m, x[N][2], y[N][2], z[N], px[N], py[N], answer[N];
vector<int> values;

bool by_z(const int i, const int j) {
	return z[i] < z[j];
}

int root[N << 1];

int getID(const int l, const int r) {
	return l + r | l != r;
}

const int LOG = 19;
pair<int, int> key[N * LOG];
int treapCount, weight[N * LOG], minY[N * LOG], maxY[N * LOG], minID[N * LOG], children[N * LOG][2];

void update(int &x) {
	minY[x] = children[x][0] ? minY[children[x][0]] : key[x].first;
	maxY[x] = children[x][1] ? maxY[children[x][1]] : key[x].first;
	minID[x] = min(key[x].second, min(minID[children[x][0]], minID[children[x][1]]));
}

void rotate(int &x, int t) {
	int y = children[x][t];
	children[x][t] = children[y][1 ^ t];
	children[y][1 ^ t] = x;
	update(x);
	update(y);
	x = y;
}

void treapInsert(int &x, const pair<int, int> &k) {
	if (x) {
		int t = key[x] < k;
		treapInsert(children[x][t], k);
		if (weight[children[x][t]] < weight[x]) {
			rotate(x, t);
		}
	} else {
		x = treapCount ++;
		key[x] = k;
		weight[x] = rand();
	}
	update(x);
}

void treapDelete(int &x, const pair<int, int> &k) {
	if (key[x] == k) {
		if (children[x][0] || children[x][1]) {
			rotate(x, weight[children[x][0]] > weight[children[x][1]]);
			treapDelete(x, k);
		} else {
			x = 0;
			return;
		}
	} else {
		treapDelete(children[x][key[x] < k], k);
	}
	update(x);
}

int treapQuery(int &x, int y1, int y2) {
	if (!x || y2 < minY[x] || maxY[x] < y1) {
		return INT_MAX;
	}
	if (y1 <= minY[x] && maxY[x] <= y2) {
		return minID[x];
	}
	int ret = min(treapQuery(children[x][0], y1, y2), treapQuery(children[x][1], y1, y2));
	if (y1 <= key[x].first && key[x].first <= y2) {
		ret = min(ret, key[x].second);
	}
	return ret;
}

void segmentTreeInsert(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapInsert(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segmentTreeInsert(l, m, x, y, w);
		segmentTreeInsert(m + 1, r, x, y, w);
	}
}

void segmentTreeDelete(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapDelete(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segmentTreeDelete(l, m, x, y, w);
		segmentTreeDelete(m + 1, r, x, y, w);
	}
}

int segmentTreeQuery(int l, int r, int x1, int x2, int y1, int y2) {
	if (x2 < values[l] || values[r] < x1) {
		return INT_MAX;
	}
	if (x1 <= values[l] && values[r] <= x2) {
		return treapQuery(root[getID(l, r)], y1, y2);
	}
	int m = l + r >> 1;
	return min(segmentTreeQuery(l, m, x1, x2, y1, y2), segmentTreeQuery(m + 1, r, x1, x2, y1, y2));
}

int main() {
	treapCount = 1;
	weight[0] = INT_MAX;
	minY[0] = INT_MAX;
	maxY[0] = INT_MIN;
	minID[0] = INT_MAX;
	vector<int> ord;
	memset(children, 0, sizeof(children));

	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d%d", &x[i][0], &x[i][1], &y[i][0], &y[i][1], z + i);
		ord.push_back(i);
	}
	sort(ord.begin(), ord.end(), by_z);
	scanf("%d", &m);
	for (int i = 0; i < m; ++i) {
		scanf("%d%d", px + i, py + i);
		values.push_back(px[i]);
	}
	sort(values.begin(), values.end());
	values.erase(unique(values.begin(), values.end()), values.end());
	memset(answer, -1, sizeof(answer));
	for (int i = 0; i < m; ++i) {
		segmentTreeInsert(0, values.size() - 1, px[i], py[i], i);
	}
	for (int _ = 0; _ < n; ++ _) {
		int i = ord[_];
		int ret = segmentTreeQuery(0, values.size() - 1, x[i][0], x[i][1], y[i][0], y[i][1]);
		if (ret != INT_MAX) {
			answer[ret] = i;
			segmentTreeDelete(0, values.size() - 1, px[ret], py[ret], ret);
		}
	}
	for (int i = 0; i < m; ++i) {
		printf("%d\n", answer[i] + 1);
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<climits>
#include<utility>
using namespace std;

const int N = 100000;
int n, m, x[N][2], y[N][2], z[N], px[N], py[N], ans[N];
vector<int> values;

bool by_z(int i, int j) {
	return z[i] < z[j];
}

int root[N << 1];

int getID(const int l, const int r) {
	return l + r | l != r;
}

const int LOG = 18;
pair<int, int> key[N * LOG];
int treapCount, weight[N * LOG], minY[N * LOG], maxY[N * LOG], minID[N * LOG], children[N * LOG][2];

void update(int x) {
	minY[x] = children[x][0] ? minY[children[x][0]] : key[x].first;
	maxY[x] = children[x][1] ? maxY[children[x][1]] : key[x].first;
	minID[x] = min(key[x].second, min(minID[children[x][0]], minID[children[x][1]]));
}

void rotate(int &x, int t) {
	int y = children[x][t];
	children[x][t] = children[y][1 ^ t];
	children[y][1 ^ t] = x;
	update(x);
	update(y);
	x = y;
}

void treapInsert(int &x, pair<int, int> k) {
	if (x) {
		int t = key[x] < k;
		treapInsert(children[x][t], k);
		if (weight[children[x][t]] < weight[x]) {
			rotate(x, t);
		}
	} else {
		x = treapCount++;
		key[x] = k;
		weight[x] = rand();
	}
	update(x);
}

void treapDelete(int &x, pair<int, int> k) {
	if (key[x] == k) {
		if (children[x][0] || children[x][1]) {
			rotate(x, weight[children[x][0]] > weight[children[x][1]]);
			treapDelete(x, k);
		} else {
			x = 0;
			return;
		}
	} else {
		treapDelete(children[x][key[x] < k], k);
	}
	update(x);
}

int treapQuery(int x, int y1, int y2) {
	if (!x || y2 < minY[x] || minY[x] < y1) {
		return INT_MAX;
	}
	if (y1 <= minY[x] && maxY[x] <= y2) {
		return minID[x];
	}
	int ret = min(treapQuery(children[x][0], y1, y2), treapQuery(children[x][1], y1, y2));
	if (y1 <= key[x].first && key[x].first <= y2) {
		ret = min(ret, key[x].second);
	}
	return ret;
}

void segInsert(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapInsert(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segInsert(l, m, x, y, w);
		segInsert(m + 1, r, x, y, w);
	}
}

void segDelete(int l, int r, int x, int y, int w) {
	if (x < values[l] || values[r] < x) {
		return;
	}
	treapDelete(root[getID(l, r)], make_pair(y, w));
	if (l < r) {
		int m = l + r >> 1;
		segDelete(l, m, x, y, w);
		segDelete(m + 1, r, x, y, w);
	}
}

int segQuery(int l, int r, int x1, int x2, int y1, int y2) {
	if (x2 < values[l] || values[r] < x1) {
		return INT_MAX;
	}
	if (x1 <= values[l] && values[r] <= x2) {
		return treapQuery(root[getID(l, r)], y1, y2);
	}
	int m = l + r >> 1;
	return min(segQuery(l, m, x1, x2, y1, y2), segQuery(m + 1, r, x1, x2, y1, y2));
}

int main() {
	treapCount = 1;
	weight[0] = INT_MAX;
	minY[0] = INT_MAX;
	maxY[0] = INT_MIN;
	minID[0] = INT_MAX;
	vector<int> ord;
	memset(children, 0, sizeof(children));

	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d%d", &x[i][0], &x[i][1], &y[i][0], &y[i][1], z + i);
		ord.push_back(i);
	}
	sort(ord.begin(), ord.end(), by_z);
	scanf("%d", &m);
	for (int i = 0; i < m; ++i) {
		scanf("%d%d", px + i, py + i);
		values.push_back(px[i]);
	}
	sort(values.begin(), values.end());
	values.erase(unique(values.begin(), values.end()), values.end());
	memset(ans, -1, sizeof(ans));
	for (int i = 0; i < m; ++i) {
		segInsert(0, values.size() - 1, px[i], py[i], i);
	}
	for (int _ = 0; _ < n; ++_) {
		int i = ord[_];
		int ret = segQuery(0, values.size() - 1, x[i][0], x[i][1], y[i][0], y[i][1]);
		if (ret != INT_MAX) {
			ans[ret] = i;
			segDelete(0, values.size() - 1, px[ret], py[ret], ret);
		}
	}
	for (int i = 0; i < m; ++i) {
		printf("%d\n", ans[i] + 1);
	}
	return 0;
}


// School Team Contest #2
// Problem G -- Shooting Gallery
#include <cstdio>
#include <cstring>
#include <climits>
#include <utility>
#include <algorithm>

#define pushBack push_back
#define lowerBound lower_bound

using namespace std;

const int N = 100000;
const int maxTreeCnt = 600000;
const int maxTreapCnt = 2000000;

int readInt(){
	int result = 0;
	char ch = getchar();
	while(ch < '0' or '9' < ch){
		ch = getchar();
	}
	while('0' <= ch and ch <= '9'){
		result = result * 10 + ch - '0';
		ch = getchar();
	}
	return result;
}

struct Point{
	int id, x, y;

	Point(){
		id = N;
	}

	inline bool operator < (const Point &other) const{
		return id < other.id;
	}

	void read(){
		x = readInt();
		y = readInt();
	}

	inline bool compareTo(const Point &other) const{
		if(y == other.y){
			return id < other.id;
		}
		return y < other.y;
	}

};

struct Rect{
	int id, z;
	Point l, r;

	inline bool operator < (const Rect &other) const{
		return z < other.z;
	}

	void read(){
		l.x = readInt();
		r.x = readInt();
		l.y = readInt();
		r.y = readInt();
		z = readInt();
	}
};

int treapCnt, priority[maxTreapCnt],
    childs[maxTreapCnt][2], lower[maxTreapCnt], upper[maxTreapCnt];
Point key[maxTreapCnt], first[maxTreapCnt];

struct Treap{
	int root;

	Treap(){
		root = 0;
	}

	inline void myUpdate(int x){
		first[x] = min(key[x],
		           min(first[childs[x][0]], first[childs[x][1]]));
		lower[x] = min(key[x].y, lower[childs[x][0]]);
		upper[x] = max(key[x].y, upper[childs[x][1]]);
	}

	inline void myRotate(int &x, int t){
		int y = childs[x][t];
		childs[x][t] = childs[y][1 - t];
		childs[y][1 - t] = x;
		myUpdate(x);
		myUpdate(y);
		x = y;
	}

	inline int myRandom(){
		return rand(); // ((rand() & 32767) << 15) | rand();
	}

	void myInsert(int &x, const Point &point){
		if(x){
			int t = key[x].compareTo(point);
			myInsert(childs[x][t], point);
			if(priority[childs[x][t]] < priority[x]){
				myRotate(x, t);
			}
		}else{
			x = ++ treapCnt;
			key[x] = point;
			priority[x] = myRandom();
			childs[x][0] = childs[x][1] = 0;
		}
		myUpdate(x);
	}

	void myErase(int &x, const Point &point){
		if(point.compareTo(key[x])){
			myErase(childs[x][0], point);
		}else if(key[x].compareTo(point)){
			myErase(childs[x][1], point);
		}else{
			if(childs[x][0] + childs[x][1] == 0){
				x = 0;
				return;
			}
			myRotate(x, priority[childs[x][0]] > priority[childs[x][1]]);
			myErase(x, point);
		}
		myUpdate(x);
	}

	Point myQuery(int x, const Rect &rect){
		if(not x or (rect.l.y <= lower[x] and upper[x] <= rect.r.y)){
			return first[x];
		}
		Point tmp;
		if(rect.l.y <= upper[childs[x][0]]){
			tmp = min(tmp, myQuery(childs[x][0], rect));
		}
		if(lower[childs[x][1]] <= rect.r.y){
			tmp = min(tmp, myQuery(childs[x][1], rect));
		}
		if(rect.l.y <= key[x].y and key[x].y <= rect.r.y){
			tmp = min(tmp, key[x]);
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(root, point);
	}

	void erase(const Point &point){
		myErase(root, point);
	}

	Point query(const Rect &rect){
		return myQuery(root, rect);
	}

};

int rangeMax;
Treap treaps[maxTreeCnt];

struct Tree{
	inline int myIndex(int l, int r){
		return (l + r) | (l != r);
	}

	void myInsert(int l, int r, const Point &point){
		treaps[myIndex(l, r)].insert(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myInsert(l, m, point);
			}else{
				myInsert(m + 1, r, point);
			}
		}
	}

	void myErase(int l, int r, const Point &point){
		treaps[myIndex(l, r)].erase(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myErase(l, m, point);
			}else{
				myErase(m + 1, r, point);
			}
		}
	}

	Point myQuery(int l, int r, const Rect rect){
		if(rect.l.x <= l and r <= rect.r.x){
			return treaps[myIndex(l, r)].query(rect);
		}
		int m = (l + r) >> 1;
		Point tmp;
		if(rect.l.x <= m){
			tmp = min(tmp, myQuery(l, m, rect));
		}
		if(m < rect.r.x){
			tmp = min(tmp, myQuery(m + 1, r, rect));
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(0, rangeMax, point);
	}

	void erase(const Point &point){
		myErase(0, rangeMax, point);
	}

	Point query(const Rect &rect){
		return myQuery(0, rangeMax, rect);
	}
};

int rectCnt, shotCnt;
Rect rects[N];
Point shots[N];

int listSize, list[maxTreeCnt];

Tree tree;

int result[N];

int main(){
	scanf("%d", &rectCnt);
	listSize = 0;
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].id = i;
		rects[i].read();
		list[listSize ++] = rects[i].l.x;
		list[listSize ++] = rects[i].r.x;
	}
	sort(rects, rects + rectCnt);
	scanf("%d", &shotCnt);
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].id = i;
		shots[i].read();
		list[listSize ++] = shots[i].x;
	}
	sort(list, list + listSize);
	listSize = unique(list, list + listSize) - list;
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].l.x = lowerBound(list, list + listSize, rects[i].l.x)
		             - list;
		rects[i].r.x = lowerBound(list, list + listSize, rects[i].r.x)
		             - list;
	}
	rangeMax = listSize;
	treapCnt = 0;
	lower[0] = INT_MAX;
	upper[0] = INT_MIN;
	priority[0] = INT_MAX;
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].x = lowerBound(list, list + listSize, shots[i].x) - list;
		tree.insert(shots[i]);
	}
	memset(result, 0, sizeof(result));
	for(int i = 0; i < rectCnt; ++ i){
		Point tmp = tree.query(rects[i]);
		if(tmp.id < shotCnt){
			tree.erase(tmp);
			result[tmp.id] = rects[i].id + 1;
		}
	}
	for(int i = 0; i < shotCnt; ++ i){
		printf("%d\n", result[i]);
	}
	return 0;
}


// School Team Contest #2
// Problem G -- Shooting Gallery
#include <vector>
#include <cstdio>
#include <cstring>
#include <climits>
#include <utility>
#include <algorithm>

#define pushBack push_back
#define lowerBound lower_bound

using namespace std;

const int N = 100000;
const int maxTreeCnt = 600000;
const int maxTreapCnt = 2000000;

struct Point{
	int id, x, y;

	Point(){
		id = N;
	}

	bool operator < (const Point &other) const{
		return id < other.id;
	}

	void read(){
		scanf("%d%d", &x, &y);
	}

	bool compareTo(const Point &other) const{
		if(y == other.y){
			return id < other.id;
		}
		return y < other.y;
	}

	void show(){
		printf("(%d, %d) %d\n", x, y, id);
	}
};

struct Rect{
	int id, z;
	Point l, r;

	bool operator < (const Rect &other) const{
		return z < other.z;
	}

	void read(){
		scanf("%d%d%d%d%d", &l.x, &r.x, &l.y, &r.y, &z);
	}
};

int treapCnt, priority[maxTreapCnt],
    childs[maxTreapCnt][2], lower[maxTreapCnt], upper[maxTreapCnt];
Point null, key[maxTreapCnt], first[maxTreapCnt];

struct Treap{
	int root;

	Treap(){
		root = 0;
	}

	void myUpdate(int x){
		first[x] = min(key[x],
		           min(first[childs[x][0]], first[childs[x][1]]));
		lower[x] = min(key[x].y,
		           min(lower[childs[x][0]], lower[childs[x][1]]));
		upper[x] = max(key[x].y,
		           max(upper[childs[x][0]], upper[childs[x][1]]));
	}

	void myRotate(int &x, int t){
		int y = childs[x][t];
		childs[x][t] = childs[y][1 - t];
		childs[y][1 - t] = x;
		myUpdate(x);
		myUpdate(y);
		x = y;
	}

	void myInsert(int &x, const Point &point){
		if(x){
			int t = key[x].compareTo(point);
			myInsert(childs[x][t], point);
			if(priority[childs[x][t]] < priority[x]){
				myRotate(x, t);
			}
		}else{
			x = ++ treapCnt;
			key[x] = point;
			priority[x] = rand();
			childs[x][0] = childs[x][1] = 0;
		}
		myUpdate(x);
	}

	void myErase(int &x, const Point &point){
		if(point.compareTo(key[x])){
			myErase(childs[x][0], point);
		}else if(key[x].compareTo(point)){
			myErase(childs[x][1], point);
		}else{
			if(childs[x][0] + childs[x][1] == 0){
				x = 0;
				return;
			}
			myRotate(x, priority[childs[x][0]] > priority[childs[x][1]]);
			myErase(x, point);
		}
		myUpdate(x);
	}

	Point myQuery(int x, const Rect &rect){
		if(rect.r.y < lower[x] or upper[x] < rect.l.y){
			return null;
		}
		if(rect.l.y <= lower[x] and upper[x] <= rect.r.y){
			return first[x];
		}
		Point tmp = min(myQuery(childs[x][0], rect),
		                myQuery(childs[x][1], rect));
		if(rect.l.y <= key[x].y and key[x].y <= rect.r.y){
			tmp = min(tmp, key[x]);
		}
		return tmp;
	}

	void myShow(int x){
		if(x){
			key[x].show();
			printf("%d %d\n", lower[x], upper[x]);
			first[x].show();
			myShow(childs[x][0]);
			myShow(childs[x][1]);
		}
	}

	void insert(const Point &point){
		myInsert(root, point);
	}

	void erase(const Point &point){
		myErase(root, point);
	}

	Point query(const Rect &rect){
		return myQuery(root, rect);
	}

	void show(){
		myShow(root);
	}
};

int rangeMax;
Treap treaps[maxTreeCnt];

struct Tree{
	int myIndex(int l, int r){
		return (l + r) | (l != r);
	}

	void myInsert(int l, int r, const Point &point){
		treaps[myIndex(l, r)].insert(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myInsert(l, m, point);
			}else{
				myInsert(m + 1, r, point);
			}
		}
	}

	void myErase(int l, int r, const Point &point){
		treaps[myIndex(l, r)].erase(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myErase(l, m, point);
			}else{
				myErase(m + 1, r, point);
			}
		}
	}

	Point myQuery(int l, int r, const Rect rect){
		if(rect.l.x <= l and r <= rect.r.x){
			return treaps[myIndex(l, r)].query(rect);
		}
		int m = (l + r) >> 1;
		Point tmp;
		if(rect.l.x <= m){
			tmp = min(tmp, myQuery(l, m, rect));
		}
		if(m < rect.r.x){
			tmp = min(tmp, myQuery(m + 1, r, rect));
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(0, rangeMax, point);
	}

	void erase(const Point &point){
		myErase(0, rangeMax, point);
	}

	Point query(const Rect &rect){
		return myQuery(0, rangeMax, rect);
	}
};

int rectCnt, shotCnt;
Rect rects[N];
Point shots[N];

vector<int> sortedList;

Tree tree;

int result[N];

int main(){
	scanf("%d", &rectCnt);
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].id = i;
		rects[i].read();
		sortedList.pushBack(rects[i].l.x);
		sortedList.pushBack(rects[i].r.x);
	}
	sort(rects, rects + rectCnt);
	scanf("%d", &shotCnt);
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].id = i;
		shots[i].read();
		sortedList.pushBack(shots[i].x);
	}
	sort(sortedList.begin(), sortedList.end());
	sortedList.erase(unique(sortedList.begin(), sortedList.end()), \
	                 sortedList.end());
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].l.x = lowerBound(sortedList.begin(), sortedList.end(),
		               rects[i].l.x) - sortedList.begin();
		rects[i].r.x = lowerBound(sortedList.begin(), sortedList.end(),
		               rects[i].r.x) - sortedList.begin();
	}
	rangeMax = sortedList.size();
	treapCnt = 0;
	lower[0] = INT_MAX;
	upper[0] = INT_MIN;
	priority[0] = INT_MAX;
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].x = lowerBound(sortedList.begin(), sortedList.end(),
		             shots[i].x) - sortedList.begin();
		tree.insert(shots[i]);
	}
	memset(result, 0, sizeof(result));
	for(int i = 0; i < rectCnt; ++ i){
		Point tmp = tree.query(rects[i]);
		if(tmp.id < shotCnt){
			tree.erase(tmp);
			result[tmp.id] = rects[i].id + 1;
		}
	}
	for(int i = 0; i < shotCnt; ++ i){
		printf("%d\n", result[i]);
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <vector>
#include <utility>
#include <climits>
#include <algorithm>

#define ALL(v) (v).begin(), (v).end()
#define SIZE(v) ((int)(v).size())

const int N = 100000;
const int LOG = 19;

int n, m, x[N][2], y[N][2], z[N], a[N], b[N], answer[N], order[N];
std::vector <int> values;

bool by_z(int i, int j) {
    return z[i] < z[j];
}

int root[N << 1];

int getID(int l, int r) {
    return l + r | l != r;
}

std::pair <int, int> key[N * LOG];
int treapCount, weight[N * LOG], minY[N * LOG], maxY[N * LOG], minID[N * LOG], children[N * LOG][2];

void update(int &x) {
    minY[x] = children[x][0] ? minY[children[x][0]] : key[x].first;
    maxY[x] = children[x][1] ? maxY[children[x][1]] : key[x].first;
    minID[x] = std::min(key[x].second, std::min(minID[children[x][0]], minID[children[x][1]]));
}

void rotate(int &x, int t) {
    int y = children[x][t];
    children[x][t] = children[y][1 ^ t];
    children[y][1 ^ t] = x;
    update(x);
    update(y);
    x = y;
}

void treapInsert(int &x, const std::pair <int, int> &k) {
    if (x)  {
        int t = key[x] < k;
        treapInsert(children[x][t], k);
        if (weight[children[x][t]] < weight[x]) {
            rotate(x, t);
        }
    } else {
        x = treapCount ++;
        key[x] = k;
        weight[x] = rand() << 15 | rand();
    }
    update(x);
}

void treapDelete(int &x, const std::pair <int, int> &k) {
    if (key[x] != k) {
        treapDelete(children[x][key[x] < k], k);
    } else {
        if (children[x][0] || children[x][1]) {
            rotate(x, weight[children[x][0]] > weight[children[x][1]]);
            treapDelete(x, k);
        } else {
            x = 0;
            return;
        }
    }
    update(x);
}

int treapQuery(int &x, int y1, int y2) {
    if (!x || y2 < minY[x] || maxY[x] < y1) {
        return INT_MAX;
    }
    if (y1 <= minY[x] && maxY[x] <= y2) {
        return minID[x];
    }
    int ret = std::min(treapQuery(children[x][0], y1, y2), treapQuery(children[x][1], y1, y2));
    if (y1 <= key[x].first && key[x].first <= y2) {
        ret = std::min(ret, key[x].second);
    }
    return ret;
}

void segmentTreeInsert(int l, int r, int x, int y, int w) {
    if (x < values[l] || values[r] < x) {
        return;
    }
    treapInsert(root[getID(l, r)], std::make_pair(y, w));
    if (l < r) {
        int m = l + r >> 1;
        segmentTreeInsert(l, m, x, y, w);
        segmentTreeInsert(m + 1, r, x, y, w);
    }
}

void segmentTreeDelete(int l, int r, int x, int y, int w) {
    if (x < values[l] || values[r] < x) {
        return;
    }
    treapDelete(root[getID(l, r)], std::make_pair(y, w));
    if (l < r) {
        int m = l + r >> 1;
        segmentTreeDelete(l, m, x, y, w);
        segmentTreeDelete(m + 1, r, x, y, w);
    }
}

int segmentTreeQuery(int l, int r, int x1, int x2, int y1, int y2) {
    if (x2 < values[l] || values[r] < x1) {
        return INT_MAX;
    }
    if (x1 <= values[l] && values[r] <= x2) {
        return treapQuery(root[getID(l, r)], y1, y2);
    }
    int m = l + r >> 1;
    return std::min(segmentTreeQuery(l, m, x1, x2, y1, y2), segmentTreeQuery(m + 1, r, x1, x2, y1, y2));
}

int main() {
    treapCount = 1;
    weight[0] = minY[0] = minID[0] = INT_MAX;
    maxY[0] = INT_MIN;
    memset(children, 0, sizeof(children));
    scanf("%d", &n);
    for (int i = 0; i < n; ++ i) {
        scanf("%d%d%d%d%d", &x[i][0], &x[i][1], &y[i][0], &y[i][1], z + i);
        order[i] = i;
    }
    std::sort(order, order + n, by_z);
    scanf("%d", &m);
    for (int i = 0; i < m; ++ i) {
        scanf("%d%d", a + i, b + i);
        values.push_back(a[i]);
    }
    std::sort(ALL(values));
    values.erase(std::unique(ALL(values)), values.end());
    memset(answer, -1, sizeof(answer));
    memset(root, 0, sizeof(root));
    for (int i = 0; i < m; ++ i) {
        segmentTreeInsert(0, SIZE(values) - 1, a[i], b[i], i);
    }
    for (int _ = 0; _ < n; ++ _) {
        int i = order[_];
        int ret = segmentTreeQuery(0, SIZE(values) - 1, x[i][0], x[i][1], y[i][0], y[i][1]);
        if (ret != INT_MAX) {
            answer[ret] = i;
            segmentTreeDelete(0, SIZE(values) - 1, a[ret], b[ret], ret);
        }
    }
    for (int i = 0; i < m; ++ i) {
        printf("%d\n", answer[i] + 1);
    }
    return 0;
}


// School Team Contest #2
// Problem G -- Shooting Gallery
#include <cstdio>
#include <cstring>
#include <climits>
#include <utility>
#include <algorithm>

#define pushBack push_back
#define lowerBound lower_bound

using namespace std;

const int N = 100000;
const int maxTreeCnt = 600000;
const int maxTreapCnt = 2000000;

int readInt(){
	int result = 0;
	char ch = getchar();
	while(ch < '0' or '9' < ch){
		ch = getchar();
	}
	while('0' <= ch and ch <= '9'){
		result = result * 10 + ch - '0';
		ch = getchar();
	}
	return result;
}

struct Point{
	int id, x, y;

	Point(){
		id = N;
	}

	inline bool operator < (const Point &other) const{
		return id < other.id;
	}

	void read(){
		x = readInt();
		y = readInt();
	}

	inline bool compareTo(const Point &other) const{
		if(y == other.y){
			return id < other.id;
		}
		return y < other.y;
	}

};

struct Rect{
	int id, z;
	Point l, r;

	inline bool operator < (const Rect &other) const{
		return z < other.z;
	}

	void read(){
		l.x = readInt();
		r.x = readInt();
		l.y = readInt();
		r.y = readInt();
		z = readInt();
	}
};

int treapCnt, priority[maxTreapCnt],
    childs[maxTreapCnt][2], lower[maxTreapCnt], upper[maxTreapCnt];
Point key[maxTreapCnt], first[maxTreapCnt];

struct Treap{
	int root;

	Treap(){
		root = 0;
	}

	inline void myUpdate(int x){
		first[x] = min(key[x],
		           min(first[childs[x][0]], first[childs[x][1]]));
		lower[x] = min(key[x].y, lower[childs[x][0]]);
		upper[x] = max(key[x].y, upper[childs[x][1]]);
	}

	inline void myRotate(int &x, int t){
		int y = childs[x][t];
		childs[x][t] = childs[y][1 - t];
		childs[y][1 - t] = x;
		myUpdate(x);
		myUpdate(y);
		x = y;
	}

	inline int myRandom(){
		return ((rand() & 32767) << 15) | rand();
	}

	void myInsert(int &x, const Point &point){
		if(x){
			int t = key[x].compareTo(point);
			myInsert(childs[x][t], point);
			if(priority[childs[x][t]] < priority[x]){
				myRotate(x, t);
			}
		}else{
			x = ++ treapCnt;
			key[x] = point;
			priority[x] = myRandom();
			childs[x][0] = childs[x][1] = 0;
		}
		myUpdate(x);
	}

	void myErase(int &x, const Point &point){
		if(point.compareTo(key[x])){
			myErase(childs[x][0], point);
		}else if(key[x].compareTo(point)){
			myErase(childs[x][1], point);
		}else{
			if(childs[x][0] + childs[x][1] == 0){
				x = 0;
				return;
			}
			myRotate(x, priority[childs[x][0]] > priority[childs[x][1]]);
			myErase(x, point);
		}
		myUpdate(x);
	}

	Point myQuery(int x, const Rect &rect){
		if(not x or (rect.l.y <= lower[x] and upper[x] <= rect.r.y)){
			return first[x];
		}
		Point tmp;
		if(rect.l.y <= upper[childs[x][0]]){
			tmp = min(tmp, myQuery(childs[x][0], rect));
		}
		if(lower[childs[x][1]] <= rect.r.y){
			tmp = min(tmp, myQuery(childs[x][1], rect));
		}
		if(rect.l.y <= key[x].y and key[x].y <= rect.r.y){
			tmp = min(tmp, key[x]);
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(root, point);
	}

	void erase(const Point &point){
		myErase(root, point);
	}

	Point query(const Rect &rect){
		return myQuery(root, rect);
	}

};

int rangeMax;
Treap treaps[maxTreeCnt];

struct Tree{
	inline int myIndex(int l, int r){
		return (l + r) | (l != r);
	}

	void myInsert(int l, int r, const Point &point){
		treaps[myIndex(l, r)].insert(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myInsert(l, m, point);
			}else{
				myInsert(m + 1, r, point);
			}
		}
	}

	void myErase(int l, int r, const Point &point){
		treaps[myIndex(l, r)].erase(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myErase(l, m, point);
			}else{
				myErase(m + 1, r, point);
			}
		}
	}

	Point myQuery(int l, int r, const Rect rect){
		if(rect.l.x <= l and r <= rect.r.x){
			return treaps[myIndex(l, r)].query(rect);
		}
		int m = (l + r) >> 1;
		Point tmp;
		if(rect.l.x <= m){
			tmp = min(tmp, myQuery(l, m, rect));
		}
		if(m < rect.r.x){
			tmp = min(tmp, myQuery(m + 1, r, rect));
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(0, rangeMax, point);
	}

	void erase(const Point &point){
		myErase(0, rangeMax, point);
	}

	Point query(const Rect &rect){
		return myQuery(0, rangeMax, rect);
	}
};

int rectCnt, shotCnt;
Rect rects[N];
Point shots[N];

int listSize, list[maxTreeCnt];

Tree tree;

int result[N];

int main(){
	scanf("%d", &rectCnt);
	listSize = 0;
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].id = i;
		rects[i].read();
		list[listSize ++] = rects[i].l.x;
		list[listSize ++] = rects[i].r.x;
	}
	sort(rects, rects + rectCnt);
	scanf("%d", &shotCnt);
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].id = i;
		shots[i].read();
		list[listSize ++] = shots[i].x;
	}
	sort(list, list + listSize);
	listSize = unique(list, list + listSize) - list;
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].l.x = lowerBound(list, list + listSize, rects[i].l.x)
		             - list;
		rects[i].r.x = lowerBound(list, list + listSize, rects[i].r.x)
		             - list;
	}
	rangeMax = listSize;
	treapCnt = 0;
	lower[0] = INT_MAX;
	upper[0] = INT_MIN;
	priority[0] = INT_MAX;
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].x = lowerBound(list, list + listSize, shots[i].x) - list;
		tree.insert(shots[i]);
	}
	memset(result, 0, sizeof(result));
	for(int i = 0; i < rectCnt; ++ i){
		Point tmp = tree.query(rects[i]);
		if(tmp.id < shotCnt){
			tree.erase(tmp);
			result[tmp.id] = rects[i].id + 1;
		}
	}
	for(int i = 0; i < shotCnt; ++ i){
		printf("%d\n", result[i]);
	}
	return 0;
}


// School Team Contest #2
// Problem G -- Shooting Gallery
#include <vector>
#include <cstdio>
#include <cstring>
#include <climits>
#include <utility>
#include <algorithm>

#define pushBack push_back
#define lowerBound lower_bound

using namespace std;

const int N = 100000;
const int maxTreeCnt = 600000;
const int maxTreapCnt = 4000000;

int readInt(){
	int result = 0;
	char ch = getchar();
	while(ch < '0' or '9' < ch){
		ch = getchar();
	}
	while('0' <= ch and ch <= '9'){
		result = result * 10 + ch - '0';
		ch = getchar();
	}
	return result;
}

struct Point{
	int id, x, y;

	Point(){
		id = N;
	}

	inline bool operator < (const Point &other) const{
		return id < other.id;
	}

	void read(){
		x = readInt();
		y = readInt();
	}

	inline bool compareTo(const Point &other) const{
		if(y == other.y){
			return id < other.id;
		}
		return y < other.y;
	}

};

struct Rect{
	int id, z;
	Point l, r;

	inline bool operator < (const Rect &other) const{
		return z < other.z;
	}

	void read(){
		l.x = readInt();
		r.x = readInt();
		l.y = readInt();
		r.y = readInt();
		z = readInt();
	}
};

int treapCnt, priority[maxTreapCnt],
    childs[maxTreapCnt][2], lower[maxTreapCnt], upper[maxTreapCnt];
Point null, key[maxTreapCnt], first[maxTreapCnt];

struct Treap{
	int root;

	Treap(){
		root = 0;
	}

	void myUpdate(int x){
		first[x] = min(key[x],
		           min(first[childs[x][0]], first[childs[x][1]]));
		lower[x] = min(key[x].y,
		           min(lower[childs[x][0]], lower[childs[x][1]]));
		upper[x] = max(key[x].y,
		           max(upper[childs[x][0]], upper[childs[x][1]]));
	}

	void myRotate(int &x, int t){
		int y = childs[x][t];
		childs[x][t] = childs[y][1 - t];
		childs[y][1 - t] = x;
		myUpdate(x);
		myUpdate(y);
		x = y;
	}

	inline int myRandom(){
		return ((rand() & 32767) << 15) | rand();
	}

	void myInsert(int &x, const Point &point){
		if(x){
			int t = key[x].compareTo(point);
			myInsert(childs[x][t], point);
			if(priority[childs[x][t]] < priority[x]){
				myRotate(x, t);
			}
		}else{
			x = ++ treapCnt;
			key[x] = point;
			priority[x] = myRandom();
			childs[x][0] = childs[x][1] = 0;
		}
		myUpdate(x);
	}

	void myErase(int &x, const Point &point){
		if(point.compareTo(key[x])){
			myErase(childs[x][0], point);
		}else if(key[x].compareTo(point)){
			myErase(childs[x][1], point);
		}else{
			if(childs[x][0] + childs[x][1] == 0){
				x = 0;
				return;
			}
			myRotate(x, priority[childs[x][0]] > priority[childs[x][1]]);
			myErase(x, point);
		}
		myUpdate(x);
	}

	Point myQuery(int x, const Rect &rect){
		if(rect.r.y < lower[x] or upper[x] < rect.l.y){
			return null;
		}
		if(rect.l.y <= lower[x] and upper[x] <= rect.r.y){
			return first[x];
		}
		Point tmp = min(myQuery(childs[x][0], rect),
		                myQuery(childs[x][1], rect));
		if(rect.l.y <= key[x].y and key[x].y <= rect.r.y){
			tmp = min(tmp, key[x]);
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(root, point);
	}

	void erase(const Point &point){
		myErase(root, point);
	}

	Point query(const Rect &rect){
		return myQuery(root, rect);
	}

};

int rangeMax;
Treap treaps[maxTreeCnt];

struct Tree{
	inline int myIndex(int l, int r){
		return (l + r) | (l != r);
	}

	void myInsert(int l, int r, const Point &point){
		treaps[myIndex(l, r)].insert(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myInsert(l, m, point);
			}else{
				myInsert(m + 1, r, point);
			}
		}
	}

	void myErase(int l, int r, const Point &point){
		treaps[myIndex(l, r)].erase(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myErase(l, m, point);
			}else{
				myErase(m + 1, r, point);
			}
		}
	}

	Point myQuery(int l, int r, const Rect rect){
		if(rect.l.x <= l and r <= rect.r.x){
			return treaps[myIndex(l, r)].query(rect);
		}
		int m = (l + r) >> 1;
		Point tmp;
		if(rect.l.x <= m){
			tmp = min(tmp, myQuery(l, m, rect));
		}
		if(m < rect.r.x){
			tmp = min(tmp, myQuery(m + 1, r, rect));
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(0, rangeMax, point);
	}

	void erase(const Point &point){
		myErase(0, rangeMax, point);
	}

	Point query(const Rect &rect){
		return myQuery(0, rangeMax, rect);
	}
};

int rectCnt, shotCnt;
Rect rects[N];
Point shots[N];

vector<int> sortedList;

Tree tree;

int result[N];

int main(){
	scanf("%d", &rectCnt);
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].id = i;
		rects[i].read();
		sortedList.pushBack(rects[i].l.x);
		sortedList.pushBack(rects[i].r.x);
	}
	sort(rects, rects + rectCnt);
	scanf("%d", &shotCnt);
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].id = i;
		shots[i].read();
		sortedList.pushBack(shots[i].x);
	}
	sort(sortedList.begin(), sortedList.end());
	sortedList.erase(unique(sortedList.begin(), sortedList.end()), \
	                 sortedList.end());
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].l.x = lowerBound(sortedList.begin(), sortedList.end(),
		               rects[i].l.x) - sortedList.begin();
		rects[i].r.x = lowerBound(sortedList.begin(), sortedList.end(),
		               rects[i].r.x) - sortedList.begin();
	}
	rangeMax = sortedList.size();
	treapCnt = 0;
	lower[0] = INT_MAX;
	upper[0] = INT_MIN;
	priority[0] = INT_MAX;
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].x = lowerBound(sortedList.begin(), sortedList.end(),
		             shots[i].x) - sortedList.begin();
		tree.insert(shots[i]);
	}
	memset(result, 0, sizeof(result));
	for(int i = 0; i < rectCnt; ++ i){
		Point tmp = tree.query(rects[i]);
		if(tmp.id < shotCnt){
			tree.erase(tmp);
			result[tmp.id] = rects[i].id + 1;
		}
	}
	for(int i = 0; i < shotCnt; ++ i){
		printf("%d\n", result[i]);
	}
	return 0;
}


// School Team Contest #2
// Problem G -- Shooting Gallery
#include <vector>
#include <cstdio>
#include <cstring>
#include <climits>
#include <utility>
#include <algorithm>

#define pushBack push_back
#define lowerBound lower_bound

using namespace std;

const int N = 100000;
const int maxTreeCnt = 600000;
const int maxTreapCnt = 2000000;

struct Point{
	int id, x, y;

	Point(){
		id = N;
	}

	bool operator < (const Point &other) const{
		return id < other.id;
	}

	void read(){
		scanf("%d%d", &x, &y);
	}

	bool compareTo(const Point &other) const{
		if(y == other.y){
			return id < other.id;
		}
		return y < other.y;
	}
};

struct Rect{
	int id, z;
	Point l, r;

	bool operator < (const Rect &other) const{
		return z < other.z;
	}

	void read(){
		scanf("%d%d%d%d%d", &l.x, &r.x, &l.y, &r.y, &z);
	}
};

int treapCnt, priority[maxTreapCnt],
    childs[maxTreapCnt][2], lower[maxTreapCnt], upper[maxTreapCnt];
Point null, key[maxTreapCnt], first[maxTreapCnt];

struct Treap{
	int root;

	Treap(){
		root = 0;
	}

	void myUpdate(int x){
		first[x] = min(key[x],
		           min(first[childs[x][0]], first[childs[x][1]]));
		lower[x] = min(key[x].y,
		           min(lower[childs[x][0]], lower[childs[x][1]]));
		upper[x] = max(key[x].y,
		           max(upper[childs[x][0]], upper[childs[x][1]]));
	}

	void myRotate(int &x, int t){
		int y = childs[x][t];
		childs[x][t] = childs[y][1 - t];
		childs[y][1 - t] = x;
		myUpdate(x);
		myUpdate(y);
		x = y;
	}

	void myInsert(int &x, const Point &point){
		if(x){
			int t = key[x].compareTo(point);
			myInsert(childs[x][t], point);
			if(priority[childs[x][t]] < priority[x]){
				myRotate(x, t);
			}
		}else{
			x = ++ treapCnt;
			key[x] = point;
			priority[x] = rand();
			childs[x][0] = childs[x][1] = 0;
		}
		myUpdate(x);
	}

	void myErase(int &x, const Point &point){
		if(point.compareTo(key[x])){
			myErase(childs[x][0], point);
		}else if(key[x].compareTo(point)){
			myErase(childs[x][1], point);
		}else{
			if(childs[x][0] + childs[x][1] == 0){
				x = 0;
				return;
			}
			myRotate(x, priority[childs[x][0]] > priority[childs[x][1]]);
			myErase(x, point);
		}
		myUpdate(x);
	}

	Point myQuery(int x, const Rect &rect){
		if(x == 0 or rect.r.y < lower[x] or upper[x] < rect.l.y){
			return null;
		}
		if(rect.l.y <= lower[x] and upper[x] <= rect.r.y){
			return first[x];
		}
		return min(key[x], min(myQuery(childs[x][0], rect),
		                       myQuery(childs[x][1], rect)));
	}

	void insert(const Point &point){
		myInsert(root, point);
	}

	void erase(const Point &point){
		myErase(root, point);
	}

	Point query(const Rect &rect){
		return myQuery(root, rect);
	}
};

int rangeMax;
Treap treaps[maxTreeCnt];

struct Tree{
	int myIndex(int l, int r){
		return (l + r) | (l != r);
	}

	void myInsert(int l, int r, const Point &point){
		treaps[myIndex(l, r)].insert(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myInsert(l, m, point);
			}else{
				myInsert(m + 1, r, point);
			}
		}
	}

	void myErase(int l, int r, const Point &point){
		treaps[myIndex(l, r)].erase(point);
		if(l < r){
			int m = (l + r) >> 1;
			if(point.x <= m){
				myErase(l, m, point);
			}else{
				myErase(m + 1, r, point);
			}
		}
	}

	Point myQuery(int l, int r, const Rect rect){
		if(rect.l.x <= l and r <= rect.r.x){
			return treaps[myIndex(l, r)].query(rect);
		}
		int m = (l + r) >> 1;
		Point tmp;
		if(rect.l.x <= m){
			tmp = min(tmp, myQuery(l, m, rect));
		}
		if(m < rect.r.x){
			tmp = min(tmp, myQuery(m + 1, r, rect));
		}
		return tmp;
	}

	void insert(const Point &point){
		myInsert(0, rangeMax, point);
	}

	void erase(const Point &point){
		myErase(0, rangeMax, point);
	}

	Point query(const Rect &rect){
		return myQuery(0, rangeMax, rect);
	}
};

int rectCnt, shotCnt;
Rect rects[N];
Point shots[N];

vector<int> sortedList;

Tree tree;

int result[N];

int main(){
	scanf("%d", &rectCnt);
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].id = i;
		rects[i].read();
		sortedList.pushBack(rects[i].l.x);
		sortedList.pushBack(rects[i].r.x);
	}
	sort(rects, rects + rectCnt);
	scanf("%d", &shotCnt);
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].id = i;
		shots[i].read();
		sortedList.pushBack(shots[i].x);
	}
	sort(sortedList.begin(), sortedList.end());
	sortedList.erase(unique(sortedList.begin(), sortedList.end()), \
	                 sortedList.end());
	for(int i = 0; i < rectCnt; ++ i){
		rects[i].l.x = lowerBound(sortedList.begin(), sortedList.end(),
		               rects[i].l.x) - sortedList.begin();
		rects[i].r.x = lowerBound(sortedList.begin(), sortedList.end(),
		               rects[i].r.x) - sortedList.begin();
	}
	rangeMax = sortedList.back();
	treapCnt = 0;
	lower[0] = INT_MAX;
	upper[0] = INT_MIN;
	priority[0] = INT_MAX;
	for(int i = 0; i < shotCnt; ++ i){
		shots[i].x = lowerBound(sortedList.begin(), sortedList.end(),
		             shots[i].x) - sortedList.begin();
		tree.insert(shots[i]);
	}
	memset(result, 0, sizeof(result));
	for(int i = 0; i < rectCnt; ++ i){
		Point tmp = tree.query(rects[i]);
		if(tmp.id < shotCnt){
			tree.erase(tmp);
			result[tmp.id] = i + 1;
		}
	}
	for(int i = 0; i < shotCnt; ++ i){
		printf("%d\n", result[i]);
	}
	return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

struct target{
    int id,xl,xr,yl,yr,z;

    target(){}

    bool operator < (target X)const{
        return z < X.z;
    }
}T[100001];

int prev[100002],nxt[100002];

int main(){
    int n,m;

    scanf("%d",&n);

    for(int i = 1;i <= n;++i){
        scanf("%d %d %d %d %d",&T[i].xl,&T[i].xr,&T[i].yl,&T[i].yr,&T[i].z);
        T[i].id = i;
        prev[i] = i-1; nxt[i] = i+1;
    }

    nxt[0] = 1;

    sort(T,T + n);

    scanf("%d",&m);

    for(int i = 0,j,x,y,ans;i < m;++i){
        scanf("%d %d",&x,&y);
        ans = 0;

        j = nxt[0];

        while(j != n+1){
            if(T[j].xl <= x && x <= T[j].xr && T[j].yl <= y && y <= T[j].yr){
                ans = T[j].id;
                prev[nxt[i]] = prev[i];
                nxt[prev[i]] = nxt[i];
                break;
            }

            j = nxt[j];
        }

        printf("%d\n",ans);
    }

    return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

struct target{
    int id,xl,xr,yl,yr,z;

    target(){}

    bool operator < (target X)const{
        return z < X.z;
    }
}T[100001];

int prev[100002],nxt[100002];

int main(){
    int n,m;

    scanf("%d",&n);

    for(int i = 1;i <= n;++i){
        scanf("%d %d %d %d %d",&T[i].xl,&T[i].xr,&T[i].yl,&T[i].yr,&T[i].z);
        T[i].id = i;
        prev[i] = i-1; nxt[i] = i+1;
    }

    nxt[0] = 1;

    sort(T,T + n);

    scanf("%d",&m);

    for(int i = 0,j,x,y,ans;i < m;++i){
        scanf("%d %d",&x,&y);
        ans = 0;

        j = nxt[0];

        while(j != n+1){
            if(T[j].xl <= x && x <= T[j].xr && T[j].yl <= y && y <= T[j].yr){
                ans = T[j].id;
                prev[nxt[j]] = prev[j];
                nxt[prev[j]] = nxt[j];
                break;
            }

            j = nxt[j];
        }

        printf("%d\n",ans);
    }

    return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

struct target{
    int id,xl,xr,yl,yr,z;

    target(){}

    bool operator < (target X)const{
        return z < X.z;
    }
}T[100001];

int prev[100002],nxt[100002];

int main(){
    int n,m;

    scanf("%d",&n);

    for(int i = 1;i <= n;++i){
        scanf("%d %d %d %d %d",&T[i].xl,&T[i].xr,&T[i].yl,&T[i].yr,&T[i].z);
        T[i].id = i;
    }

    sort(T + 1,T + (n+1));
    nxt[0] = 1;

    for(int i = 1;i <= n;++i){
        nxt[i] = i+1;
        prev[i] = i-1;
    }

    scanf("%d",&m);

    for(int i = 0,j,x,y,ans;i < m;++i){
        scanf("%d %d",&x,&y);
        ans = 0;

        j = nxt[0];

        while(j != n+1){
            if(T[j].xl <= x && x <= T[j].xr && T[j].yl <= y && y <= T[j].yr){
                ans = T[j].id;
                prev[nxt[j]] = prev[j];
                nxt[prev[j]] = nxt[j];
                break;
            }

            j = nxt[j];
        }

        printf("%d\n",ans);
    }

    return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

struct target{
    int id,xl,xr,yl,yr,z;

    target(){}

    bool operator < (target X)const{
        return z < X.z;
    }
}T[100001];

int prev[100002],nxt[100002];

int main(){
    int n,m;

    scanf("%d",&n);

    for(int i = 1;i <= n;++i){
        scanf("%d %d %d %d %d",&T[i].xl,&T[i].xr,&T[i].yl,&T[i].yr,&T[i].z);
        T[i].id = i;
        prev[i] = i-1; nxt[i] = i+1;
    }

    nxt[0] = 1;

    sort(T,T + n);

    scanf("%d",&m);

    for(int i = 0,j,x,y,ans;i < m;++i){
        scanf("%d %d",&x,&y);
        ans = 0;

        j = nxt[0];

        while(j != n+1){
            if(T[j].xl <= x && x <= T[j].xr && T[j].yl <= y && y <= T[j].yr){
                ans = T[j].id;
                prev[nxt[j]] = prev[j];
                nxt[prev[j]] =
                break;
            }

            j = nxt[j];
        }

        printf("%d\n",ans);
    }

    return 0;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}a[123123];

int pt(A a,A b)
{
    return a.z>b.z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",&a[i].xl,&a[i].xr,&a[i].yl ,&a[i].yr,&a[i].z),a[i].id=i;;
    sort(a,a+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=to[k])
        {
            if(x>=a[to[k]].xl&&x<=a[to[k]].xr&&y>=a[to[k]].yl&&y<=a[to[k]].yr)
            {
                fk=a[to[k]].id+1;
                to[k]=to[to[k]];
                break;
            }
        }
        printf("%d\n",fk);

    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}aa[123231],a[123123];
int id[123232];
int pt(int x ,int y)
{
    return aa[x].z>aa[y].z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",&aa[i].xl,&aa[i].xr,&aa[i].yl ,&aa[i].yr,&aa[i].z),aa[i].id=id[i]=i;;
    sort(id,id+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        a[i]=aa[id[i]];
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=to[k])
        {
            if(x>=a[to[k]].xl&&x<=a[to[k]].xr&&y>=a[to[k]].yl&&y<=a[to[k]].yr)
            {
                fk=a[to[k]].id+1;
                to[k]=to[to[k]];
                break;
            }
        }
        printf("%d\n",fk);

    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}a[123123];

int pt(const A& a,const A& b)
{
    return a.z>b.z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",&a[i].xl,&a[i].xr,&a[i].yl ,&a[i].yr,&a[i].z),a[i].id=i;;
    sort(a,a+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=to[k])
        {
            if(x>=a[to[k]].xl&&x<=a[to[k]].xr&&y>=a[to[k]].yl&&y<=a[to[k]].yr)
            {
                fk=a[to[k]].id+1;
                to[k]=to[to[k]];
                break;
            }
        }
        printf("%d\n",fk);

    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}aa[123231],a[123123];
int id[123232];
int pt(int x ,int y)
{
    return aa[x].z>aa[y].z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",&aa[i].xl,&aa[i].xr,&aa[i].yl ,&aa[i].yr,&aa[i].z),aa[i].id=id[i]=i;;
    sort(id,id+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        a[i]=aa[id[i]];
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0,tk;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=tk)
        {
            tk=to[k];
            if(x>=a[tk].xl&&x<=a[tk].xr&&y>=a[tk].yl&&y<=a[tk].yr)
            {
                fk=a[tk].id+1;
                to[k]=to[tk];
                break;
            }
        }
        printf("%d\n",fk);

    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}aa[123231],a[123123];
int id[123232];
int pt(int x ,int y)
{
    return aa[x].z>aa[y].z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",&aa[i].xl,&aa[i].xr,&aa[i].yl ,&aa[i].yr,&aa[i].z),aa[i].id=id[i]=i;;
    sort(id,id+n,pt);
    int to[123121];
    for(int i=0;i<=n;i++)
    {
        a[i]=aa[id[i]];
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0,tk;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=tk)
        {
            tk=to[k];
            if(x>=a[tk].xl&&x<=a[tk].xr&&y>=a[tk].yl&&y<=a[tk].yr)
            {
                fk=a[tk].id+1;
                to[k]=to[tk];
                break;
            }
        }
        printf("%d\n",fk);
    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}a[123123];

int pt(A a,A b)
{
    return a.z>b.z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",a[i].xl,a[i].xr,a[i].yl ,a[i].yr,a[i].z),a[i].id=i;;
    sort(a,a+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=to[k])
        {
            if(x>=a[to[k]].xl&&x<=a[to[k]].xr&&y>=a[to[k]].yl&&y<=a[to[k]].yr)
            {
                fk=a[to[k]].id+1;
                to[k]=to[to[k]];
                break;
            }
        }
        printf("%d\n",fk);

    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}aa[123231],a[123123];
int id[123232];
int pt(int x ,int y)
{
    return a[x].z<a[y].z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        scanf("%d%d%d%d%d",&aa[i].xl,&aa[i].xr,&aa[i].yl ,&aa[i].yr,&aa[i].z),id[i]=i;;
    sort(id,id+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        a[i]=aa[id[i]];
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0;
        scanf("%d %d",&x,&y);
        for(int k=n;to[k]!=-1;k=to[k])
        {
            if(x>=a[to[k]].xl&&x<=a[to[k]].xr&&y>=a[to[k]].yl&&y<=a[to[k]].yr)
            {
                fk=a[to[k]].id+1;
                to[k]=to[to[k]];
                break;
            }
        }
        printf("%d\n",fk);

    }
    cin>>n;
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<string>
#include<ctime>
using namespace std;
struct A{int xl,xr,yl,yr,z,id;}a[123123];

int pt(A a,A b)
{
    return a.z>b.z;
}

int main()
{
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i].xl>>a[i].xr>>a[i].yl >>a[i].yr>>a[i].z,a[i].id=i;;
    sort(a,a+n,pt);
    int to[12312];
    for(int i=0;i<=n;i++)
    {
        to[i]=i-1;
    }
    cin>>m;
    while(m--)
    {
        int x,y,fk=0;
        cin>>x>>y;
        for(int k=n;to[k]!=-1;k=to[k])
        {
            if(x>=a[to[k]].xl&&x<=a[to[k]].xr&&y>=a[to[k]].yl&&y<=a[to[k]].yr)
            {
                fk=a[to[k]].id+1;
                to[k]=to[to[k]];
                break;
            }
        }
        cout<<fk<<'\n';

    }
    cin>>n;
}


#include<cstdio>
#include<algorithm>
using namespace std;
const int nn=100005;
struct mrx{int x1,x2,y1,y2,z,p;}a[nn];
int n,m,l[nn],r[nn];
void read(int &x){
	char ch=getchar();for(;ch<48;ch=getchar());
	for(x=0;ch>=48;ch=getchar())x=x*10+ch-48;
}
inline bool cmp(const mrx &x,const mrx &y){
	return x.z<y.z;
}
int main(){
	read(n);
	for(int i=1;i<=n;++i){
		read(a[i].x1);read(a[i].x2);
		read(a[i].y1);read(a[i].y2);
		read(a[i].z);a[i].p=i;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;++i)l[i]=i-1,r[i]=i+1;
	r[0]=1;l[0]=n;r[n]=0;
	read(m);
	for(int i=1;i<=m;++i){
		int x,y,j=0;
		read(x);read(y);
		for(j=r[0];j;j=r[j])
			if(x>=a[j].x1&&x<=a[j].x2&&y>=a[j].y1&&y<=a[j].y2){
				r[l[j]]=r[j],l[r[j]]=l[j];
				break;
			}
		printf("%d\n",a[j].p);
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
struct point{
  int x1,x2,y1,y2,id,z;
};
int n,m;
int pre[100050],suc[100050];
point a[100050];
bool cmp(point x,point y){
  return x.z<y.z?true:false;
}
int main(){
  scanf("%d",&n);
  for (int i=1;i<=n;i++){
    scanf("%d%d%d%d%d",&a[i].x1,&a[i].x2,&a[i].y1,&a[i].y2,&a[i].z);
    a[i].id=i;
  }
  sort(a+1,a+1+n,cmp);
  for (int i=1;i<=n;i++){
    pre[i]=i-1;suc[i]=i+1;
  }
  scanf("%d",&m);
  int x,y,first=1,j;
  for (;m--;){
    scanf("%d%d",&x,&y);
	for (j=first;j<=n;j=suc[j]){
	  if (x>=a[j].x1 && x<=a[j].x2 && y<=a[j].y2 && y>=a[j].y1) break;
	}
	if (j>n){
	  printf("0\n");
	  continue;
	}
	printf("%d\n",a[j].id);
	if (j==first){
	  first=suc[j];
	  continue;
	}
	pre[suc[j]]=pre[j];
	suc[pre[j]]=suc[j];
  }
  return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i,s,t) for (int i = s; i <= t; ++i)
#define per(i,s,t) for (int i = s; i >= t; --i)
using namespace std;
char ch;
inline void read(int &x){
	for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar());
	for (x = 0; ch >= '0' && ch <= '9'; ch = getchar()) x = x*10+ch-48;
}
struct res{
	int xl, xr, yl, yr, z, id;
	void Read(){
		read(xl); read(xr); read(yl); read(yr); read(z);
	}
}p[100010];
int n, l[100010], r[100010];
inline bool cmp(res A, res B){ return A.z < B.z; }
int main(){
	read(n);
	rep(i,1,n){
		p[i].Read(); p[i].id = i;
	}
	sort(p+1, p+n+1, cmp);
	rep(i,1,n) l[i] = i-1, r[i] = i+1;
	r[0] = 1; r[n] = 0;
	int Q, ans, x, y; read(Q);
	while (Q--){
		ans = 0; read(x); read(y);
		for (int i = r[0]; i; i = r[i])
		if (x >= p[i].xl && x <= p[i].xr && y >= p[i].yl && y <= p[i].yr){
			ans = p[i].id; r[l[i]] = r[i]; l[r[i]] = l[i]; break;
		}
		printf("%d\n", ans);
	}
	return 0;
}