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

public class TestsGen {
	static int testcount = 0;

	static Random random = new Random(2837542);
	
	static int MAXN = 100000;
	static int MAX = (int) 1e9;
	
	static class Point implements Comparable<Point> {
		int x, y;
		boolean isUp;
		
		public Point(int x2, int y2, boolean nextBoolean) {
			x = x2;
			y = y2;
			isUp = nextBoolean;
		}
		
		@Override
		public String toString() {
			return (isUp ? "U" : "F") + " " + x + " " + y;
		}

		@Override
		public int compareTo(Point o) {
			if (x < o.x) return -1;
			if (x > o.x) return 1;
			if (y < o.y) return -1;
			if (y > o.y) return 1;
			if (isUp != o.isUp) {
				return isUp ? -1 : 1;
			}
			return 0;
		}
	}

	static void write(Point[] a, int d, int l) throws IOException {
		PrintWriter out = new PrintWriter(String.format("%02d", ++testcount));
		System.out.println("Generating test #" + testcount);
		out.println(a.length + " " + d + " " + l);
		for (int i = 0; i < a.length; i++) {
			out.println(a[i]);
		}
		out.close();
	}
	
	static double dist(double x1, double y1, double x2, double y2) {
		return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	}
	
	static double eps = 1e-9;
	
	static void writeYes(int n, int d, int l) throws IOException {
		double pos = random.nextDouble() * (l - d) + d / 2.0;
		Point[] p = new Point[n];
		TreeSet<Point> ts = new TreeSet<Point>();
		for (int i = 0; i < n; i++) {
			int x = random.nextInt(l + 1);
			int y = random.nextInt(d + 1);
			boolean b = random.nextBoolean();
			Point pp = new Point(x, y, b);
			while (dist(x, y, pos, d / 2.0) < d / 2.0 - eps || ts.contains(pp)) {
				x = random.nextInt(l + 1);
				y = random.nextInt(d + 1);
				b = random.nextBoolean();
				pp = new Point(x, y, b);
			}
			ts.add(pp);
			p[i] = pp;
		}
		write(p, d, l);
	}
	
	static void writeMax(int d, int l) throws IOException {
		double pos = random.nextDouble() * (l - d) + d / 2.0;
		ArrayList<Point> al = new ArrayList<Point>();
		for (int x = 0; x <= l ; x++) {
			for (int y = 0; y <= d; y++) {
				for (int bb = 0; bb < 2; bb++) {
					boolean b = false;
					if (bb == 0) {
						b = true;
					}
					if (dist(x, y, pos, d / 2.0) > d / 2.0 - eps) {
						al.add(new Point(x, y, b));
					}
				}
			}
		}
		Collections.shuffle(al, random);
		write(al.toArray(new Point[al.size()]), d, l);
	}
	
	static void writeRand(int n, int d, int l) throws IOException {
		Point[] p = new Point[n];
		TreeSet<Point> ts = new TreeSet<Point>();
		for (int i = 0; i < n; i++) {
			int x = random.nextInt(l + 1);
			int y = random.nextInt(d + 1);
			boolean b = random.nextBoolean();
			Point pp = new Point(x, y, b);
			while (ts.contains(pp)) {
				x = random.nextInt(l + 1);
				y = random.nextInt(d + 1);
				b = random.nextBoolean();
				pp = new Point(x, y, b);
			}
			ts.add(pp);
			p[i] = pp;
		}
		write(p, d, l);
	}
	
	static void writeNo(int n, int d, int l) throws IOException {
		double pos = random.nextDouble() * (l - d) + d / 2.0;
		ArrayList<Point> p = new ArrayList<Point>();
		TreeSet<Point> ts = new TreeSet<Point>();
		for (int i = 0; i < n - 1; i++) {
			int x = random.nextInt(l + 1);
			int y = random.nextInt(d + 1);
			boolean b = random.nextBoolean();
			Point pp = new Point(x, y, b);
			while (dist(x, y, pos, d / 2.0) < d / 2.0 - eps || ts.contains(pp)) {
				x = random.nextInt(l + 1);
				y = random.nextInt(d + 1);
				b = random.nextBoolean();
				pp = new Point(x, y, b);
			}
			ts.add(pp);
			p.add(pp);
		}
		{
			int x = random.nextInt(l + 1);
			int y = random.nextInt(d + 1);
			while (dist(x, y, pos, d / 2.0) > d / 2.0 - eps) {
				x = random.nextInt(l + 1);
				y = random.nextInt(d + 1);
			}
			p.add(new Point(x, y, random.nextBoolean()));
		}
		Collections.shuffle(p, random);
		write(p.toArray(new Point[n]), d, l);
	}
	
	public static void main(String[] args) throws IOException {
		while (new File(String.format("%02d.t", testcount + 1)).exists()) {
			testcount++;
		}
		writeYes(10, 3, 10);
		writeRand(10, 4, 8);
		writeNo(10, 3, 12);
		writeMax(5, 20);
		writeYes(MAXN, MAX / 2, MAX);
		writeYes(MAXN, MAX, MAX);
		writeYes(MAXN, 2 * MAXN, MAX);
		writeNo(MAXN, MAX / 2, MAX);
		writeNo(MAXN, MAX, MAX);
		writeNo(MAXN, 2 * MAXN, MAX);
		writeRand(MAXN, MAX / 2, MAX);
		writeRand(MAXN, MAX, MAX);
		writeRand(MAXN, 2 * MAXN, MAX);
		writeMax(100, 200);
		writeMax(100, 500);
	}

}
