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




public class TestGen {

    static private class Group {
        public int[] workers;
        public int n;
        public Group(int n, int[] w) {
            workers = w;
            this.n = n;
        }
        
        public void add(int t) {
            int[] nw = new int[n + 1];
            for (int i = 0; i < n; ++i)
                nw[i] = workers[i];
            nw[n] = t;
            ++n;
            workers = nw;
        }

        @Override
        public String toString() {
            String ans = "" + n;
            for (int i = 0; i < n; i++)
                ans = ans + " " + workers[i];
            return ans;         
        }
    }
    
    
    static PrintWriter out;
    static Random rnd = new Random(0);
    static int tNumber;
    
    static void printTest(Group[] g) throws IOException {
        if (tNumber < 10)
            out = new PrintWriter("../tests/0" + tNumber);
        else
            out = new PrintWriter("../tests/" + tNumber);
        tNumber++;
        int n = g.length;
        int k = 0;
        for (int i = 0; i < n; i++)
            k += g[i].n;
        out.println(n + " " + k);
        for (int i = 0; i < n; i++) {                
            out.print(g[i].n);
            for (int j = 0; j < g[i].n; j++)
                out.print(" " + Math.min(10000000, g[i].workers[j]));
            out.println();
        }
        out.close();
    }
    
    static void genSample() throws FileNotFoundException {
        out = new PrintWriter("../tests/01");               
        out.println("3 8");
        out.println("3 1 2 3");
        out.println("2 6 1");
        out.println("3 1 3 5");
        out.close();        
        
    }
    
    static int randFromTo(int l, int r) {
        return rnd.nextInt(r - l + 1) + l;      
    }
    

    static Group genRandomGroup(int n, int mn, int mx) {
        int[] w = new int[n];
        for (int i = 0; i < n; ++i) 
            w[i] = randFromTo(mn, mx);
        return new Group(n, w);
    }

    static int[] getPartition(int n, int k) {
        if (k > n) {
            int[] l = new int[k - n];
            for (int i = 0; i < k - n; i++)
                l[i] = 0;
            int[] r = getPartition(n, n);
            int[] arr = new int[k];
            for (int i = 0; i < l.length; i++)
                arr[i] = l[i];
            for (int i = 0; i < r.length; i++)
                arr[i + l.length] = r[i];
            return arr;                         
        }
        //System.out.println(n + " " + k);      
        if (k == 0)
            return new int[]{};
        if (k == 1)
            return new int[]{n};        
        int t = randFromTo(1, n - 1);
        int nk = randFromTo(Math.max(1, k + t - n), Math.min(k - 1, t));

        int[] l = getPartition(t, nk);
        
        int[] r = getPartition(n - t, k - nk);

        int[] arr = new int[k];
        for (int i = 0; i < l.length; i++)
            arr[i] = l[i];
        for (int i = 0; i < r.length; i++)
            arr[i + l.length] = r[i];
        return arr;        
    }


    static Group[] goodSetOfGroups(int n, int k, int mn, int mx) {
        int[] cnts = getPartition(k - n, n);
        int[] sp = new int[n];
        for (int i = 0; i < n; ++i) 
            sp[i] = randFromTo(mn * cnts[i] + 1, mx * cnts[i] + 1);
        Group[] ans = new Group[n];
        for (int i = 0; i < n; ++i) {
            ans[i] = new Group(cnts[i], getPartition(randFromTo(cnts[i], sp[i]), cnts[i]));
        }
        shuffleArray(sp);
        for (int i = 0; i < n; ++i) {
            ans[i].add(sp[i]);
            shuffleArray(ans[i].workers);
        }
        return ans;
    }
    
    static void shuffleArray(int[] ar) {
        for (int i = ar.length - 1; i > 0; i--) {
            int index = rnd.nextInt(i + 1);
            int a = ar[index];
            ar[index] = ar[i];
            ar[i] = a;
        }
    }
    int[] merge(int[] a, int[] b) {
        int[] ans = new int[a.length + b.length];
        for (int i = 0; i < a.length; i++)
            ans[i] = a[i];

        for (int i = 0; i < b.length; i++)
            ans[i + a.length] = b[i];
        return ans;
    }

    
    static Group[] genA(int n, int k, int mn, int mx) {
        Group[] t = new Group[n];
        int[] pt = getPartition(k, n);
        for (int i = 0; i < n; ++i)
            t[i] = genRandomGroup(pt[i], mn, mx);
        return t;
    }

    static Group[] genC(int n, int k, int mn, int mx) {
        return goodSetOfGroups(n, k, mn, mx);
    }

    static Group[] genB(int n, int k, int mn, int mx) {
        int r = randFromTo(1, n / 2);
        int y = randFromTo(r, k + r - n);
        Group[] t = genA(n - r, k - y, mn, mx);
        Group[] o = genC(r, y, mn, mx);
        Group[] ans = new Group[n];
        for (int i = 0; i < t.length; i++)
            ans[i] = t[i];
        for (int i = 0; i < o.length; i++)
            ans[i + t.length] = o[i];       
        return ans;
    }

    
    public static void main(String[] args) throws IOException {
        genSample();
        tNumber = 2;
        for (int i = 0; i < 5; ++i) {            
            printTest(genA(5, randFromTo(10, 20), 1, 1000));
            printTest(genB(5, randFromTo(10, 20), 1, 1000));
            printTest(genC(5, randFromTo(10, 20), 1, 1000));
        }
        for (int i = 0; i < 5; ++i) {            
            printTest(genA(randFromTo(7, 10), randFromTo(20, 40), 1, 100000));
            printTest(genB(randFromTo(7, 10), randFromTo(20, 40), 1, 100000));
            printTest(genC(randFromTo(7, 10), randFromTo(20, 40), 1, 100000));
        }       
        for (int i = 0; i < 5; ++i) {            
            printTest(genA(randFromTo(10, 13), randFromTo(40, 50), 1, 10000000));
            printTest(genB(randFromTo(10, 13), randFromTo(40, 50), 1, 10000000));
            printTest(genC(randFromTo(10, 13), randFromTo(40, 50), 1, 10000000));
        }
        for (int i = 0; i < 5; ++i) {            
            printTest(genA(15, randFromTo(45, 50), 1, 10000000));
            printTest(genB(15, randFromTo(45, 50), 1, 10000000));
            printTest(genC(15, randFromTo(45, 50), 1, 10000000));
        }        
    }
}
