#include using namespace std; long long ask(int a, int b) { cout << "? " << a << " " << b << endl; cout.flush(); long long x; cin >> x; if (x == -1) exit(0); return x; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector> p(N, vector(N, -1)); // Query all pairs involving 0 and 1 (enough for reconstruction) for (int i = 1; i < N; i++) { p[0][i] = p[i][0] = ask(0, i); } if (N >= 2) { for (int i = 2; i < N; i++) { p[1][i] = p[i][1] = ask(1, i); } } vector d(N); bool found = false; vector answer; for (int d0 = 0; d0 <= 9; d0++) { for (int d1 = 0; d1 <= 9; d1++) { if (d0 * d1 != p[0][1]) continue; vector cur(N, -1); cur[0] = d0; cur[1] = d1; bool ok = true; // propagate using best available constraint for (int i = 2; i < N; i++) { if (d0 != 0 && p[0][i] % d0 == 0) { cur[i] = p[0][i] / d0; } else if (d1 != 0 && p[1][i] % d1 == 0) { cur[i] = p[1][i] / d1; } else { ok = false; break; } if (cur[i] < 0 || cur[i] > 9) { ok = false; break; } } if (!ok) continue; // full verification (critical for WA fix) for (int i = 0; i < N && ok; i++) { for (int j = i + 1; j < N; j++) { if (cur[i] * cur[j] != p[i][j]) { ok = false; break; } } } if (ok) { if (found) { cout << "! -1\n"; cout.flush(); return 0; } found = true; answer = cur; } } } if (!found) { cout << "! -1\n"; cout.flush(); return 0; } long long X = 0, pw = 1; for (int i = 0; i < N; i++) { X += answer[i] * pw; pw *= 10; } cout << "! " << X << endl; cout.flush(); return 0; }