import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class TestGen {
	public static void main(String[] args) {
    	
		//multiply of N and TL is 500
    	printTest(getRandom(2, 1, 10, 10, 2, 3, 1, 2, false));
    	printTest(getRandom(3, 3, 10, 10, 1, 4, 1, 4, true));
    	printTest(getRandom(5, 8, 150, 50, 1, 5, 1, 5, true));
    	printTest(getRandom(10, 30, 1000, 50, 15, 30, 1, 10, false));
    	printTest(getRandom(10, 30, 10000, 50, 1500, 3000, 10, 30, false));
    	printTest(getRandom(150, 3000, 10, 3, 1, 10, 1, 2, false));
    	
    	printTest(getRandom(2, 1, 10, 5, 2, 3, 1, 2, true));
    	printTest(getRandom(3, 3, 10, 3, 1, 4, 1, 4, true));
    	printTest(getRandom(5, 8, 150, 40, 1, 5, 1, 5, true));
    	printTest(getRandom(10, 30, 1000, 20, 15, 30, 1, 10, false));
    	printTest(getRandom(10, 30, 10000, 30, 1500, 3000, 10, 30, false));
    	printTest(getRandom(150, 3000, 10, 2, 1, 10, 1, 2, false));
    	
    	//multiply of N and TL is 10000
    	printTest(getRandom(2, 1, 5000, 4999, 1, 2, 1, 2, true));
    	printTest(getRandom(3, 3, 10000, 3000, 1, 3, 1, 10, true));
    	printTest(getRandom(3, 3, 10000, 3000, 30, 50, 100, 200, true));
    	
    	printTest(getRandom(1000, 10000, 500, 10, 10, 20, 1, 5, false));
    	printTest(getRandom(2, 1, 5000, 5000, 1, 2, 10, 20, true));
    	
    	printTest(getRandom(100, 1000, 10000, 100, 1, 100, 50, 100, false));
    	printTest(getRandom(100, 1000, 10000, 100, 1, 100, 1, 50, false));
    	printTest(getRandom(100, 1000, 10000, 100, 1, 20, 1, 100, false));
    	
    }

	static final Random RNG = new Random(58L);

	static Test getRandom(int v, int mm, int cars, int limit, int minCap,
			int maxCap, int minL, int maxL, boolean fl) {
		int m = mm;
		Set<Edge> z = new HashSet<>();
		Edge[] edges = new Edge[m];
		for (int i = 0; i < m; i++) {
			int x, y;
			do {
				if (fl) {
					x = RNG.nextInt(v - 1);
					y = x + RNG.nextInt(v - x);
				} else {
					x = RNG.nextInt(v);
					y = RNG.nextInt(v);
				}
			} while (x == y || !z.add(new Edge(x, y, 0, 0)));
			edges[i] = new Edge(x, y, minCap + RNG.nextInt(maxCap - minCap),
					minL + RNG.nextInt(maxL - minL));
		}
		return new Test(v, cars, limit, edges);
	}

	static Test getRandomAntiBin(int v) {
		int limit = 10000 / v;
		int m = v + v / 3 * 2;
		Set<Edge> z = new HashSet<>();
		Edge[] edges = new Edge[m];
		for (int i = 0; i < m; i++) {
			int x, y;
			do {
				x = RNG.nextInt(v);
				y = RNG.nextInt(v);
			} while (x == y || !z.add(new Edge(x, y, 0, 0)));
			edges[i] = new Edge(x, y, RNG.nextInt(10) + 1, RNG.nextInt(5) + 1);
		}
		return new Test(v, 15000 + RNG.nextInt(100), limit, edges);
	}

	static int testNum;

	static void printTest(Test test) {
		System.err.println("[" + ++testNum + "]");
		try {
			PrintWriter out = new PrintWriter("../tests/" + testNum / 10 + ""
					+ testNum % 10);
			out.println(test.n + " " + test.edges.length + " " + test.k + " "
					+ test.tl);
			for (Edge e : test.edges) {
				out.println(e.from + 1 + " " + (e.to + 1) + " " + e.length
						+ " " + e.cap);
			}
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	static class Edge {
		int from;
		int to;
		int cap;
		int length;

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + from;
			result = prime * result + to;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Edge other = (Edge) obj;
			if (from != other.from)
				return false;
			if (to != other.to)
				return false;
			return true;
		}

		public Edge(int from, int to, int cap, int length) {
			this.from = from;
			this.to = to;
			this.cap = cap;
			this.length = length;
		}

	}

	static class Test {
		int n;
		int k;
		int tl;
		Edge[] edges;

		public Test(int n, int k, int tl, Edge[] edges) {
			this.n = n;
			this.k = k;
			this.tl = tl;
			this.edges = edges;
		}

	}
}
