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

public class Tests {
    int testNo = 1;

    class Circle {
        int x;
        int y;
        int r;

        Circle(int x, int y, int r) {
            this.x = x;
            this.y = y;
            this.r = r;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Circle circle = (Circle) o;

            if (r != circle.r) return false;
            if (x != circle.x) return false;
            if (y != circle.y) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = x;
            result = 31 * result + y;
            result = 31 * result + r;
            return result;
        }
    }

    public void printTest(Circle[] c) {
        PrintWriter out = null;
        try {
            new File("tests").mkdir();
            out = new PrintWriter("tests/" + testNo / 10 + testNo % 10);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
            return;
        }

        out.println(c.length);
        for (Circle aC : c) {
            out.println(aC.x + " " + aC.y + " " + aC.r);
        }

        out.close();
        testNo++;
    }


    public void genGrid(int width, int height, int n, int minr, int maxr) {
        Set<Circle> circles = new HashSet<Circle>();
        for (int i = 0; i < n; i++) {
            Circle c;
            do {
                int x = rnd.nextInt(width) * maxr * 2;
                int y = rnd.nextInt(height) * maxr * 2;
                int r = minr + rnd.nextInt(maxr - minr + 1);
                c = new Circle(x, y, r);
            } while (circles.contains(c));
            circles.add(c);
        }
        printTest(circles.toArray(new Circle[circles.size()]));
    }

    boolean intersect(Circle c1, Circle c2) {
        long d = 1L * (c1.x - c2.x) * (c1.x - c2.x) + 1L * (c1.y - c2.y) * (c1.y - c2.y);
        long sr2 = 1L * (c1.r + c2.r) * (c1.r + c2.r);
        if (sr2 <= d) {
            return false;
        }
        long dr2 = 1L * (c1.r - c2.r) * (c1.r - c2.r);
        if (d <= dr2) {
            return false;
        }
        return true;
    }

    public void genRandom(int n, int maxc, int maxr) {
        Set<Circle> circles = new HashSet<Circle>();

        for (int i = 0; i < n; i++) {
            Circle c;
            boolean ok;
            do {
                int x = rnd.nextInt(2 * maxc + 1) - maxc;
                int y = rnd.nextInt(2 * maxc + 1) - maxc;
                int r = 1 + rnd.nextInt(maxr);
                c = new Circle(x, y, r);

                ok = true;
                for (Circle c2 : circles) {
                    if (intersect(c, c2)) {
                        ok = false;
                        break;
                    }
                }
            } while (!ok);
            circles.add(c);
        }
        printTest(circles.toArray(new Circle[circles.size()]));
    }

    public void genFrontGrid(int width, int height, int n, int minr, int maxr) {
        Set<Circle> circles = new HashSet<Circle>();
        for (int i = 0; i < n; i++) {
            Circle c;
            do {
                int x = rnd.nextInt(width) * maxr * 2;
                int y = rnd.nextInt(height) * maxr * 2;
                int r = minr + rnd.nextInt(maxr - minr + 1);
                c = new Circle(x  - (maxr - r), y, r);
            } while (circles.contains(c));
            circles.add(c);
        }
        printTest(circles.toArray(new Circle[circles.size()]));
    }

    public void genBackGrid(int width, int height, int n, int minr, int maxr) {
        Set<Circle> circles = new HashSet<Circle>();
        for (int i = 0; i < n; i++) {
            Circle c;
            do {
                int x = rnd.nextInt(width) * maxr * 2;
                int y = rnd.nextInt(height) * maxr * 2;
                int r = minr + rnd.nextInt(maxr - minr + 1);
                c = new Circle(x  + (maxr - r), y, r);
            } while (circles.contains(c));
            circles.add(c);
        }
        printTest(circles.toArray(new Circle[circles.size()]));
    }

    public void genMixedGrid(int width, int height, int n, int minr, int maxr) {
        Set<Circle> circles = new HashSet<Circle>();
        for (int i = 0; i < n; i++) {
            Circle c;
            do {
                int sx = rnd.nextInt(width);
                int sy = rnd.nextInt(height);
                int x = sx * maxr * 2;
                int y = sy * maxr * 2;
                int r = minr + rnd.nextInt(maxr - minr + 1);
                c = new Circle(x  + ((sx + sy) % 3 - 1) * (maxr - r), y, r);
            } while (circles.contains(c));
            circles.add(c);
        }
        printTest(circles.toArray(new Circle[circles.size()]));
    }

    Random rnd = new Random(5557894629L);

    public void run() {
/*
        printTest(new Circle[]{
                new Circle(2, 2, 2),
                new Circle(2, 2, 1),
                new Circle(5, 2, 1),
                new Circle(5, 5, 2)
        });
*/
        printTest(new Circle[]{
                new Circle(2, 2, 2),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 2),
                new Circle(2, 2, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 3),
                new Circle(2, 2, 2),
                new Circle(2, 2, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 1),
                new Circle(4, 2, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 1),
                new Circle(2, 4, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 2),
                new Circle(1, 2, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 2),
                new Circle(3, 2, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 2),
                new Circle(1, 2, 1),
                new Circle(3, 2, 1),
        });
        printTest(new Circle[]{
                new Circle(2, 2, 3),
                new Circle(0, 2, 1),
                new Circle(4, 2, 1),
                new Circle(2, 0, 1),
                new Circle(2, 4, 1),
        });
        printTest(new Circle[]{
                new Circle(0, 0, 1),
                new Circle(2, 2, 1),
                new Circle(2, 0, 1),
                new Circle(0, 2, 1)
        });
        printTest(new Circle[]{
                new Circle(0, 0, 1000000),
        });
        printTest(new Circle[]{
                new Circle(1000000, 1000000, 1000000),
        });
        printTest(new Circle[]{
                new Circle(1000000, 1000000, 1000000),
                new Circle(1000000, -1000000, 1000000),
                new Circle(-1000000, 1000000, 1000000),
                new Circle(-1000000, -1000000, 1000000),
        });
        genRandom(5, 10, 10);
        genRandom(10, 10, 10);
        genRandom(5, 100, 10);
        genRandom(5, 100, 100);
        genRandom(25, 100, 100);
        genRandom(100, 1000, 100);
        genRandom(1000, 1000, 100);
        genRandom(2000, 1000, 100);
        genRandom(2000, 10000, 1000);
        genRandom(3000, 20000, 1000);
        genRandom(5000, 10000, 1000);
        genRandom(5000, 20000, 10000);

        genGrid(1, 100000, 100000, 1, 1);
        genGrid(100000, 1, 100000, 1, 1);
        genGrid(316, 316, 316*316, 1, 1);
//        genGrid(10, 10, 100000, 1, 1000);
        genGrid(10, 10, 100000, 1, 10000);
        genGrid(100, 100, 100000, 1, 10);
        genGrid(100, 100, 100000, 1, 1000);
        genGrid(10, 100, 100000, 1, 5000);
        genGrid(100, 10, 100000, 1, 5000);
        genGrid(1, 1, 100000, 1, 100000);
        genGrid(1, 1, 100000, 1, 1000000);

        genFrontGrid(10, 10, 100000, 1, 1000);
        genFrontGrid(10, 10, 100000, 1, 10000);
        genFrontGrid(100, 100, 100000, 1, 1000);
        genFrontGrid(1, 1, 100000, 1, 100000);
        genFrontGrid(1, 1, 100000, 1, 1000000);

        genBackGrid(10, 10, 100000, 1, 1000);
        genBackGrid(10, 10, 100000, 1, 10000);
        genBackGrid(100, 100, 100000, 1, 1000);
        genBackGrid(100, 100, 100000, 1, 10000);
        genBackGrid(1, 1, 100000, 1, 100000);
        genBackGrid(1, 1, 100000, 1, 1000000);

        genMixedGrid(10, 10, 100000, 1, 1000);
        genMixedGrid(10, 10, 100000, 1, 10000);
        genMixedGrid(100, 100, 100000, 1, 1000);
        genMixedGrid(100, 100, 100000, 1, 10000);

    }

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