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

public class TestGen {
    int testCount;
    PrintWriter testsDesc;
    static Random random = new Random(787788);
    static final int MAX_N = 18;
    static final int MAX_C = 1_000_000;

    class Test {
        int a[];
        int b[][];

        Test() {}
        Test(int a[], int b[][]) {
            this.a = a;
            this.b = b;
        }
    }

    Test samples[] = {
            new Test(new int[]{1, 1}, new int[][]{{0, 1, 2}, {1, 0, 3}, {2, 3, 0}}),
            new Test(new int[]{2, 2}, new int[][]{{0, 1, 4, 2, 5}, {1, 0, 2, 6, 6}, {4, 2, 0, 6, 6}, {2, 6, 6, 0, 2}, {5, 6, 6, 2, 0}})
    };

    Test hand[] = {
            new Test(new int[]{1}, new int[][]{{0, 1}, {1, 0}}),
            new Test(new int[]{3}, new int[][]{{0, 5, 5, 1}, {5, 0, 5, 4}, {5, 5, 0, 3}, {1, 4, 3, 0}})
    };

    void write(Test t) throws IOException {
        String path = String.format("../tests/%02d", ++testCount);
        PrintWriter out = new PrintWriter(path);
        out.println((t.b.length - 1) + " " + t.a.length);
        for (int i = 0; i < t.a.length; i++) {
            out.print(t.a[i]);
            if (i + 1 == t.a.length) {
                out.println();
            } else {
                out.print(" ");
            }
        }
        for (int i = 0; i < t.b.length; i++) {
            for (int j = 0; j < t.b[i].length; j++) {
                out.print(t.b[i][j]);
                if (j + 1 == t.b[i].length) {
                    out.println();
                } else {
                    out.print(" ");
                }
            }
        }
        out.close();
        System.out.println(String.format("Test %d is generated", testCount));
    }

    void genHand(Test[] a) throws IOException {
        for (Test test : a) {
            write(test);
        }
    }

    void genMaxTest() throws IOException {
        int n = MAX_N;
        int k = n;
        int a[] = new int[k];
        for (int i = 0; i < k; i++) {
            a[i] = 1;
        }
        int b[][] = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                b[i][j] = i == j ? 0 : MAX_C;
            }
        }
        write(new Test(a, b));
    }

    int[] getPartition(int n, int k) {
        int m = n - 1;
        TreeSet<Integer> set = new TreeSet<>();
        while (set.size() < k - 1) {
            int x = random.nextInt(m);
            set.add(x);
        }
        set.add(m);
        int last = -1;
        Integer b[] = set.toArray(new Integer[set.size()]);
        int a[] = new int[k];
        for (int i = 0; i < b.length; i++) {
            a[i] = b[i] - last;
            last = b[i];
        }
        return a;
    }

    void genOneAnswer(int n, int k) throws IOException {
        int a[] = getPartition(n, k);
        int b[][] = new int[n + 1][n + 1];
        int C = random.nextInt(MAX_C / 4) + MAX_C / 4;
        for (int i = 0; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                int o = C + random.nextInt(C);
                b[i][j] = b[j][i] = o;
            }
            b[i][i] = 0;
        }

        int p[] = new int[n];
        for (int i = 0; i < n; i++) {
            p[i] = i;
            int j = random.nextInt(i + 1);
            int o = p[j];
            p[j] = p[i];
            p[i] = o;
        }

        int sum = 0;
        for (int i = 0; i < k; i++) {
            b[0][p[sum + 0] + 1] = b[p[sum + 0] + 1][0] = random.nextInt(C) + 1;
            b[0][p[sum + a[i] - 1] + 1] = b[p[sum + a[i] - 1] + 1][0] = random.nextInt(C) + 1;
            for (int j = 0; j < a[i] - 1; j++) {
                b[p[sum + j] + 1][p[sum + j + 1] + 1] = b[p[sum + j + 1] + 1][p[sum + j] + 1] = random.nextInt(C) + 1;
            }
            sum += a[i];
        }

        write(new Test(a, b));
    }

    void genRand(int n, int k) throws IOException {
        int a[] = new int[k];
        for (int i = 0; i < k; i++) {
            a[i] = 1;
        }
        for (int i = 0; i < n - k; i++) {
            int x = random.nextInt(k);
            a[x]++;
        }
        int b[][] = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                b[i][j] = b[j][i] = random.nextInt(MAX_C) + 1;
            }
            b[i][i] = 0;
        }
        write(new Test(a, b));
    }

    void run() throws IOException {
        new File("../tests").mkdir();

        genHand(samples);
        genHand(hand);
        genOneAnswer(8, 4);
        genRand(10, 3);
        genRand(12, 9);
        genRand(15, 2);
        genMaxTest();
        genOneAnswer(MAX_N * 2 / 3, MAX_N / 4);
        genOneAnswer(MAX_N - 1, MAX_N / 3);
        genOneAnswer(MAX_N, 1);
        genOneAnswer(MAX_N, MAX_N / 2);
        genOneAnswer(MAX_N, MAX_N - 2);
        genOneAnswer(MAX_N, 3);
        genRand(MAX_N, 1);
        genRand(MAX_N, 2);
        genRand(MAX_N, 3);
        genRand(MAX_N, 5);
        genRand(MAX_N, 11);
    }

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