import java.io.*;
import java.util.*;

public class TestGen {
    static int nTests = 0;
    static final Random random = new Random(42);

    static class Point {
        public final int x, y;
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
        public int hashCode() {
            return x * 31 + y;
        }
        public boolean equals(Object o) {
            Point p = (Point) o;
            return x == p.x && y == p.y;
        }
    }

    static class Query {
        public final int minX, maxX, minY, maxY;
        public Query(int minX, int maxX, int minY, int maxY) {
            this.minX = Math.min(minX, maxX);
            this.maxX = Math.max(minX, maxX);
            this.minY = Math.min(minY, maxY);
            this.maxY = Math.max(minY, maxY);
        }
    }

    static void write(Collection<Point> points, Collection<Query> queries) throws IOException {
        PrintWriter out = new PrintWriter(String.format("%02d", ++nTests));
        out.println(points.size() + " " + queries.size());
        for (Point p : points) {
            out.println(p.x + " " + p.y);
        }
        for (Query q : queries) {
            out.println(q.minX + " " + q.maxX + " " + q.minY + " " + q.maxY);
        }
        out.close();
    }

    static List<Point> points(int... pts) {
        List<Point> rv = new ArrayList<Point>();
        for (int i = 1; i < pts.length; i += 2) {
            rv.add(new Point(pts[i - 1], pts[i]));
        }
        return rv;
    }

    static List<Query> queries(int... qrs) {
        List<Query> rv = new ArrayList<Query>();
        for (int i = 3; i < qrs.length; i += 4) {
            rv.add(new Query(qrs[i - 3], qrs[i - 2], qrs[i - 1], qrs[i]));
        }
        return rv;
    }

    static void writeCornerCases(int minX, int maxX, int minY, int maxY, int nPoints) throws IOException {
        Set<Point> pts = new HashSet<Point>();
        while (pts.size() < nPoints) {
            pts.add(new Point(random.nextInt(maxX - minX + 1) + minX, random.nextInt(maxY - minY + 1) + minY));
        }
        List<Query> qrs = new ArrayList<Query>();
        for (int lx = minX; lx <= maxX; ++lx) {
            for (int rx = lx; rx <= maxX; ++rx) {
                for (int ly = minY; ly <= maxY; ++ly) {
                    for (int ry = ly; ry <= maxY; ++ry) {
                        qrs.add(new Query(lx, rx, ly, ry));
                    }
                }
            }
        }
        write(pts, qrs);
    }

    static void writeBig(int points, int queries) throws IOException {
        Set<Integer> x = new HashSet<Integer>();
        Set<Integer> y = new HashSet<Integer>();
        while (x.size() < points + 2 * queries) {
            x.add(random.nextInt(2000000001) - 1000000000);
        }
        while (y.size() < points + 2 * queries) {
            y.add(random.nextInt(2000000001) - 1000000000);
        }
        Iterator<Integer> gx = x.iterator();
        Iterator<Integer> gy = y.iterator();
        List<Point> pts = new ArrayList<Point>();
        for (int i = 0; i < points; ++i) {
            pts.add(new Point(gx.next(), gy.next()));
        }
        List<Query> qrs = new ArrayList<Query>();
        for (int i = 0; i < queries; ++i) {
            qrs.add(new Query(gx.next(), gx.next(), gy.next(), gy.next()));
        }
        write(pts, qrs);
    }

    public static void main(String[] args) throws IOException {
        //Sample tests
        write(points(30, 239), queries(13, 42, 11, 100500));
        write(points(0, 0,   2, 0,   0, 2,    2, 2), queries(-1, 3, -1, 3,   1, 5, 1, 5));

        //Some more corner cases
        write(points(30, 239), queries(13, 42, 1111, 100500));
        writeCornerCases(-4, 4, 10, 15, 25);
        writeCornerCases(-10, 9, -5, 5, 40);
        writeCornerCases(-5, 5, -9, 10, 100);

        int[] sizes = {2500, 5000, 10000, 20000, 30000, 50000};
        for (int i : sizes) {
            writeBig(2 * i, i);
            writeBig(2 * i, i);
        }
    }
}
