import std.conv, std.functional, std.range, std.stdio, std.string; import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, 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; } bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } } bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } } int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; } int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); } int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); } void main() { long[] vals; foreach (x; 0 .. 9 + 1) foreach (y; 0 .. 9 + 1) { vals ~= 2L^^x * 5L^^y; } const V = cast(int)(vals.length); int[long] tr; foreach (u; 0 .. V) { tr[vals[u]] = u; } debug { writeln("V = ", V); writeln("vals = ", vals); } auto graph = new int[][V]; foreach (u; 0 .. V) { foreach (p; [2L, 5L]) { if (vals[u] % p == 0) { graph[u] ~= tr[vals[u] / p]; } } foreach (p; [2L, 5L]) { const val = min(p * vals[u], 10L^^9); if (val in tr) { graph[u] ~= tr[val]; } } } auto rev = new int[][V]; foreach (u; 0 .. V) { foreach (v; graph[u]) { rev[v] ~= u; } } auto dp = new int[][][](2, V, V); auto deg = new int[][][](2, V, V); auto prev = new int[][][](2, V, V); foreach (t; 0 .. 2) foreach (u; 0 .. V) foreach (v; 0 .. V) { dp[t][u][v] = -1; deg[t][u][v] = cast(int)(graph[t ? u : v].length); } DList!int que; foreach (t; 0 .. 2) foreach (u; 0 .. V) { dp[t][u][u] = t; prev[t][u][u] = -1; que ~= t; que ~= u; que ~= u; } for (; !que.empty; ) { const t = que.front; que.removeFront; const u = que.front; que.removeFront; const v = que.front; que.removeFront; const z = dp[t][u][v]; if (t) { foreach (vv; rev[v]) { if (!~dp[0][u][vv]) { if (z & 1) { if (--deg[0][u][vv]) { continue; } } dp[0][u][vv] = z + 1; prev[0][u][vv] = v; que ~= 0; que ~= u; que ~= vv; } } } else { foreach (uu; rev[u]) { if (!~dp[1][uu][v]) { if (z & 1) { if (--deg[1][uu][v]) { continue; } } dp[1][uu][v] = z + 1; prev[1][uu][v] = u; que ~= 1; que ~= uu; que ~= v; } } } } debug { int mx = -1; foreach (t; 0 .. 2) foreach (u; 0 .. V) foreach (v; 0 .. V) { assert(~dp[t][u][v], [t, u, v].to!string); chmax(mx, dp[t][u][v]); } writeln("mx = ", mx); stdout.flush; } { int u = tr[readLong]; int v = tr[readLong]; for (; ; ) { // 1: me { if (u == v) { return; } const uu = prev[1][u][v]; if(!graph[u].any!(a=>a==uu))for(;;){} writeln(vals[uu]); stdout.flush; u = uu; } // 0: enemy { if (u == v) { return; } const vv = tr[readLong]; if(!graph[v].any!(a=>a==vv))for(;;){} v = vv; } } } }