#include <bits/stdc++.h>
using namespace std;
const int N = 888;
int p[N];
int ans[N], n;
int pos[N], r2[N];
int cnt;
bool queryOne(int id) {
  cnt++;
  printf("? %d", n - 1);
  for (int i = 1; i <= n; i++) {
    if (i != id) {
      printf(" %d", i);
    }
  }
  puts("");
  fflush(stdout);
  int t;
  scanf("%d", &t);
  return t;
}
int queryRem(int id) {
  cnt++;
  printf("? 2 %d %d\n", pos[1], id);
  fflush(stdout);
  int t;
  scanf("%d", &t);
  return t;
}
int queryK(int k, int id) {
  cnt++;
  printf("? %d", n - 2 * k - 1);
  for (int i = 1; i <= n; i++) {
    if ((!::ans[i] || ::ans[i] == 1 + k || ::ans[i] == n - k) && i != id)
      printf(" %d", i);
  }
  puts("");
  fflush(stdout);
  int t;
  scanf("%d", &t);
  return t;
}
void Exit() {
  if (cnt > n * 18) {
    cerr << 0 << endl;
    for (int i = 1; i <= n; i++) cout << p[i] << ' ';
    cout << endl;
    exit(0);
  }
  if (ans[1] > n / 2) {
    for (int i = 1; i <= n; i++) {
      ans[i] = n + 1 - ans[i];
    }
  }
  printf("!");
  for (int i = 1; i <= n; i++) {
    printf(" %d", ans[i]);
  }
  cout << endl;
  exit(0);
}
int qu[N], qn;
bool query(int id) {
  printf("? %d", qn + 1);
  for (int i = 0; i < qn; i++) {
    printf(" %d", qu[i]);
  }
  printf(" %d\n", id);
  fflush(stdout);
  scanf("%d", &id);
  return id;
}
int r3[N];
int rem3() {
  memset(r3, -1, sizeof r3);
  qn = 2, qu[0] = pos[1], qu[1] = pos[2];
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (query(i)) {
      r3[i] = 0;
    }
  }
  qn = 2, qu[0] = pos[2], qu[1] = pos[3];
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (r3[i] != -1) continue;
    if (query(i)) {
      r3[i] = 1;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (r3[i] != -1) continue;
    r3[i] = 2;
  }
}
int r5[N];
int tmp[10];
int rem5() {
  memset(r5, -1, sizeof r5);
  for (int j = 1; j <= 4; j++) {
    qn = 4;
    qu[0] = pos[n];
    qu[1] = pos[n - 2];
    qu[2] = pos[n - 3];
    qu[3] = pos[j];
    for (int i = 1; i <= n; i++) {
      if (ans[i]) continue;
      if (r5[i] != -1) continue;
      if (query(i)) {
        r5[i] = (5 - (n * 3 + j) % 5) % 5;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (r5[i] != -1) continue;
    r5[i] = (5 - n * 3 % 5) % 5;
  }
}
int r7[N];
int rem7() {
  memset(r7, -1, sizeof r7);
  int arr[6][10] = {{1, 2, 3, n - 3, n - 2, n - 1}, {1, 2, 3, n - 3, n - 2, n},
                    {1, 2, 3, n - 3, n - 1, n},     {1, 2, 3, n - 2, n - 1, n},
                    {1, 2, 4, n - 2, n - 1, n},     {1, 3, 4, n - 2, n - 1, n}};
  for (int j = 0; j < 6; j++) {
    qn = 6;
    for (int i = 0; i < 6; i++) {
      qu[i] = pos[arr[j][i]];
    }
    for (int i = 1; i <= n; i++) {
      if (ans[i]) continue;
      if (r7[i] != -1) continue;
      if (query(i)) {
        r7[i] = (14 - 3 * n % 7 - j) % 7;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (r7[i] != -1) continue;
    r7[i] = (14 - 3 * n % 7 - 6) % 7;
  }
}
int query4(int a, int b, int c, int d) {
  printf("? 4 %d %d %d %d\n", a, b, c, d);
  fflush(stdout);
  scanf("%d", &a);
  return a;
}
int query8(int a, int b, int c, int d, int e, int f, int g, int h) {
  printf("? 8 %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h);
  fflush(stdout);
  scanf("%d", &a);
  return a;
}
int r4[N];
int r8[N];
int rem8() {
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (r2[i] == 0) {
      if (query4(pos[1], pos[2], pos[3], i))
        r4[i] = 2;
      else
        r4[i] = 0;
    } else {
      if (query4(pos[1], pos[2], pos[4], i))
        r4[i] = 1;
      else
        r4[i] = 3;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    if (r4[i] == 0) {
      if (query8(pos[1], pos[2], pos[3], pos[n], pos[n - 1], pos[n - 2],
                 pos[n - 3], i))
        r8[i] = 0;
      else
        r8[i] = 4;
    } else if (r4[i] == 1) {
      if (query8(pos[2], pos[3], pos[4], pos[n], pos[n - 1], pos[n - 2],
                 pos[n - 3], i))
        r8[i] = 5;
      else
        r8[i] = 1;
    } else if (r4[i] == 2) {
      if (query8(pos[1], pos[3], pos[4], pos[n], pos[n - 1], pos[n - 2],
                 pos[n - 3], i))
        r8[i] = 6;
      else
        r8[i] = 2;
    } else if (r4[i] == 3) {
      if (query8(pos[1], pos[2], pos[4], pos[n], pos[n - 1], pos[n - 2],
                 pos[n - 3], i))
        r8[i] = 7;
      else
        r8[i] = 3;
    }
  }
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    if (queryOne(i)) {
      pos[1] = i;
      ans[i] = 1;
      break;
    }
  }
  for (int i = n; i >= 1; i--) {
    if (queryOne(i)) {
      pos[n] = i;
      ans[i] = n;
      break;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (ans[i]) continue;
    r2[i] = queryRem(i);
  }
  if (n == 2) {
    Exit();
  }
  for (int i = 1; i < 4; i++) {
    for (int j = 1; j <= n; j++) {
      if (!ans[j] && queryK(i, j)) {
        if (r2[j] == (1 + i & 1)) {
          ans[j] = 1 + i;
          pos[1 + i] = j;
        } else {
          ans[j] = n - i;
          pos[n - i] = j;
        }
      }
    }
    if (n == (i + 1) * 2) {
      Exit();
    }
  }
  rem3();
  rem5();
  rem7();
  rem8();
  for (int i = 1; i <= n; i++) {
    if (!ans[i]) {
      for (int j = 1; j <= n; j++) {
        if (j % 3 == r3[i] && j % 5 == r5[i] && j % 7 == r7[i] &&
            j % 8 == r8[i]) {
          ans[i] = j;
          break;
        }
      }
    }
  }
  Exit();
  return 0;
}
