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

public class TestGen {

    static int done = 0;

    static final int MAX_N = 100000;
    static final int MAX = 1000000;
    static final int TEST_CASES_NUM = 100;

    static class Road {
        int fr, to;

        public Road(int fr, int to) {
            super();
            this.fr = fr;
            this.to = to;
        }

    }

    static class Test {
        int n, m;
        ArrayList<Road> g;
        int[] a, b, c, d;

        Test(int n, int m) {
            this.n = n;
            this.m = m;
            g = new ArrayList<>();
        }
    }

    static void print(Test t) throws IOException {
        done++;
        System.err.println(done);
        PrintWriter out;
        if (done < 10)
            out = new PrintWriter("../tests/0" + String.valueOf(done));
        else
            out = new PrintWriter("../tests/" + String.valueOf(done));
        out.println(t.n + " " + t.m + " " + t.g.size());
        for (int i = 0; i < t.g.size(); i++) {
            out.println((t.g.get(i).fr + 1) + " " + (t.g.get(i).to + 1));
        }
        out.println(t.a.length);
        for (int i = 0; i < t.a.length; i++) {
            out.println(t.a[i] + " " + t.b[i] + " " + t.c[i] + " " + t.d[i]);
        }
        out.close();
    }

    static Test firstSample() {
        Test res = new Test(1, 1);
        res.g.add(new Road(0, 0));
        res.a = new int[] { 1, 5 };
        res.b = new int[] { 2, 6 };
        res.c = new int[] { 3, 7 };
        res.d = new int[] { 4, 8 };
        return res;
    }

    static Test secondSample() {
        Test res = new Test(4, 5);
        res.g.add(new Road(0, 1));
        res.g.add(new Road(0, 2));
        res.g.add(new Road(3, 4));
        res.a = new int[] { 1, 10, 10, 7 };
        res.b = new int[] { 2, 20, 9, 2 };
        res.c = new int[] { 3, 30, 8, 4 };
        res.d = new int[] { 4, 40, 7, 199 };
        return res;
    }

    final static Random rnd = new Random(13);

    static Test genTest(int n, int m, int maxCnt) {
        Test res = new Test(n, m);
        double coef = rnd.nextDouble();
        int cur = 0;
        for (int i = 0; i < n; i++) {
            if (maxCnt == 0)
                break;
            int last = 0;
            while (rnd.nextDouble() > coef) {
                if (maxCnt == 0 || cur == m)
                    break;
                if (rnd.nextBoolean()) {
                    res.g.add(new Road(i, cur));
                    maxCnt--;
                    last = cur;
                }
                cur++;
            }
            cur = last;
        }
        int testCases = TEST_CASES_NUM;
        res.a = new int[testCases];
        res.b = new int[testCases];
        res.c = new int[testCases];
        res.d = new int[testCases];
        for (int i = 0; i < testCases; i++) {
            res.a[i] = rnd.nextInt(MAX) + 1;
            res.b[i] = rnd.nextInt(MAX) + 1;
            res.c[i] = rnd.nextInt(MAX) + 1;
            res.d[i] = rnd.nextInt(MAX) + 1;
        }
        randomShuffle(res.g);
        return res;
    }

    static Test interesting1(int m, int maxCnt) {
        int n = 2;
        Test res = new Test(n, m);
        double coef = rnd.nextDouble();
        int cur = 0;
        for (int i = 0; i < n; i++) {
            if (maxCnt == 0)
                break;
            int last = -1;
            while (cur <= (m / 2) * (i + 1)) {
                if (maxCnt == 0 || cur == m)
                    break;
                if (true) {
                    res.g.add(new Road(i, cur));
                    maxCnt--;
                    last = cur;
                }
                cur++;
            }
            cur = last;
        }
        int testCases = TEST_CASES_NUM;
        res.a = new int[testCases];
        res.b = new int[testCases];
        res.c = new int[testCases];
        res.d = new int[testCases];
        for (int i = 0; i < testCases; i++) {
            res.a[i] = rnd.nextInt(MAX) + 1;
            res.b[i] = rnd.nextInt(MAX) + 1;
            res.c[i] = rnd.nextInt(MAX) + 1;
            res.d[i] = rnd.nextInt(MAX) + 1;
        }
        randomShuffle(res.g);
        return res;
    }

    static Test interesting2() {
        int n = 1;
        int m = 1;
        Test res = new Test(n, m);
        int testCases = TEST_CASES_NUM;
        res.a = new int[testCases];
        res.b = new int[testCases];
        res.c = new int[testCases];
        res.d = new int[testCases];
        for (int i = 0; i < testCases; i++) {
            res.a[i] = rnd.nextInt(MAX) + 1;
            res.b[i] = rnd.nextInt(MAX) + 1;
            res.c[i] = rnd.nextInt(MAX) + 1;
            res.d[i] = rnd.nextInt(MAX) + 1;
        }
        return res;
    }

    static Test interesting3(int n, int m, int maxCnt) {
        Test res = new Test(n, m);
        int testCases = TEST_CASES_NUM;
        res.a = new int[testCases];
        res.b = new int[testCases];
        res.c = new int[testCases];
        res.d = new int[testCases];
        for (int i = 0; i < testCases; i++) {
            res.a[i] = rnd.nextInt(MAX) + 1;
            res.b[i] = rnd.nextInt(MAX) + 1;
            res.c[i] = rnd.nextInt(MAX) + 1;
            res.d[i] = rnd.nextInt(MAX) + 1;
        }
        int x = rnd.nextInt(testCases);
        long[] w1 = new long[n];
        long[] w2 = new long[m];
        long a = res.a[x];
        long b = res.b[x];
        long c = res.c[x];
        long d = res.d[x];
        w1[0] = a;
        for (int i = 1; i < n; i++) {
            a = w1[i] = (a * b + c) % d;
        }
        for (int i = 0; i < m; i++) {
            a = w2[i] = (a * b + c) % d;
        }
        ArrayList<Road2> roads2 = new ArrayList<>();
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                roads2.add(new Road2(i, j, (int) (w1[i] + w2[j])));
        Collections.sort(roads2);
        for (Road2 v : roads2) {
            if (maxCnt == 0)
                break;
            boolean canAdd = true;
            for (Road r : res.g) {
                if (r.fr < v.fr && r.to > v.to)
                    canAdd = false;
                if (r.fr > v.fr && r.to < v.to)
                    canAdd = false;
            }
            if (canAdd) {
                res.g.add(new Road(v.fr, v.to));
                maxCnt--;
            }
        }
        randomShuffle(res.g);
        return res;
    }

    static class Road2 implements Comparable<Road2> {
        int fr, to;
        int val;

        Road2(int fr, int to, int val) {
            this.fr = fr;
            this.to = to;
            this.val = val;
        }

        @Override
        public int compareTo(Road2 arg0) {
            return -Integer.compare(val, arg0.val);
        }
    }

    public static void main(String[] args) throws IOException {
        new File("../tests").mkdir();
        done = 0;
        print(firstSample());
        print(secondSample());
        for (int i = 0; i < 3; i++) {
            print(genTest(MAX_N, MAX_N, MAX_N));
        }
        for (int i = 0; i < 5; i++) 
            print(interesting3(100, 100, MAX_N));
        for (int i = 0; i < 5; i++) {
            print(genTest(rnd.nextInt(10) + 1, rnd.nextInt(10) + 1, MAX_N));
        }
        for (int i = 0; i < 5; i++) {
            print(genTest(rnd.nextInt(MAX_N) + 1, rnd.nextInt(MAX_N) + 1, MAX_N));
        }
        for (int i = 0; i < 5; i++) {
            print(genTest(rnd.nextInt(100) + 1, rnd.nextInt(100) + 1, MAX_N));
        }
        print(genTest(MAX_N, MAX_N, 5));
        print(interesting1(10, MAX_N));
        print(interesting1(MAX_N, MAX_N));
        print(interesting2());

    }

    static void randomShuffle(ArrayList<Road> g) {
        Road[] tmp = new Road[g.size()];
        for (int i = 0; i < g.size(); i++)
            tmp[i] = g.get(i);
        for (int i = 0; i < g.size(); i++) {
            int xx = rnd.nextInt(i + 1);
            Road r1 = tmp[xx];
            tmp[xx] = tmp[i];
            tmp[i] = r1;
        }
        g.clear();
        for (int i = 0; i < tmp.length; i++)
            g.add(tmp[i]);
    }
}
