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

public class Tests {
    private static File dir = new File("../tests");
    private int curTest = 1;
    private static boolean verbose = true;

    private String testName;
    private PrintWriter out;
    private Random r = new Random(5516681322906813814L);
    
    final static int MAX = 1000000000;
    final static int N = 1000;

    public void run() {
        w(1, 7, 7);
        w(3, 8, 2);
        qRow(1, 4);
        qRow(6, 9);
        t();

        w(9, 10, 1);
        qRow(8, 11);
        t();
        
        w(5, 95, 1);
        qRow(4, 9);
        t();
        
        tUniform(3, 6, 1, 11);
        tUniform(5, 10, 1, 101);
        tUniform(N, N, 1, N);

        w(1, 1000, 7);
        qRow(MAX - N + 1, MAX + 1);
        t();
        
        tUniform(N, N, MAX - N + 1, MAX + 1);
        
        w(1, MAX + 1, N);
        qRow(1, 6);
        qRow(MAX - 4, MAX + 1);
        t();
        
        w(1, 8);
        w(MAX - 6, MAX + 1);
        qRow(1, 21);
        qRow(MAX - 19, MAX + 1);
        t();
        
        tUniform(N, N, 1, MAX + 1);
        
        for (int s : new int[]{10, N, MAX / 3}) {
            for (int i = 0; i < N; i++) {
                w(1 + r.nextInt(s), MAX - r.nextInt(s));
            }
            for (int i = 0; i < N / 3; i++) {
                q(1 + r.nextInt(s));
                q(MAX - r.nextInt(s));
                q(s + r.nextInt(MAX - 2 * s));
            }
            t();
        }
    }
    
    void tUniform(int n, int m, int low, int high) {
        for (int i = 0; i < n; i++) {
            int a, b;
            for (;;) {
                a = low + r.nextInt(high - low);
                b = low + 1 + r.nextInt(high - low);
                if (a < b) {
                    break;
                }
            }
            w(a, b);
        }
        for (int i = 0; i < m; i++) {
            q(low + r.nextInt(high - low));
        }
        t();
    }
    
    List<Integer> from = new ArrayList<Integer>();
    List<Integer> to = new ArrayList<Integer>();
    List<Integer> x = new ArrayList<Integer>();
    Set<Integer> q = new TreeSet<Integer>();
    
    void clear() {
        from.clear();
        to.clear();
        x.clear();
        q.clear();
    }
    
    void w(int fromValue, int toValue, int xValue) {
        from.add(fromValue);
        to.add(toValue);
        x.add(xValue);
    }
    
    void w(int fromValue, int toValue) {
        w(fromValue, toValue, 1 + r.nextInt(N));
    }
    
    void q(int qValue) {
        q.add(qValue);
    }
    
    void qRow(int low, int high) {
        for (int i = low; i < high; i++) {
            q(i);
        }
    }
    
    private void t() {
        open();
        out.println(x.size() + " " + q.size());
        for (int i = 0; i < x.size(); i++) {
            out.println(from.get(i) + " " + (to.get(i) - 1) + " " + x.get(i));
        }
        for (int i : q) {
            out.println(i);
        }
        close();
    }

    private void open() {
        try {
            testName = "" + curTest / 10 + curTest % 10;
            out = new PrintWriter(new File(dir, testName));
            if (verbose) { 
                System.out.print("Generating " + testName + "...");
            }
        } catch (IOException e) {
            throw new RuntimeException("Unable to open " + testName + " for writing", e);
        }
    }

    private void close() {
        out.close();
        if (verbose) {
            System.out.println(" done.");
        }
        curTest++;
        clear();
    }

    public static void main(String[] args) {
        Locale.setDefault(Locale.US);
        dir.mkdirs();
        new Tests().run();
    }
}
