#include <bits/stdc++.h>
using namespace std;
int d[4][1010], dep[1010], l[1010], r[1010], cnt, tl[1010], tr[1010], n;
int father[1010];
char s[4][1010];
vector<int> node[1010], tnode[1010];
void solve1(int c, int cnt) {
  for (int i = 1; i <= n; i++) d[0][i] = d[1][i] = 0;
  for (int i = c; i <= cnt; i += 2) {
    int mid = (l[i] + r[i]) / 2;
    for (int j = 1; j <= n; j++)
      if (dep[j] == l[i] - 1) {
        d[0][j] = mid - l[i] + 1;
        d[1][j] = d[0][j] - 1;
      }
  }
  if (c == 2) c = 0;
  for (int t = 0; t <= 1; t++) {
    printf("?");
    for (int i = 1; i <= n; i++) printf(" %d", d[t][i]);
    puts("");
    fflush(stdout);
    scanf("%s", s[2 * c + t] + 1);
  }
}
void get_res() {
  for (int i = 0; i <= 9; i++)
    for (int j = 0; j <= 3; j++) {
      printf("?");
      for (int k = 1; k <= n; k++)
        if (dep[k] % 3 == j && (k >> i) & 1)
          printf(" %d", 1);
        else
          printf(" %d", 0);
      puts("");
      fflush(stdout);
      scanf("%s", s[0] + 1);
      for (int k = 2; k <= n; k++)
        if ((dep[k] - 1) % 3 == j && s[0][k] == '1') father[k] += 1 << i;
    }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) dep[i] = -1;
  dep[1] = 0;
  for (int i = 2; i <= n; i++) node[1].push_back(i);
  l[1] = 1;
  r[1] = n;
  cnt = 1;
  while (true) {
    solve1(2, cnt);
    solve1(1, cnt);
    int tot = 0;
    for (int i = 1; i <= cnt; i++) tnode[i].clear();
    for (int i = 1; i <= cnt; i++) {
      int c = (i % 2), len = node[i].size(), mid = (l[i] + r[i]) / 2, c0, c1;
      if (l[i] < mid - 1) {
        tl[tot + 1] = l[i];
        tr[tot + 1] = mid - 1;
        tot++;
        c0 = tot;
      }
      if (mid + 1 < r[i]) {
        tl[tot + 1] = mid + 1;
        tr[tot + 1] = r[i];
        tot++;
        c1 = tot;
      }
      for (int j = 0; j <= len - 1; j++) {
        int ch = -1, v = node[i][j];
        if (s[2 * c][v] == '0')
          ch = 1;
        else if (s[2 * c + 1][v] == '1')
          ch = 0;
        else
          dep[v] = mid;
        if (ch == 0) {
          if (l[i] == mid - 1)
            dep[v] = l[i];
          else
            tnode[c0].push_back(v);
        } else if (ch == 1) {
          if (mid + 1 == r[i])
            dep[v] = mid + 1;
          else
            tnode[c1].push_back(v);
        }
      }
    }
    cnt = tot;
    for (int i = 1; i <= tot; i++) {
      l[i] = tl[i];
      r[i] = tr[i];
      node[i] = tnode[i];
    }
    int flag = 1;
    for (int i = 1; i <= n; i++)
      if (dep[i] == -1) {
        flag = 0;
        break;
      }
    if (flag) break;
  }
  get_res();
  puts("!");
  for (int i = 2; i <= n; i++) printf("%d %d\n", father[i], i);
  return 0;
}
