#include using namespace std; using ll = long long; const int inf = 1 << 30; const ll INF = 1LL << 60; const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1}; #define rep(i, s, t) for (ll i = (ll)s; i < (ll)(t); i++) #define rrep(i, s, t) for (ll i = (ll)(t) - 1; i >= (ll)(s); i--) #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) template bool chmin(T1& x, T2 y) { return x > y ? (x = y, true) : false; } template bool chmax(T1& x, T2 y) { return x < y ? (x = y, true) : false; } template using min_heap = priority_queue, greater>; template using max_heap = priority_queue; void solve() { int N; cin >> N; vector P(N, -1); rep(i, 0, N) { vector A(N); rep(j, 0, N) { if (j == i) A[j] = 2; else A[j] = 1; } cout << "? "; rep(j, 0, N) cout << A[j] << " "; cout << endl; int l; cin >> l; assert(l >= 0); if (l == 1) { P[0] = i; break; } } auto comp = [&](int x, int y) -> bool { vector A(N); A[P[0]] = 1; rep(i, 0, N) { if (i == P[0]) continue; if (i == x) A[i] = 2; else if (i == y) A[i] = 3; else A[i] = 1; } cout << "? "; rep(j, 0, N) cout << A[j] << " "; cout << endl; int l; cin >> l; assert(l >= 0); return (l == 3); }; auto merge_sort = [&](auto self, vector &V) -> void { int S = V.size(); if (S <= 1) return; vector L, R; rep(i, 0, S / 2) L.push_back(V[i]); rep(i, S / 2, S) R.push_back(V[i]); V.clear(); int s = 0, t = 0; self(self, L); self(self, R); while (s < L.size() || t < R.size()) { if (s < L.size() && t < R.size()) { if (comp(L[s], R[t])) { V.push_back(L[s]); s++; } else { V.push_back(R[t]); t++; } } else if (s == L.size()) { V.push_back(R[t]); t++; } else { V.push_back(L[s]); s++; } } }; vector V; rep(i, 0, N) if (i != P[0]) V.push_back(i); merge_sort(merge_sort, V); rep(i, 0, N - 1) P[i + 1] = V[i]; vector Q(N); rep(i, 0, N) Q[P[i]] = i; cout << "! "; rep(i, 0, N) cout << Q[i] + 1 << " "; cout << endl; } int main() { // cin.tie(0)->sync_with_stdio(0); // cout << fixed << setprecision(15); srand(time(NULL)); int T; // cin >> T; T = 1; while (T--) solve(); }