#include <bits/stdc++.h>   using namespace std;   const int N = 810;   int gi() {     int x = 0, o = 1;     char ch = getchar();     while ((ch <  0  || ch >  9 ) && ch !=  - ) ch = getchar();     if (ch ==  - ) o = -1, ch = getchar();     while (ch >=  0  && ch <=  9 ) x = x * 10 + ch -  0 , ch = getchar();     return x * o;   }   int n, ans[N], pos[N], odd[N], p[N];   bool vis[10];   int query(vector<int> a) {     cout <<  ?   << int(a.size());     for (auto x : a) cout <<     << x;     cout << endl;     int t = gi();     if (t == -1) throw  orzxzz ;     return t;   }   int query_3(int x) {     if (query({pos[1], pos[2], x})) return 0;     if (query({pos[1], pos[3], x})) return 2;     return 1;   }   int query_5(int x) {     memset(vis, 0, sizeof(vis));     for (int i = 1; i <= 4; i++) {       int val = (5 - (3 * n - 3 + i) % 5) % 5;       if (query({pos[n], pos[n - 1], pos[n - 2], pos[i], x})) return val;       vis[val] = 1;     }     for (int i = 0; i < 5; i++)       if (!vis[i]) return i;     throw  orzxzz ;   }   int query_7(int x) {     memset(vis, 0, sizeof(vis));     int cnt = 0;     for (int i = 1; i <= 4 && cnt <= 5; i++)       for (int j = 1; j <= 4 && cnt <= 5; j++) {         int val = (7 - (4 * n + 4 - i - (n - j + 1)) % 7) % 7;         if (vis[val]) continue;         vector<int> vec = {x};         for (int k = 1; k <= 4; k++)           if (i != k) vec.push_back(pos[k]);         for (int k = 1; k <= 4; k++)           if (j != k) vec.push_back(pos[n - k + 1]);         if (query(vec)) return val;         vis[val] = 1;         ++cnt;       }     for (int i = 0; i < 7; i++)       if (!vis[i]) return i;     throw  orzxzz ;   }   int query_8(int x) {     int ret = odd[x];     for (int i = 1; i <= 4; i++) {       int val = (4 - (10 - i) % 4) % 4;       if (val != ret) continue;       vector<int> vec = {x};       for (int j = 1; j <= 4; j++)         if (i != j) vec.push_back(pos[j]);       if (!query(vec)) ret += 2;       break;     }     for (int i = 1; i <= 4; i++) {       int val = (8 - (4 * n + 4 - i) % 8) % 8;       if (val != ret && val != ret + 4) continue;       vector<int> vec = {x};       for (int j = 1; j <= 4; j++)         if (i != j) vec.push_back(pos[j]);       for (int j = 1; j <= 4; j++) vec.push_back(pos[n - j + 1]);       if (query(vec) ^ (val == ret)) ret += 4;       break;     }     return ret;   }   int main() {     ios::sync_with_stdio(0);     cin.tie(0);     cin >> n;     for (int i = 1; i <= n; i++) {       vector<int> vec;       for (int j = 1; j <= n; j++)         if (i != j) vec.push_back(j);       if (query(vec)) {         if (!pos[1])           pos[1] = i, ans[i] = 1;         else           pos[n] = i, ans[i] = n;       }     }     for (int i = 1; i <= n; i++)       if (!ans[i]) {         if (query({pos[1], i})) odd[i] = 1;       }     for (int t = 2; 2 * t <= n && t <= 4; t++) {       for (int i = 1; i <= n; i++)         if (!ans[i]) {           vector<int> vec;           for (int j = 1; j <= n; j++)             if (!ans[j] && j != i) vec.push_back(j);           if (query(vec)) {             if (!pos[t])               pos[t] = i;             else               pos[n - t + 1] = i;           }         }       if (odd[pos[t]] != (t & 1)) swap(pos[t], pos[n - t + 1]);       ans[pos[t]] = t;       ans[pos[n - t + 1]] = n - t + 1;     }     for (int i = 1; i <= n; i++)       if (!ans[i]) {         int a = query_3(i), b = query_5(i), c = query_7(i), d = query_8(i);         for (int j = 1; j <= n; j++)           if (j % 3 == a && j % 5 == b && j % 7 == c && j % 8 == d) {             ans[i] = j;             break;           }       }     if (ans[1] > n / 2) {       for (int i = 1; i <= n; i++) ans[i] = n + 1 - ans[i];     }     cout <<  ! ;     for (int i = 1; i <= n; i++) cout <<     << ans[i];     return 0;   }