use std::fmt;

mod utils {
    use std::io::stdin;

    /// TODO: use generics
    pub fn read_line() -> Result<Vec<i32>, String> {
        let mut line = String::new();
        stdin().read_line(&mut line).ok();
        line.split_whitespace()
            .map(|x| {
                x.parse::<i32>()
                    .map_err(|err| format!("Error at read_numbers(): {:?}", err.to_string()))
            })
            .collect()
    }

    pub fn read_n_lines(n: usize) -> Result<Vec<Vec<i32>>, String> {
        (0..n).map(|_| read_line()).collect()
    }
}

type NodeId = usize;
type PointId = usize;

#[derive(Debug, Clone)]
struct Point {
    x: i32,
    y: i32,
    id: usize,
}

#[derive(Debug)]
struct Node {
    location: PointId,
    left: Option<NodeId>,
    right: Option<NodeId>,
}

struct KDTree {
    nodes: Vec<Node>,
    points: Vec<Point>,
    i_point: PointId,
    result_find: Vec<usize>,
}

impl KDTree {
    fn make_tree(&mut self, left: NodeId, right: NodeId, depth: usize) -> Option<NodeId> {
        if left >= right {
            return None;
        }

        self.sort_points(left, right, depth % 2);

        let middle: NodeId = (left + right) / 2;
        let t = self.i_point;
        self.i_point += 1;

        self.nodes[t].location = middle as PointId;
        self.nodes[t].left = self.make_tree(left, middle, depth + 1);
        self.nodes[t].right = self.make_tree(middle + 1, right, depth + 1);

        Some(t)
    }

    fn sort_points(&mut self, left: NodeId, right: NodeId, axis: usize) -> () {
        let mut points_with_index: Vec<Point> = self.points[left..right].to_vec();
        points_with_index.sort_by(|p1, p2| {
            if axis == 0 {
                p1.x.cmp(&p2.x)
            } else {
                p1.y.cmp(&p2.y)
            }
        });

        //self.points.splice(left..right, points_with_index);
        for (i, p) in points_with_index.iter().enumerate() {
            self.points[i + left] = Point { ..*p };
        }
    }

    fn find(&mut self, sx: i32, tx: i32, sy: i32, ty: i32) -> () {
        self.result_find.clear();
        self.result_find.reserve(20_000);
        self.find_rec(0, sx, tx, sy, ty, 0);
        self.result_find.sort();
    }

    fn find_rec(&mut self, i_node: NodeId, sx: i32, tx: i32, sy: i32, ty: i32, depth: usize) -> () {
        let i_point = self.nodes[i_node].location;
        let left = self.nodes[i_node].left;
        let right = self.nodes[i_node].right;
        let p = self.points[i_point].clone();

        if sx <= p.x && p.x <= tx && sy <= p.y && p.y <= ty {
            self.result_find.push(p.id);
            // println!("{}: {:?}", i_point, p);
        }

        let mut find = |pos| self.find_rec(pos, sx, tx, sy, ty, depth + 1);

        if depth % 2 == 0 {
            if left.is_some() && sx <= p.x {
                find(left.unwrap());
            }
            if right.is_some() && p.x <= tx {
                find(right.unwrap());
            }
        } else {
            if left.is_some() && sy <= p.y {
                find(left.unwrap());
            }
            if right.is_some() && p.y <= ty {
                find(right.unwrap());
            }
        }
    }
}

impl fmt::Debug for KDTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let nodes_str = self.nodes
            .iter()
            .map(|node| format!("    {:?}", node))
            .collect::<Vec<String>>()
            .join("\n");
        write!(f, "KDTree {{\n  nodes:\n{}\n}}", nodes_str)
    }
}

fn solve() -> Result<(), String> {
    let n = utils::read_line()?[0] as usize;
    let coords = utils::read_n_lines(n)?;
    let q = utils::read_line()?[0] as usize;
    let queries = utils::read_n_lines(q)?;

    let points = coords
        .iter()
        .enumerate()
        .map(|(i, c)| Point {
            x: c[0],
            y: c[1],
            id: i,
        })
        .collect::<Vec<Point>>();
    let nodes = coords
        .iter()
        .map(|_| Node {
            location: 0,
            left: None,
            right: None,
        })
        .collect();

    let mut kdtree = KDTree {
        nodes: nodes,
        points: points,
        i_point: 0,
        result_find: vec![],
    };
    kdtree.make_tree(0, n, 0);

    for q in queries.iter() {
        kdtree.find(q[0], q[1], q[2], q[3]);
        // for x in kdtree.result_find.iter() {
        //     println!("{}", x);
        // }
        if kdtree.result_find.len() > 0 {
            print!(
                "{}",
                kdtree
                    .result_find
                    .iter()
                    .map(|x| format!("{}", x))
                    .collect::<Vec<_>>()
                    .join("\n")
            );
            println!();
        }
        println!();
    }

    Ok(())
}

fn main() {
    match solve() {
        Err(err) => panic!("Error at solve(): {}", err),
        _ => (),
    };
}



Measured memory_bytes: 62220