import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

public class TestGen implements Runnable {
    public static final String ENDL = "\r\n";
    int testCount;
    Random random = new Random(1234123);
    private int nodeId;
    private Map<Integer, Node> ids = new HashMap<>();
    private Map<Node, Integer> rids = new HashMap<>();

    void write(String s) {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(String.format("../tests/%02d", ++testCount));
            System.out.println(testCount);
            pw.print(s);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
    }

    String lines(String[] args) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            builder.append(args[i]);
            if (i < args.length - 1) {
                builder.append(ENDL);
            }
        }
        return builder.toString();
    }

    void genSamples() throws IOException {
        write(lines(new String[] {
                "3 4",
                "2 3 2",
                "0 0 1",
                "0 0 5",
        }));
        write(lines(new String[] {
                "1 100",
                "0 0 1"
        }));
        write(lines(new String[] {
                "2 4",
                "0 2 2",
                "0 0 3"
        }));
    }

    void writeTree(int n, Node node) {
        StringBuilder builder = new StringBuilder();
        int rmin = node.right == null ? node.value : min(node.right);
        int t = (node.value + rmin) / 2 + (node.value + rmin) % 2;
        if (t == node.value) t += 2;
        builder.append(n).append(" ").append(t).append(ENDL);
        nodeId = 0;
        ids.clear();
        rids.clear();
        calcIds(node);
        int[] l = new int[n];
        int[] r = new int[n];
        int[] a = new int[n];

        writeLRA(node, l, r, a);

        for (int i = 0; i < n; i++) {
            builder.append(l[i] + 1).append(" ").append(r[i] + 1).append(" ").append(a[i]).append(ENDL);
        }

        write(builder.toString());
    }

    int max(Node node) {
        if (node.right == null) return node.value;
        return max(node.right);
    }

    int min(Node node) {
        if (node.left == null) return node.value;
        return min(node.left);
    }

    private void writeLRA(Node node, int[] l, int[] r, int[] a) {
        if (node == null) return;
        int id = rids.get(node);
        a[id] = node.value;
        Integer lid = rids.get(node.left);
        Integer rid = rids.get(node.right);
        l[id] = lid == null ? -1 : lid;
        r[id] = rid == null ? -1 : rid;
        writeLRA(node.left, l, r, a);
        writeLRA(node.right, l, r, a);
    }

    void writeLeft(int n, int mn, int mx) {
        writeTree(n, genLeft(n, mn, mx));
    }

    void writeRight(int n, int mn, int mx) {
        writeTree(n, genRight(n, mn, mx));
    }

    Node genLeft(int n, int mn, int mx) {
        Set<Integer> keys = getBetterRandomSet(n, mn, mx);

        int[] keysa = new int[keys.size()];
        int pos = 0;
        for (int x : keys) {
            keysa[pos++] = x;
        }

        Arrays.sort(keysa);
        Node cur = new Node(keysa[keysa.length - 1]);
        Node root = cur;
        for (int i = keysa.length - 2; i >= 0; i--) {
            int x = keysa[i];
            cur = cur.left = new Node(x);
        }

        return root;
    }

    Node genRight(int n, int mn, int mx) {
        Set<Integer> keys = getBetterRandomSet(n, mn, mx);

        int[] keysa = new int[keys.size()];
        int pos = 0;
        for (int x : keys) {
            keysa[pos++] = x;
        }

        Arrays.sort(keysa);
        Node cur = new Node(keysa[0]);
        Node root = cur;
        for (int i = 1; i < keysa.length; i++) {
            int x = keysa[i];
            cur = cur.right = new Node(x);
        }

        return root;
    }

    void writeRandomTree(int n, int mn, int mx) {
        writeTree(n, genRandomTree(n, mn, mx));
    }

    void writeRandomTreeMaybeWithAnswer(int n, int mn, int mx) {
        Node node = genTreeMaybeWithAnswer(n, mn, mx);
        writeTree(calcsize(node), node);
    }

    private int calcsize(Node node) {
        if (node == null) return 0;
        return 1 + calcsize(node.left) + calcsize(node.right);
    }

    private void calcIds(Node node) {
        if (node != null) {
            int cur = nodeId++;
            ids.put(cur, node);
            rids.put(node, cur);

            calcIds(node.left);
            calcIds(node.right);
        }
    }

    Node genTreeMaybeWithAnswer(int n, int mn, int mx) {
        Node ans = genRandomTree(n, mn, mx);
        Node revert = revert(ans);
        return revert;
    }

    private Node revert(Node ans) {
        if (ans == null || ans.left == null) return null;
        return new Node(ans.left.value, revert(ans.left), revert(ans.right));
    }

    Node genRandomTree(int n, int mn, int mx) {
        Set<Integer> keys = getRandomSet(n, mn, mx);

        Node res = null;
        for (int key : keys) {
            res = insert(res, key);
        }

        return res;
    }

    private Set<Integer> getRandomSet(int n, int mn, int mx) {
        Set<Integer> keys = new HashSet<>();

        while (keys.size() < n) {
            keys.add(random.nextInt(mx) + mn);
        }
        return keys;
    }

    private Set<Integer> getBetterRandomSet(int n, int mn, int mx) {
        Set<Integer> keys = new HashSet<>();

        while (keys.size() < n) {
            int key = random.nextInt(mx) + mn;
            if (!keys.contains(key - 1) && !keys.contains(key + 1)) {
                keys.add(key);
            }
        }
        return keys;
    }

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

        try {
            genSamples();

            writeRandomTree(3, 1, 1000);
            writeRandomTree(3, 1, 1000);
            writeRandomTree(3, 1, 1000);
            writeRandomTree(4, 1, 1000);
            writeRandomTree(4, 1, 1000);
            writeRandomTree(4, 1, 1000);
            writeRandomTree(4, 1, 1000);
            writeRandomTree(5, 1, 1000);
            writeLeft(10, 1, 1_000_000_000);
            writeLeft(10, 1, 1_000_000_000);
            writeLeft(1000, 1, 1_000_000_000);
            writeLeft(1000, 1, 1_000_000_000);
            writeLeft(100000, 1, 1_000_000_000);
            writeLeft(100000, 1, 1_000_000_000);
            writeRight(10, 1, 1_000_000_000);
            writeRight(10, 1, 1_000_000_000);
            writeRight(1000, 1, 1_000_000_000);
            writeRight(1000, 1, 1_000_000_000);
            writeRight(100000, 1, 1_000_000_000);
            writeRight(100000, 1, 1_000_000_000);
            writeRandomTreeMaybeWithAnswer(15, 1, 1000);
            writeRandomTreeMaybeWithAnswer(15, 1, 1000);
            writeRandomTreeMaybeWithAnswer(100, 1, 1000);
            writeRandomTreeMaybeWithAnswer(100, 1, 100000);
            writeRandomTreeMaybeWithAnswer(100, 1, 100000);
            writeRandomTreeMaybeWithAnswer(100, 1, 1_000_000_000);
            writeRandomTreeMaybeWithAnswer(100000, 1, 1_000_000_000);
            writeRandomTreeMaybeWithAnswer(100000, 1, 1_000_000_000);
            writeRandomTree(10, 1, 1000);
            writeRandomTree(10, 1, 1000);
            writeRandomTree(100, 1, 10000);
            writeRandomTree(1000, 1, 100000);
            writeRandomTree(1000, 1, 100000);
            writeRandomTree(100000, 1, 1000000000);
            writeRandomTree(100000, 1, 1000000000);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        new Thread(null, new TestGen(), "", 1 << 26).start();
    }

    public static final class Node {
        int value;
        Node left, right;

        public Node(int value) {
            this.value = value;
        }

        public Node(int value, Node left, Node right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }

    Node insert(Node n, int value) {
        if (n == null) {
            return new Node(value);
        }

        if (value == n.value) {
            throw new RuntimeException("Equal keys");
        } else if (value < n.value) {
            n.left = insert(n.left, value);
            return n;
        } else {
            n.right = insert(n.right, value);
            return n;
        }
    }
}
