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

public class TestsGen implements Runnable {
	public static void main(String[] args) {
		if (args.length < 1) {
			for (I = 1; (new File(getName(I) + ".t")).exists(); I++)
				;
		} else {
			I = Integer.parseInt(args[0]);
		}
		new Thread(new TestsGen()).start();
	}

	PrintWriter out;

	Random rand = new Random(6439586L);

	static int I;

	static String getName(int i) {
		return ((i < 10) ? "0" : "") + i;
	}

	void open() {
		try {
			System.out.println("Generating test " + I);
			out = new PrintWriter(getName(I));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	void close() {
		out.close();
		I++;
	}
	
	final String ALPHA = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	final String TRASH = getTrash();
	
	String getTrash() {
		String ans = "";
		for (int i = 32; i <= 126; ++i) {
			if (ALPHA.indexOf((char)i) == -1) {
				ans += (char)i;
			}
		}
		return ans;
	}
	
	String randString(int len, String alpha) {
		StringBuilder ans = new StringBuilder();
		int k = alpha.length();
		for (int i = 0; i < len; i++) {
			ans.append(alpha.charAt(rand.nextInt(k)));
		}
		return ans.toString();
	}


	long rand(long l, long r) {
		return l + (rand.nextLong() >>> 1) % (r - l + 1);
	}

	int rand(int l, int r) {
		return l + rand.nextInt(r - l + 1);
	}
	
	String getDate(int i) {
		return (i / 60 < 10 ? "0" : "") + i / 60 + ":" + (i % 60 < 10 ? "0" : "") + i % 60;
	}

	String invert(String s) {
		if (s.length() == 0) return s;
		if (Character.isLowerCase(s.charAt(0))) {
			return Character.toUpperCase(s.charAt(0)) + s.substring(1);
		} else {
			return Character.toLowerCase(s.charAt(0)) + s.substring(1);
		}
	}
	
	HashSet<String> getWords(int n, int ml) {
		HashSet<String> ans = new HashSet<String>();
		while (ans.size() < n) {
			String s = randString(rand(1, ml), ALPHA); 
			if (!ans.contains(invert(s))) {
				ans.add(s);
			}
		}
		return ans;
	}
	
	char getTrashCharacter() {
		return TRASH.charAt(rand(0, TRASH.length() - 1));
	}
	
	String getText(String[] dict, double termp, double trashp) {
		String ans = new  String();
		while (ans.length() < MAXSL) {
			if (rand.nextDouble() < termp) break;
			if (rand.nextDouble() < trashp) {
				ans += getTrashCharacter();
			} else {
				String as = dict[rand(0, dict.length - 1)] + getTrashCharacter();
				if (rand.nextBoolean()) {
					as = invert(as);
				}
				ans += as;
			}
		}
		if (ans.length() > MAXSL) {
			return ans.substring(0, MAXSL);
		} else {
			return ans;
		}
	}
	
		
	void genTest(int n, int m, int ml, double termp, double trashp) {
		HashSet<String> dict = getWords(m, ml);
		String[][] head = new String[n][];
		String[] da = dict.toArray(new String[dict.size()]);
		int k = 0;
		for (int i = 0; i < n; ++i) {
			head[i] = new String[rand(1, MAXSYN + 1)];
			for (int j = 0; j < head[i].length; ++j) {
				head[i][j] = da[k++];
			}
		}
		
		open();
		out.println(n);
		for (int i = 0; i < n; ++i) {
			out.println(head[i][0]);
			out.println(head[i].length - 1);
			for (int j = 1; j < head[i].length; ++j) {
				out.println(head[i][j]);
			}
			int l = rand(1, MAXCOL);
			out.println(l);
			for (int j = 0; j < l; ++j) {
				out.println(getText(da, termp, trashp));
			}
		}
		
		close();
	}
	
	void genRandTest(int maxn, int maxwl) {
		int n = rand(2, maxn);
		int m = 100 * n;
		if (rand.nextBoolean()) {
			m = 11 * n;
		}
		int minl = 1;
		int tm = m / (ALPHA.length() / 2);
		while (tm > 0) {
			tm /= ALPHA.length();
			++minl;
		}
		genTest(n, m, rand(minl, maxwl), rand.nextDouble() / 10, rand.nextDouble());
	}
	
	final int MAXN = 50;
	final int MAXSYN = 10;
	final int MAXCOL = 10;
	final int MAXSL = 80;
	final int MAXWL = 20;
	
	
	
	public void solve() throws IOException {
		for (int i = 0; i < 10; ++i) {
			genRandTest(2, 5);
		}
		for (int i = 0; i < 30; ++i) {
			genRandTest(MAXN, MAXWL);
		}
		for (int i = 0; i < 10; ++i) {
			int n = MAXN;
			int m = 100 * n;
			if (rand.nextBoolean()) {
				m = 11 * n;
			}
			genTest(n, m, MAXWL, rand.nextDouble() / 10, rand.nextDouble());
		}
		genTest(MAXN, 11 * MAXN, MAXWL, 1, 1);
		genTest(MAXN, 11 * MAXN, MAXWL, 1, 0);
		genTest(MAXN, 11 * MAXN, MAXWL, 0, 1);
		genTest(MAXN, 11 * MAXN, MAXWL, 0, 0);
		genTest(MAXN, 100 * MAXN, MAXWL, 0, 0);
	}
	
	public void run() {
		try {
			solve();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}
}