using System; using static System.Console; using System.Linq; using System.Collections.Generic; using System.Runtime.Intrinsics.Arm; class Program { static int NN => int.Parse(ReadLine()); static int[] NList => ReadLine().Split().Select(int.Parse).ToArray(); static int[][] NArr(long n) => Enumerable.Repeat(0, (int)n).Select(_ => NList).ToArray(); public static void Main() { Solve(); } static void Solve() { var n = NN; var ans = Enumerable.Repeat(-1, n).ToArray(); var tree = new List<(int to, int mul)>[n]; for (var i = 0; i < n; ++i) tree[i] = new List<(int to, int mul)>(); var first = -1; var second = -1; for (var i = 0; i + 1 < n; ++i) { WriteLine($"? {i} {n - 1}"); var p = NN; if (p == 0) ans[i] = 0; else { if (first == -1) first = i; else if (second == -1) second = i; tree[i].Add((n - 1, p)); } } if (second > 0) { WriteLine($"? {first} {second}"); tree[first].Add((second, NN)); } var set = new HashSet(); for (var i = 1; i < 10; ++i) { var na = (int[])ans.Clone(); na[first] = i; var q = new Queue(); q.Enqueue(first); var flg = true; while (q.Count > 0) { var cur = q.Dequeue(); foreach (var next in tree[cur]) { if (na[next.to] < 0) { na[next.to] = next.mul / na[cur]; } else { if (na[next.to] != next.mul / na[cur]) { flg = false; q.Clear(); break; } } } } if (flg) { for (var j = 0; j < n; ++j) { if (na[j] < 0 || na[j] > 9) flg = false; foreach (var next in tree[j]) { if (na[j] * na[next.to] != next.mul) flg = false; } } } if (flg) set.Add(string.Concat(na.Reverse())); } if (set.Count == 1) foreach (var si in set) WriteLine($"! {si}"); else WriteLine($"! -1"); } }