#include <bits/stdc++.h>
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(c) begin(c), end(c)
#define dump(x) std::cerr << __LINE__ << ":\t" #x " = " << (x) << std::endl

const int D = 2;
using value_t = int;
using dat_t = std::array<value_t, D>;

struct node {
    const dat_t *key;
    dat_t min, max;
    int size;

    node *left, *right;
};

node *make_tree(const dat_t **left, const dat_t **right, int d){
    d %= D;

    int sz = right - left;
    if(sz <= 0) return nullptr;

    node *res = new node;
    for(int d = 0; d < D; ++d){
        res->min[d] = std::numeric_limits<int>::max();
        res->max[d] = std::numeric_limits<int>::min();
        for(auto i = left; i != right; ++i){
            res->min[d] = std::min(res->min[d], (**i)[d]);
            res->max[d] = std::max(res->max[d], (**i)[d]);
        }
    }

    sort(left, right, [d](const dat_t *a, const dat_t *b){
            return (*a)[d] < (*b)[d];
        });
    res->key = left[sz/2];

    if(sz > 1){
        res->left = make_tree(left, left + sz/2, d + 1);
        res->right = make_tree(left + sz/2 + 1, right, d + 1);
    } else {
        res->left = nullptr;
        res->right = nullptr;
    }
    res->size = sz;
    return res;
}

node *make_tree(const dat_t *left, const dat_t *right){
    static const dat_t *ptr[500010];
    int sz = right - left;
    for(auto i = left; i != right; ++i) ptr[i - left] = i;
    return make_tree(ptr, ptr + sz, 0);
}

void range_query(const node *n, const dat_t &min, const dat_t &max,
                 std::vector<std::pair<const dat_t*, const node*>> &ans){
    if(n == nullptr) return;

    int overwrap = 2;
    // for(int d = 0; d < D; ++d){
    //     dump(n->min[d]);
    //     dump(n->max[d]);
    // }

    // dump(min[0]);
    // dump(max[0]);
    // dump(min[1]);
    // dump(max[1]);

    for(int d = 0; d < D; ++d){
        if(n->max[d] < min[d] || max[d] < n->min[d]){
            overwrap = 0;
            break;
        } else if(!(min[d] <= n->min[d] && n->max[d] <= max[d])){
            overwrap = 1;
        }
    }

    // dump(overwrap);

    if(overwrap == 0){
        ;
    } else if(overwrap == 1){
        bool inner = true;
        for(int d = 0; d < D; ++d){
            if(!(min[d] <= (*n->key)[d] && (*n->key)[d] <= max[d])){
                inner = false;
                break;
            }
        }
        if(inner) ans.emplace_back(n->key, nullptr);
        range_query(n->left, min, max, ans);
        range_query(n->right, min, max, ans);
    } else {
        ans.emplace_back(nullptr, n);
    }
}

using namespace std;
dat_t ps[500010];

int main(){
    int n;
    cin >> n;
    for(int i = 0; i < n; ++i){
        cin >> ps[i][0] >> ps[i][1];
    }
    node *root = make_tree(ps, ps + n);

    int q;
    cin >> q;
    for(int i = 0; i < q; ++i){
        dat_t min, max;
        cin >> min[0] >> max[0] >> min[1] >> max[1];
        vector<pair<const dat_t*, const node*>> res;
        range_query(root, min, max, res);
        vector<const dat_t*> ans;
        for(auto &p : res){
            if(p.first != nullptr){
                ans.push_back(p.first);
            } else if(p.second != nullptr){
                stack<const node*> stk;
                stk.push(p.second);
                while(stk.size()){
                    auto c = stk.top();
                    stk.pop();
                    if(c == nullptr) continue;
                    ans.push_back(c->key);
                    stk.push(c->left);
                    stk.push(c->right);
                }
            } else {
                assert(false);
            }
        }
        sort(ans.begin(), ans.end());
        for(auto &p : ans){
            cout << p - ps << '\n';
        }
        cout << '\n';
    }
}

Measured memory_bytes: 41192