#include <bits/stdc++.h>   const int MAXN = 1000 + 5;   char str[MAXN];   int n;   inline std::vector<int> query(std::vector<int> d) {     std::vector<int> ans;     printf( ?  );     for (auto x : d) printf( %d  , x);     puts(  );     std::fflush(stdout);     scanf( %s , str + 1);     for (int i = 1; i <= n; ++i) ans.push_back(str[i] -  0 );     return ans;   }   std::vector<int> G[MAXN];   std::vector<int> node[MAXN * 50];   int tot = 1;   struct Node {     int l, r, id;     Node(int l = 0, int r = 0, int id = 0) : l(l), r(r), id(id) {}     inline bool operator<(const Node &t) const { return l < t.l; }   };   int fa[MAXN];   inline void work(std::vector<int> id, int bit) {     std::vector<int> d;     d.resize(n);     for (auto x : id) {       for (auto y : G[x - 1])         if ((y >> bit) & 1) d[y - 1] = 1;     }     std::vector<int> a;     a = query(d);     for (auto x : id) {       for (auto y : G[x]) fa[y] |= (a[y - 1] << bit);     }   }   bool tag[MAXN];   int main() {     scanf( %d , &n);     std::vector<Node> now;     G[0].push_back(1);     now.push_back(Node(0, n, 1));     for (int i = 2; i <= n; ++i) node[tot].push_back(i);     while (!now.empty()) {       std::vector<Node> v1, v2;       std::sort(now.begin(), now.end());       for (int i = 0; i < now.size(); i += 2) {         v1.push_back(now[i]);         if (i + 1 < now.size()) v2.push_back(now[i + 1]);       }       std::vector<int> d, a1, a2;       d.resize(n);       now.clear();       memset(tag, 0, sizeof(tag));       for (auto x : v1) {         int mid = (x.l + x.r) >> 1;         assert(x.l < x.r - 1);         for (auto y : G[x.l]) d[y - 1] = mid - x.l - 1, tag[y - 1] = 1;       }       a1 = query(d);       for (int i = 0; i <= n - 1; ++i)         if (tag[i]) d[i]++;       a2 = query(d);       for (auto x : v1) {         int mid = (x.l + x.r) >> 1;         Node ls = Node(x.l, mid, ++tot), rs = Node(mid, x.r, ++tot);         for (auto y : node[x.id]) {           if (!a1[y - 1] && a2[y - 1])             G[mid].push_back(y);           else if (a1[y - 1])             node[ls.id].push_back(y);           else             node[rs.id].push_back(y);         }         if (ls.l + 1 < ls.r) now.push_back(ls);         if (rs.l + 1 < rs.r) now.push_back(rs);       }       d.clear();       d.resize(n);       memset(tag, 0, sizeof(tag));       for (auto x : v2) {         int mid = (x.l + x.r) >> 1;         assert(x.l < x.r - 1);         for (auto y : G[x.l]) d[y - 1] = mid - x.l - 1, tag[y - 1] = 1;       }       a1 = query(d);       for (int i = 0; i <= n - 1; ++i)         if (tag[i]) d[i]++;       a2 = query(d);       for (auto x : v2) {         int mid = (x.l + x.r) >> 1;         Node ls = Node(x.l, mid, ++tot), rs = Node(mid, x.r, ++tot);         for (auto y : node[x.id]) {           if (!a1[y - 1] && a2[y - 1])             G[mid].push_back(y);           else if (a1[y - 1])             node[ls.id].push_back(y);           else             node[rs.id].push_back(y);         }         if (ls.l + 1 < ls.r) now.push_back(ls);         if (rs.l + 1 < rs.r) now.push_back(rs);       }     }     for (int i = 0; i <= 9; ++i) {       std::vector<int> v1, v2, v3;       for (int i = 1; i < n; i += 3) {         v1.push_back(i);         if (i + 1 < n) v2.push_back(i + 1);         if (i + 2 < n) v3.push_back(i + 2);       }       work(v1, i);       work(v2, i);       work(v3, i);     }     puts( ! );     for (int i = 2; i <= n; ++i) printf( %d %d n , fa[i], i);     std::fflush(stdout);     return 0;   }