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

public class TestGen {
    private static int nt = 0;

    private static boolean isHandMade(int nt) throws IOException {
        File hand = new File(String.format("%02d.t", nt));
        if (hand.exists() && hand.isFile()) {
            File dest = new File(String.format("%02d", nt));
            BufferedReader in = new BufferedReader(new FileReader(hand));
            PrintWriter out = new PrintWriter(dest);
            String line;
            while ((line = in.readLine()) != null) {
                out.println(line);
            }
            out.close();
            in.close();
            return true;
        } else {
            return false;
        }
    }

    private static PrintWriter create() throws IOException {
        while (isHandMade(++nt));
        return new PrintWriter(String.format("%02d", nt));
    }

    private static class Edge {
        public final int source, target;

        Edge(int source, int target) {
            this.source = source;
            this.target = target;
        }
    }

    private static final Random random = new Random(84358925);

    private static void simpleFullGraph(int size, boolean aIsNeighbour, boolean bIsNeighbour, int p) throws IOException {
        PrintWriter out = create();
        List<Edge> edges = new ArrayList<Edge>();
        for (int i = 0; i < size; ++i) {
            for (int j = 0; j < i; ++j) {
                edges.add(new Edge(i, j));
            }
        }
        Collections.shuffle(edges);
        int a = random.nextInt(size);
        int b;
        do {
            b = random.nextInt(size);
        } while (a == b);

        int x = -1;
        for (int i = 0; i < edges.size(); ++i) {
            Edge e = edges.get(i);
            boolean match = aIsNeighbour == (e.source == a || e.target == a) && bIsNeighbour == (e.source == b || e.target == b);
            if (match) {
                x = i;
                if (random.nextBoolean()) {
                    break;
                }
            }
        }
        if (x == -1) {
            throw new IllegalArgumentException("neighbour pattern is impossible to satisfy");
        }

        out.println(size + " " + edges.size() + " " + (a + 1) + " " + (b + 1) + " " + (x + 1) + " " + p);
        for (Edge e : edges) {
            out.println((e.source + 1) + " " + (e.target + 1));
        }
        out.close();
    }

    private static void complexFullGraph(int size, boolean aIsNeighbour, boolean bIsNeighbour, int p) throws IOException {
        PrintWriter out = create();
        List<Edge> edges = new ArrayList<Edge>();
        int extra = 200 - size * (size - 1) / 2;
        for (int i = 0; i < size; ++i) {
            for (int j = 0; j < i; ++j) {
                int extraCount = random.nextInt(extra + 1);
                extra -= extraCount;
                for (int times = extraCount; times >= 0; --times) {
                    edges.add(new Edge(i, j));
                }
            }
        }
        Collections.shuffle(edges);
        int a = random.nextInt(size);
        int b;
        do {
            b = random.nextInt(size);
        } while (a == b);

        int x = -1;
        for (int i = 0; i < edges.size(); ++i) {
            Edge e = edges.get(i);
            boolean match = aIsNeighbour == (e.source == a || e.target == a) && bIsNeighbour == (e.source == b || e.target == b);
            if (match) {
                x = i;
                if (random.nextBoolean()) {
                    break;
                }
            }
        }
        if (x == -1) {
            throw new IllegalArgumentException("neighbour pattern is impossible to satisfy");
        }

        out.println(size + " " + edges.size() + " " + (a + 1) + " " + (b + 1) + " " + (x + 1) + " " + p);
        for (Edge e : edges) {
            out.println((e.source + 1) + " " + (e.target + 1));
        }
        out.close();
    }

    private static void randomGraph(int vertices, int edges) throws IOException {
        int[][] mx = new int[vertices][vertices];
        for (int e = 0; e < edges; ++e) {
            int source = random.nextInt(vertices);
            int target;
            do {
                target = random.nextInt(vertices);
            } while (source == target);
            mx[source][target]++;
            mx[target][source]++;
        }
        int start = 1 + random.nextInt(vertices);
        int finish;
        do {
            finish = 1 + random.nextInt(vertices);
        } while (start == finish);
        int edge = 1 + random.nextInt(edges);
        int p = random.nextInt(999999999) + 2;

        PrintWriter out = create();
        out.println(vertices + " " + edges + " " + start + " " + finish + " " + edge + " " + p);
        for (int i = 0; i < edges; ++i) {
            int source, target;
            do {
                source = random.nextInt(vertices);
                target = random.nextInt(vertices);
            } while (mx[source][target] == 0);
            mx[source][target]--;
            mx[target][source]--;
            out.println((1 + source) + " " + (1 + target));
        }
        out.close();
    }

    public static void main(String[] args) throws IOException {
        simpleFullGraph(3, true, true, 1000000);
        simpleFullGraph(3, false, true, 1000000);
        simpleFullGraph(3, true, false, 100000);

        for (int size = 4; size <= 10; size += 3) {
            simpleFullGraph(size, true,  true,  1000000000);
            simpleFullGraph(size, true,  false, 1000000000);
            simpleFullGraph(size, false, true,  1000000000);
            simpleFullGraph(size, false, false, 1000000000);
        }
        for (int t = 1; t <= 25; t += 4)
        {
            randomGraph(10 + t / 4, 8 * t);
        }
        for (int size = 17; size <= 20; ++size) {
            complexFullGraph(size, true,  true,  1000000000);
            complexFullGraph(size, true,  false, 1000000000);
            complexFullGraph(size, false, true,  1000000000);
            complexFullGraph(size, false, false, 1000000000);
        }
    }
}
