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

public class DescentPermutation {
	public static int threshold;
	public static int[] prev;
	public static int[] values;
	public static int[] next;
	public static int tries;
	public static int temp;
	public static int fails = 0;
	public static int curfail;
	public static int[] res;
	public static int[][] conditions;
	public static Random r = new Random();

	public static void main(String[] args) {
		for (int i = 1; i < 2000; i++) {
			if ((isGood(i) || i <= 343) && !(i == 2 || i == 3 || i == 5 || i == 7)) {
				APKill(i);
			}
		}
	}

	public static int[] shuffleArray(int[] array) {
		int index;
		Random random = new Random();
		for (int i = array.length - 1; i > 0; i--) {
			index = random.nextInt(i + 1);
			if (index != i) {
				array[index] ^= array[i];
				array[i] ^= array[index];
				array[index] ^= array[i];
			}
		}
		return array;
	}

	public static int getMax(int n) {
		int result = 0;
		for (int i = 1; i < n; i++) {
			if (values[i] > values[result]) {
				result = i;
			}
		}
		return result;
	}

	public static int[] getStartingPerm(int n) {
		int[] result = new int[n];
		for (int i = 0; i < n; i++) {
			result[i] = i;
		}
		return shuffleArray(result);
	}

	public static void APKill(int n) {
		threshold = n * n;
		tries = 0;
		values = new int[n];
		fails = 0;
		res = getStartingPerm(n);
		conditions = new int[n][n / 2];
		for (int i = 0; i < n; i++) {
			for (int j = 1; j <= n / 2; j++) {
				if (isAP(res[i], res[(i + j) % n], res[(i + 2 * j) % n], n)) {
					conditions[i][j - 1] = 1;
					fails++;
					values[i]++;
					values[(i + j) % n]++;
					values[(i + 2 * j) % n]++;
				} else
					conditions[i][j - 1] = 0;
			}
		}
		// This is the meat of the code below. It essentially swaps at a random
		// point and verifies whether or
		// the corresponding permutation has fewer or more modular APs than in
		// the previous case.
		while (fails > 0) {
			curfail = fails;
			int max = getMax(n);
			int a = r.nextInt(n);
			if (r.nextDouble() > 0.9) {
				a = max;
			}

			int b = r.nextInt(n);
			swap(a, b);
			update(a, b, n);
			if (fails >= curfail) {
				swap(a, b);
				update(a, b, n);
				tries++;
			}

			else {
				tries = 0;
			}
			if (tries > threshold) {
				threshold = n * n;
				tries = 0;
				fails = 0;
				values = new int[n];
				res = getStartingPerm(n);
				conditions = new int[n][n - 1];
				for (int i = 0; i < n; i++) {
					for (int j = 1; j <= n / 2; j++) {
						if (isAP(res[i], res[(i + j) % n], res[(i + 2 * j) % n], n)) {
							conditions[i][j - 1] = 1;
							fails++;
							values[i]++;
							values[(i + j) % n]++;
							values[(i + 2 * j) % n]++;
						} else
							conditions[i][j - 1] = 0;
					}
				}
			}
		}
		System.out.println(n + ": " + toString(res));

	}

	public static String toString(int[] a) {
		String s = "[";
		for (int i = 0; i < a.length - 1; i++) {
			s += (a[i] + ",");
		}
		s += a[a.length - 1] + "]";
		boolean current = true;
		int p = a.length;
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a.length; j++) {
				if (mod(a[mod(j - i, p)] + a[mod(j + i, p)] - 2 * a[mod(j, p)], p) == 0 && mod(j - i, p) != mod(j, p)
						&& mod(j + i, p) != mod(j, p)) {
					current = false;
				}
			}
		}
		if (!current) {
			throw new IllegalArgumentException();
		}
		return s;
	}

	public static void swap(int i, int j) {
		temp = res[i];
		res[i] = res[j];
		res[j] = temp;
	}

	public static void update(int i, int j, int n) {
		for (int k = 1; k <= n / 2; k++) {
			if (isAP(res[i], res[(i + k) % n], res[(i + 2 * k) % n], n)) {
				if (conditions[i][k - 1] == 0) {
					conditions[i][k - 1] = 1;
					fails++;
					values[i]++;
					values[(i + k) % n]++;
					values[(i + 2 * k) % n]++;
				}
			} else {
				if (conditions[i][k - 1] == 1) {
					conditions[i][k - 1] = 0;
					fails--;
					values[i]--;
					values[(i + k) % n]--;
					values[(i + 2 * k) % n]--;
				}
			}
			if (isAP(res[j], res[(j + k) % n], res[(j + 2 * k) % n], n)) {
				if (conditions[j][k - 1] == 0) {
					conditions[j][k - 1] = 1;
					fails++;
					values[j]++;
					values[(j + k) % n]++;
					values[(j + 2 * k) % n]++;
				}
			} else {
				if (conditions[j][k - 1] == 1) {
					conditions[j][k - 1] = 0;
					fails--;
					values[j]--;
					values[(j + k) % n]--;
					values[(j + 2 * k) % n]--;
				}
			}
			if (isAP(res[(i - k + n) % n], res[i % n], res[(i + k) % n], n)) {
				if (conditions[(i - k + n) % n][k - 1] == 0) {
					conditions[(i - k + n) % n][k - 1] = 1;
					fails++;
					values[(i - k + n) % n]++;
					values[i]++;
					values[(i + k) % n]++;
				}
			} else {
				if (conditions[(i - k + n) % n][k - 1] == 1) {
					conditions[(i - k + n) % n][k - 1] = 0;
					fails--;
					values[(i - k + n) % n]--;
					values[i]--;
					values[(i + k) % n]--;
				}
			}
			if (isAP(res[(j - k + n) % n], res[j % n], res[(j + k) % n], n)) {
				if (conditions[(j - k + n) % n][k - 1] == 0) {
					conditions[(j - k + n) % n][k - 1] = 1;
					fails++;
					values[(j - k + n) % n]++;
					values[j]++;
					values[(j + k) % n]++;
				}
			} else {
				if (conditions[(j - k + n) % n][k - 1] == 1) {
					conditions[(j - k + n) % n][k - 1] = 0;
					fails--;
					values[(j - k + n) % n]--;
					values[j]--;
					values[(j + k) % n]--;
				}
			}
			if (isAP(res[(i - 2 * k + 2 * n) % n], res[(i - k + n) % n], res[i % n], n)) {
				if (conditions[(i - 2 * k + 2 * n) % n][k - 1] == 0) {
					conditions[(i - 2 * k + 2 * n) % n][k - 1] = 1;
					values[(i - 2 * k + 2 * n) % n]++;
					values[(i - k + n) % n]++;
					values[i]++;
					fails++;
				}
			} else {
				if (conditions[(i - 2 * k + 2 * n) % n][k - 1] == 1) {
					conditions[(i - 2 * k + 2 * n) % n][k - 1] = 0;
					fails--;
					values[(i - 2 * k + 2 * n) % n]--;
					values[(i - k + n) % n]--;
					values[i]--;
				}
			}
			if (isAP(res[(j - 2 * k + 2 * n) % n], res[(j - k + n) % n], res[j % n], n)) {
				if (conditions[(j - 2 * k + 2 * n) % n][k - 1] == 0) {
					conditions[(j - 2 * k + 2 * n) % n][k - 1] = 1;
					fails++;
					values[(j - 2 * k + 2 * n) % n]++;
					values[(j - k + n) % n]++;
					values[j]++;
				}
			} else {
				if (conditions[(j - 2 * k + 2 * n) % n][k - 1] == 1) {
					conditions[(j - 2 * k + 2 * n) % n][k - 1] = 0;
					fails--;
					values[(j - 2 * k + 2 * n) % n]--;
					values[(j - k + n) % n]--;
					values[j]--;
				}
			}
		}
	}

	public static boolean isAP(int a, int b, int c, int n) {
		if (modAP(a, b, c, n) == 0)
			return true;
		return false;
	}

	public static int modAP(int a, int b, int c, int n) {
		return (a + c - 2 * b + 2 * n) % n;
	}

	public static boolean isPrime(int a) {
		for (int i = 2; i * i <= a; i++) {
			if (a % i == 0)
				return false;
		}
		return true;
	}

	public static int mod(int a, int p) {
		return (a % p + p) % p;
	}

	public static boolean isGood(int a) {
		if (mod(a, 2) == 0 && isPrime(a / 2)) {
			return true;
		}
		if (mod(a, 3) == 0 && isPrime(a / 3)) {
			return true;
		}
		if (mod(a, 5) == 0 && isPrime(a / 5)) {
			return true;
		}
		if (mod(a, 7) == 0 && isPrime(a / 7)) {
			return true;
		}
		return false;
	}
}
