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

public class TestGen {
	public Random rnd = new Random(123);

	final int MAX_N = (int) 1e5;
	final int MAX_X = (int) 1e8;
	final int MAX_DX = (int) 1e3;

	public static void main(String[] args) throws IOException {
		new TestGen().run();
	}

	BufferedReader br;
	StringTokenizer in;
	PrintWriter out;

	public String nextToken() throws IOException {
		while (in == null || !in.hasMoreTokens()) {
			in = new StringTokenizer(br.readLine());
		}
		return in.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	int tNumber;

	class Point implements Comparable<Point> {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Point o) {
			if (x == o.x)
				return Integer.compare(y, o.y);
			return Integer.compare(x, o.x);
		}

		@Override
		public String toString() {
			return "Point [x=" + x + ", y=" + y + "]";
		}

	}

	void print(Point[] a, int[] dx, int[] dy, Point A, Point B)
			throws IOException {
		System.err.println(tNumber);
		if (tNumber < 10) {
			out = new PrintWriter("../tests/0" + tNumber);
		} else {
			out = new PrintWriter("../tests/" + tNumber);
		}
		tNumber++;
		out.println(A.x + " " + A.y + " " + B.x + " " + B.y);
		out.println(a.length);
		for (int i = 0; i < a.length; i++) {
			out.println(a[i].x + " " + a[i].y);
		}
		out.println(dx.length);
		for (int i = 0; i < dx.length; i++) {
			out.println(dx[i] + " " + dy[i]);
		}
		out.close();
	}

	void genSimple() throws IOException {
		Point A = new Point(0, 3);
		Point B = new Point(1, 3);
		Point[] a = new Point[] { new Point(-4, 2), new Point(-5, 2),
				new Point(-5, 1), new Point(-4, 1) };
		int[] dx = new int[] { 6, 2 };
		int[] dy = new int[] { 3, -4 };
		print(a, dx, dy, A, B);

	}

	void genSimple2() throws IOException {
		Point A = new Point(0, 0);
		Point B = new Point(1, 1);
		Point[] a = new Point[] { new Point(1, -2), new Point(3, -2),
				new Point(3, -1), new Point(2, 0), new Point(1, -1) };
		int[] dx = new int[] { -1, 1, -7, 0 };
		int[] dy = new int[] { 1, 1, 0, -20 };
		print(a, dx, dy, A, B);

	}

	int vectMul(Point a, Point b, Point c) {
		return Long.signum((b.x - a.x) * 1L * (c.y - a.y) - (b.y - a.y) * 1L
				* (c.x - a.x));
	}

	Point[] convexHull(Point[] pts) {
		Arrays.sort(pts);
		Point f = pts[0], l = pts[pts.length - 1];
		ArrayList<Point> down = new ArrayList<>();
		ArrayList<Point> up = new ArrayList<>();
		for (int i = 0; i < pts.length; i++) {
			Point cur = pts[i];
			int v = vectMul(f, l, cur);
			if (v >= 0) {
				while (up.size() > 1
						&& vectMul(up.get(up.size() - 2),
								up.get(up.size() - 1), cur) >= 0) {
					up.remove(up.size() - 1);
				}
				up.add(cur);
			}
			if (v <= 0) {
				while (down.size() > 1
						&& vectMul(down.get(down.size() - 2),
								down.get(down.size() - 1), cur) <= 0) {
					down.remove(down.size() - 1);
				}
				down.add(cur);
			}
		}
		Collections.reverse(up);
		down.addAll(up.subList(1, up.size() - 1));
		int shift = rnd.nextInt(down.size());
		Point[] res = new Point[down.size()];
		for (int i = 0; i < res.length; i++) {
			res[i] = down.get((i + shift) % res.length);
		}
		return res;
	}

	final int SMALL_COORDS = 100;

	Point genPoint(int coords) {
		return new Point(rnd.nextInt(coords) - coords / 2, rnd.nextInt(coords)
				- coords / 2);
	}

	void smallRandom(int verticesMax, int movesMax, int coords)
			throws IOException {
		Point[] pts = new Point[3 + rnd.nextInt(verticesMax - 3)];
		for (int i = 0; i < pts.length; i++) {
			pts[i] = genPoint(coords);
		}
		pts = convexHull(pts);
		if (pts.length <= 2) {
			smallRandom(verticesMax, movesMax, coords);
			return;
		}
		int shifts = rnd.nextInt(movesMax + 1);
		int[] dx = new int[shifts];
		int[] dy = new int[shifts];
		for (int i = 0; i < dx.length; i++) {
			Point z = genPoint(coords);
			dx[i] = z.x;
			dy[i] = z.y;
			if (dx[i] == 0 && dy[i] == 0) {
				i--;
			}
		}
		Point A = genPoint(coords), B = genPoint(coords);
		while (A.compareTo(B) == 0) {
			B = genPoint(coords);
		}
		print(pts, dx, dy, A, B);
	}

	void smallRandom2(int verticesMax, int movesMax, int coords)
			throws IOException {
		Point[] pts = new Point[3 + rnd.nextInt(verticesMax - 3)];
		for (int i = 0; i < pts.length; i++) {
			pts[i] = genPoint(coords);
		}
		pts = convexHull(pts);
		if (pts.length <= 2) {
			smallRandom2(verticesMax, movesMax, coords);
			return;
		}
		int shifts = rnd.nextInt(movesMax + 1);
		int[] dx = new int[shifts];
		int[] dy = new int[shifts];
		for (int i = 0; i < dx.length; i++) {
			int id = rnd.nextInt(pts.length);
			dx[i] = pts[(id + 1) % pts.length].x - pts[id].x;
			dy[i] = pts[(id + 1) % pts.length].y - pts[id].y;
			if (dx[i] == 0 && dy[i] == 0) {
				i--;
			}
		}
		Point A = genPoint(coords), B = new Point(A.x, A.y);
		while (A.compareTo(B) == 0) {
			int id = rnd.nextInt(pts.length);
			B.x = A.x + pts[(id + 1) % pts.length].x - pts[id].x;
			B.y = A.y + pts[(id + 1) % pts.length].y - pts[id].y;
		}
		print(pts, dx, dy, A, B);
	}

	void bigRandom(int verticesMax, int movesMax, int coords, int coordsDX)
			throws IOException {
		Point[] pts = new Point[verticesMax];
		double R = coords * (0.9 + rnd.nextDouble() * 0.1);
		for (int i = 0; i < pts.length; i++) {
			double alpha = i * Math.PI * 2 / pts.length;
			int x = (int) (Math.cos(alpha) * R);
			int y = (int) (Math.sin(alpha) * R);
			pts[i] = new Point(x, y);
		}
		pts = convexHull(pts);
		int shifts = rnd.nextInt(movesMax + 1);
		int[] dx = new int[shifts];
		int[] dy = new int[shifts];
		for (int i = 0; i < dx.length; i++) {
			Point z = genPoint(coordsDX);
			dx[i] = z.x;
			dy[i] = z.y;
			if (dx[i] == 0 && dy[i] == 0) {
				i--;
			}
		}
		Point A = genPoint(coords), B = genPoint(coords);
		while (A.compareTo(B) == 0) {
			B = genPoint(coords);
		}
		print(pts, dx, dy, A, B);
	}

	public void generate() throws IOException {
		new File("../tests").mkdir();
		tNumber = 1;
		genSimple();
		genSimple2();
		for (int it = 0; it < 10; it++) {
			smallRandom(4, 4, SMALL_COORDS);
		}
		for (int it = 0; it < 10; it++) {
			smallRandom(10, 10, SMALL_COORDS);
		}
		for (int it = 0; it < 18; it++) {
			smallRandom(1000, 1000, SMALL_COORDS);
		}
		for (int i = 0; i < 20; i++) {
			smallRandom(5, 5, 5);
		}
		for (int i = 0; i < 20; i++) {
			smallRandom2(5, 5, 5);
		}
		for (int i = 0; i < 10; i++) {
			bigRandom(MAX_N, MAX_N, MAX_X, MAX_DX);
		}
	}

	public void run() throws IOException {
		Locale.setDefault(Locale.US);
		generate();
	}
}