import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;

public class Tests {

    int tests = 1;

    private static int MAX_X = (int) 1e5;
    private static int MAX_Y = (int) 1e3;
    private static int MAX_H = (int) 1e3;
    private static int MAX_N = (int) 1e4;
    private static int MAX_M = (int) 1e4;

    private void myAssert(boolean b) {
        if (!b) throw new RuntimeException();
    }

    public void writeTest(int[] h, int[] x, int[] y, int a) {
        System.out.println("writing test " + tests);
        try {
            if (!new File("tests").exists()) {
                new File("tests").mkdir();
            }
            PrintWriter out = new PrintWriter(String.format("tests/%02d",
                    tests++));

            int n = h.length;
            int m = x.length;
            myAssert(n <= MAX_N);
            myAssert(m <= MAX_M);
            out.println(n + " " + m + " " + a);
            for (int i = 0; i < n; i++) {
                out.print(h[i]);
                myAssert(h[i] >= 1 && h[i] <= MAX_H);
                if (i < n - 1) {
                    out.print(" ");
                } else {
                    out.println();
                }
            }
            for (int i = 0; i < m; i++) {
                out.println(x[i] + " " + y[i]);
                myAssert(x[i] >= -MAX_X && x[i] <= MAX_X);
                myAssert(y[i] >= -MAX_Y && y[i] <= MAX_Y);
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void run() {
        writeTest(new int[]{20, 10, 20, 15, 10}, new int[]{0, 40, 50, 70}, new int[]{10, 20, 0, 30}, 10);

        randomTest(1, 2, 10, 10, 30, 60);
        randomTest(1, 5, 10, 10, 30, 60);
        randomTest(2, 5, 20, 20, 30, 60);
        randomTest(3, 5, 50, 50, 30, 60);
        randomTest(10, 2, 50, 50, 30, 60);
        randomTest(10, 5, 50, 50, 30, 60);
        randomTest(10, 5, 50, 50, 1, 1);
        randomTest(10, 5, 50, 50, 89, 89);

        randomTest(10, 10, 100, 100, 30, 60);
        randomTest(10, 10, 100, 100, 30, 60);
        randomTest(10, 10, 100, 100, 30, 60);

        randomTest(100, 100, 500, 500, 30, 60);
        randomTest(100, 100, 500, 50, 30, 60);
        randomTest(100, 100, 500, 5000, 30, 60);
        randomTest(100, 100, 500, 500, 30, 60);
        randomTest(100, 100, 500, 50, 1, 30);
        randomTest(100, 100, 500, 5000, 1, 30);
        randomTest(100, 100, 500, 500, 1, 30);
        randomTest(100, 100, 500, 50, 60, 90);
        randomTest(100, 100, 500, 5000, 60, 90);

        randomTest(1000, 1000, 10000, 1000, 30, 60);
        randomTest(1000, 1000, 10000, 100, 30, 60);
        randomTest(1000, 1000, 10000, 1000, 30, 60);

        randomTest(MAX_N, MAX_M, MAX_X, MAX_Y, 30, 60);
        randomTest(MAX_N, MAX_M, MAX_X, MAX_Y / 10, 30, 60);
        randomTest(MAX_N, MAX_M, MAX_X / 10, MAX_Y, 30, 60);
        randomTest(MAX_N, MAX_M, MAX_X, MAX_Y, 1, 30);
        randomTest(MAX_N, MAX_M, MAX_X, MAX_Y / 10, 1, 30);
        randomTest(MAX_N, MAX_M, MAX_X / 10, MAX_Y, 1, 30);
        randomTest(MAX_N, MAX_M, MAX_X, MAX_Y, 60, 90);
        randomTest(MAX_N, MAX_M, MAX_X, MAX_Y / 10, 60, 90);
        randomTest(MAX_N, MAX_M, MAX_X / 10, MAX_Y, 60, 90);
    }

    Random random = new Random(144536454674545645L);

    private void randomTest(int n, int m, int ww, int hh, int amin, int amax) {
        int a = amin + random.nextInt(amax - amin + 1);
        int[] h = new int[n];
        int[] x = new int[m];
        int[] y = new int[m];
        for (int i = 0; i < m; i++) {
            x[i] = -ww + random.nextInt(ww + ww + 1);
        }
        for (int i = 0; i < m; i++) {
            if (x[i] < -MAX_X || x[i] > MAX_X) throw new RuntimeException();
        }
        Arrays.sort(x);
        y[0] = -hh + random.nextInt(hh + hh + 1);
        if (y[0] > MAX_Y) y[0] = MAX_Y;
        if (y[0] < -MAX_Y) y[0] = -MAX_Y;
        for (int i = 1; i < m; i++) {
            if (x[i] <= x[i - 1]) x[i] = x[i - 1] + 1;
            int dy = (int) (1L * (x[i] - x[i - 1]) * hh / ww);
            y[i] = y[i - 1] - dy + random.nextInt(dy + dy + 1);
            if (y[i] > MAX_Y) y[i] = MAX_Y;
            if (y[i] < -MAX_Y) y[i] = -MAX_Y;
        }
        assignHeights(h, x, y, a, random.nextBoolean());

        writeTest(h, x, y, a);
    }

    private void assignHeights(int[] h, int[] x, int[] y, int a, boolean overflow) {
        double vx = Math.sin(Math.PI * a / 180);
        double vy = Math.cos(Math.PI * a / 180);
        double minLev = x[0] * vx + y[0] * vy;
        double maxLev = minLev;
        for (int i = 1; i < x.length; i++) {
            maxLev = Math.max(maxLev, x[i] * vx + y[i] * vy);
        }
        int s = (int) ((maxLev - minLev) / vy);
        if (overflow) {
            s += 1 + random.nextInt(s / 10 + 1);
        }
        int n = h.length;
        if (n == 1) {
            h[0] = random.nextInt(s) + 1;
        } else {
            for (int i = 0; i < n - 1; i++) {
                h[i] = 1;
            }
            for (int z = 0; z < s - (n - 1); z++) {
                h[random.nextInt(n - 1)]++;
            }
            int max = h[0];
            for (int i = 1; i < n - 1; i++) {
                max = Math.max(max, h[i]);
            }
            h[n - 1] = max + random.nextInt(max / 10 + 1);
            int i = random.nextInt(n);
            int t = h[i];
            h[i] = h[n - 1];
            h[n - 1] = t;
        }
        for (int i = 0; i < n; i++) {
            if (h[i] > MAX_H) h[i] = MAX_H;
        }
    }

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

}
