import std.conv, std.stdio, std.string; import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex, std.typecons; import core.bitop; class EOFException : Throwable { this() { super("EOF"); } } string[] tokens; string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; } int readInt() { return readToken().to!int; } long readLong() { return readToken().to!long; } real readReal() { return readToken().to!real; } void chmin(T)(ref T t, in T f) { if (t > f) t = f; } void chmax(T)(ref T t, in T f) { if (t < f) t = f; } int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = cast(int)(as.length); for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; } int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a < val)); } int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) => (a <= val)); } immutable LIM = 12; /* . / \ .---. / \ / \ .---3---4 5 / \ / \ / \ 0 1---2---@---. / \ / \ / \ / \ .---.---.---.---. */ void run() { enum LOG_BASE = 4; enum MASK = (1 << LOG_BASE) - 1; enum CLOSED = (1 << LOG_BASE) - 1; ulong encode(int[] a) { ulong ret; foreach (i; 0 .. a.length) { ret |= cast(ulong)(a[i]) << (LOG_BASE * i); } return ret; } auto ans = new BigInt[LIM + 1]; BigInt[ulong] crt; crt[encode([CLOSED, CLOSED])] = 1; foreach (m; 0 .. LIM + 1) { stderr.writefln("m = %s", m); foreach (n; 0 .. m + 1) { BigInt[ulong] nxt; void add(ulong key, BigInt val) { nxt.update(key, () => val, (ref BigInt old) => old + val); } foreach (key, val; crt) { auto a = new int[m + 3]; if (n == 0) { a[0] = CLOSED; foreach (i; 1 .. m + 3) { a[i] = (key >> (LOG_BASE * (i - 1))) & MASK; if (a[i] != CLOSED) { ++a[i]; } } } else { foreach (i; 0 .. m + 3) { a[i] = (key >> (LOG_BASE * i)) & MASK; } } debug { writefln("m = %s, n = %s, a = %s, val = %s", m, n, a, val); foreach (i; 0 .. m + 3) { if (a[i] != CLOSED) { assert(a[a[i]] == i); } } } // last row if (m == LIM && !a[0 .. n].all!(tmp => (tmp == CLOSED))) { continue; } // skip if (a[n + 1] == CLOSED) { add(encode(a), val); } // connect 0 if (a[n + 1] == CLOSED) { auto b = a.dup; b[n + 1] = n + 1; add(encode(b), val); } // connect 1 foreach (y; n .. n + 3) { auto b = a.dup; if (b[y] != CLOSED) { const yy = b[y]; b[yy] = n + 1; if (y != yy) { b[y] = CLOSED; } if (b[n + 1] == CLOSED) { b[n + 1] = yy; debug{ // writefln(" connect 1: y = %s, b = %s",y,b); } add(encode(b), val); } } } // connect 2 foreach (y0; n .. n + 3) foreach (y1; y0 + 1 .. n + 3) { auto b = a.dup; if (b[y0] != CLOSED && b[y1] != CLOSED) { if (b[y0] == y1 && b[y1] == y0) { // finishing cycle b[y0] = CLOSED; b[y1] = CLOSED; if (b.all!(tmp => (tmp == CLOSED))) { ans[m] += val; } } else { const yy0 = b[y0]; const yy1 = b[y1]; b[yy0] = yy1; b[yy1] = yy0; if (y0 != yy0) { b[y0] = CLOSED; } if (y1 != yy1) { b[y1] = CLOSED; } if (b[n + 1] == CLOSED) { debug{ // writefln(" connect 2: y0 = %s, y1 = %s, b = %s",y0,y1,b); } add(encode(b), val); } } } } } crt = nxt; } } foreach (n; 1 .. LIM + 1) { ans[n] += ans[n - 1]; } writeln(ans.to!(string[])); } void main() { // 1m17.081s // run(); // return; immutable ansStr = ["0", "1", "11", "110", "2402", "128967", "16767653", "5436906668", "4406952731948", "8819634719356421", "43329348004927734247", "522235268182347360718818", "15436131339319739257518081878"] ; try { for (; ; ) { const N = readInt(); writeln(ansStr[N]); } } catch (EOFException e) { } }