#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7, M = 20;
vector<int> v[N];
int fp[N], ch[N][2];
int n, q[N], q1[N], dis[N], q2[N], fa[N], fl[N], ft[N], fz[N], fq[N], fw[N],
    fc[N], fh[N], opt[M][N];
char s[N];
vector<int> vt[N];
inline void query() {
  int ret = 0;
  for (int i = 1; i <= n; i++)
    if (q[i] != 0) ret = 1;
  if (!ret) {
    memset(fl, 0, sizeof(fl));
    return;
  }
  putchar('?'), cout << " ";
  for (int i = 1; i <= n; i++) printf("%d ", min(q[i], n - 1));
  cout << endl;
  scanf("%s", s + 1);
  for (int i = 1; i <= n; i++) fl[i] = s[i] - '0';
}
inline void solve(int t) {
  if (t < 0) return;
  memset(q, 0, sizeof(q));
  q[1] = (1 << t);
  query();
  for (int i = 1; i <= n; i++) fw[i] = fl[i];
  memset(q, 0, sizeof(q));
  for (int i = 1; i <= n; i++)
    if ((i - 1) % (1 << (t + 2)) == 0) {
      for (int x = 0; x < v[i].size(); x++) q[v[i][x]] = (1 << t);
    }
  query();
  for (int i = 1; i <= n; i++) ft[i] = fl[i];
  for (int i = 1; i <= n; i++)
    if (q[i]) q[i]--;
  for (int i = 1; i <= n; i++) fh[i] = ft[i];
  query();
  for (int i = 1; i <= n; i++) fz[i] = (ft[i] != fl[i]);
  memset(q, 0, sizeof(q));
  for (int i = 1; i <= n; i++)
    if ((i - 1) % (1 << (t + 2)) == (1 << (t + 1))) {
      for (int x = 0; x < v[i].size(); x++) q[v[i][x]] = (1 << t);
    }
  query();
  for (int i = 1; i <= n; i++) ft[i] = fl[i];
  int opq = 0;
  for (int i = 1; i <= n; i++)
    if (ft[i] == 1) opq++;
  for (int i = 1; i <= n; i++)
    if (q[i]) q[i]--;
  query();
  for (int i = 1; i <= n; i++)
    if (fq[i] % 2 == 0 && fz[i] && !fc[i]) {
      fc[i] = fq[i] * (1 << (t + 1)) + (1 << t) + 1;
      v[fc[i]].push_back(i);
    } else if (fq[i] % 2 == 1 && (fl[i] != ft[i]) && !fc[i]) {
      fc[i] = fq[i] * (1 << (t + 1)) + (1 << t) + 1;
      v[fc[i]].push_back(i);
    }
  int opt = 0;
  for (int i = 0; i <= n; i += 2) {
    ch[i][0] = opt++;
    ch[i][1] = opt++;
    ch[i + 1][1] = opt++;
    ch[i + 1][0] = opt++;
  }
  for (int i = 1; i <= n; i++)
    if (fh[i])
      fq[i] = ch[fq[i]][0];
    else if (ft[i])
      fq[i] = ch[fq[i]][1];
    else if (fq[i] % 2 == 0)
      fq[i] = ch[fq[i]][1];
    else
      fq[i] = ch[fq[i]][0];
  for (int i = 1; i <= n; i++)
    if (!fw[i]) fq[i] = max(fq[i], 1);
  solve(t - 1);
}
int main() {
  scanf("%d", &n);
  int t = 0;
  fc[1] = 1, v[1].push_back(1);
  while ((1 << (t + 1)) <= n - 1) t++;
  solve(t);
  for (int i = 0; i <= 2; i++) {
    memset(q1, 0, sizeof(q1));
    memset(q2, 0, sizeof(q2));
    for (int x = 1; x <= n; x++)
      if (fc[x] % 3 == i % 3) q1[++q1[0]] = x;
    for (int x = 1; x <= n; x++)
      if (fc[x] % 3 == (i + 1) % 3) q2[++q2[0]] = x;
    for (int z = 0; z <= t; z++) {
      memset(q, 0, sizeof(q));
      for (int x = 1; x <= q1[0]; x++)
        if (x & (1 << z)) q[q1[x]] = 1;
      query();
      for (int x = 1; x <= n; x++) opt[z][x] = fl[x];
    }
    for (int x = 1; x <= q2[0]; x++) {
      int c = 0;
      for (int z = 0; z <= t; z++)
        if (opt[z][q2[x]]) c |= (1 << z);
      fa[q2[x]] = q1[c];
    }
  }
  cout << "!" << endl;
  for (int i = 2; i <= n; i++) printf("%d %d\n", i, fa[i]);
  cout << endl;
}
