import sys input = lambda : sys.stdin.readline().rstrip() sys.setrecursionlimit(max(1000, 10**9)) write = lambda x: sys.stdout.write(x+"\n") DEBUG = False def _sub(i,j): a = [3,5,4,8,7,6] p = a[i-1]//n - a[j-1]//n q = a[i-1]%n - a[j-1]%n if p>q: p,q = q,p return p,q import sys def query(i,j): print("? {0} {1}".format(i, j)) sys.stdout.flush() if DEBUG: return _sub(i,j) else: return tuple(map(int, input().split())) n = int(input()) m = n*n-n ts = [query(1,i) for i in range(2,m+1)] from collections import defaultdict c = defaultdict(int) for t in ts: c[t[0]] += 1 c[t[1]] += 1 kv = list(c.items()) kv.sort() if kv[0][1]==n-1: val = kv[0][0] y = kv[0][0] + n - 1 for item in kv: if item[1] in (2*n-1, 2*n-3): break x = item[0] + n - 1 # print(x,item) else: val = kv[-1][0] assert kv[-1][1]==n-1 y = kv[-1][0] for item in kv[::-1]: if item[1] in (2*n-1, 2*n-3): break x = item[0] + 1 # done = [[False]*n for _ in range(n)] # done[x][y] = True ans = [None]*m ans[0] = (x,y) xy2i = defaultdict(list) for i,t in enumerate(ts): xy2i[min(t),max(t)].append(i) if val in t: if t[0]==val: t = (t[1], t[0]) ans[i+1] = (x-t[0], y-t[1]) if x-t[0]==n-1 and y-t[1]==0: index = i large = True elif x-t[0]==1 and y-t[1]==n-1: index = i large = False for i,t in enumerate(ts): if ans[i+1] is None: tt = query(index+2, i+2) if large: tt = (tt[1],tt[0]) ans[i+1] = (n-1-tt[0], -tt[1]) else: ans[i+1] = (1-tt[0], n-1-tt[1]) xx,yy = x - ans[i+1][0], y - ans[i+1][1] if xx<=yy: for ii in xy2i[xx,yy]: if i==ii: continue if ans[ii+1] is None: ans[ii+1] = (x-yy, y-xx) # print(ans[ii+1], ii+1) else: for ii in xy2i[yy,xx]: if i==ii: continue if ans[ii+1] is None: ans[ii+1] = (x-yy, y-xx) # print(ans[ii+1], ii+1) print("! "+ " ".join(map(str, [item[0]*n+item[1] for item in ans])))