#include <bits/stdc++.h>   using namespace std;   const double eps = 1e-9;   const int MAXB = 10;   const int MAXN = 1025;   vector<int> distGroup[MAXN];   int hasDist[MAXN];   int predecessor[MAXN];   vector<int> output;   set<int> centers;   string result, resultm;   int maxDist[MAXN];   int minDist[MAXN];   vector<string> strangeresults;   int main() {     int N;     cin >> N;     for (int i = (0); i < (N); i++) minDist[i] = 1;     for (int i = (0); i < (N); i++) maxDist[i] = (1 << MAXB) - 1;     for (int i = (0); i < (N); i++) hasDist[i] = -1;     for (int i = (0); i < (N); i++) distGroup[i].clear();     distGroup[0].push_back(0);     maxDist[0] = minDist[0] = hasDist[0] = 0;     int largest = 0;     for (int p = int(MAXB) - 1; p >= (0); p--) {       for (int s = (0); s < (2); s++) {         output = vector<int>(N, 0);         centers.clear();         for (int i = (s << (p + 1)); true; i += (4 << p)) {           if (i > N || int((distGroup[i]).size()) == 0) break;           for (auto n : distGroup[i]) {             assert(output[n] == 0);             output[n] = (1 << p);           }           centers.insert(i);         }         if (int((centers).size()) > 0) {           cout <<  ? ;           for (auto v : output) cout <<     << min(N - 1, v);           cout << endl << flush;           cin >> result;           cout <<  ? ;           for (auto v : output) cout <<     << max(0, min(N - 1, v - 1));           cout << endl << flush;           cin >> resultm;           while (int((result).size()) != N || int((resultm).size()) != N) {             cerr <<  VERY STRANGE!! got    << result <<    and    << resultm                  <<    as results  << endl                  << flush;             strangeresults.push_back(result);             strangeresults.push_back(resultm);             if (int((strangeresults).size()) == (N - 1) * 2) {               cout <<  !  << endl;               for (int i = (0); i < (N - 1); i++)                 cout << strangeresults[i * 2] <<     << strangeresults[i * 2 + 1]                      << endl;               return 0;             }             cout <<  ? ;             for (auto v : output) cout <<     << min(N - 1, v);             cout << endl << flush;             cin >> result;             cout <<  ? ;             for (auto v : output) cout <<     << max(0, min(N - 1, v - 1));             cout << endl << flush;             cin >> resultm;           }           for (int i = (0); i < (N); i++) {             if (minDist[i] == maxDist[i]) continue;             if (centers.find(minDist[i] - 1) != centers.end()) {               if (result[i] ==  1 ) {                 if (resultm[i] ==  1 ) {                   maxDist[i] -= (1 << p);                 } else {                   minDist[i] = maxDist[i] = minDist[i] - 1 + (1 << p);                 }               } else                 minDist[i] += (1 << p);             }             if (minDist[i] == maxDist[i]) {               hasDist[i] = minDist[i];               largest = max(largest, minDist[i]);               distGroup[minDist[i]].push_back(i);             }           }         }       }     }     for (int i = (0); i < (N); i++) predecessor[i] = -1;     for (int i = (0); i < (N); i++)       assert(minDist[i] == maxDist[i] && maxDist[i] == hasDist[i]);     for (int a = (0); a < (2); a++) {       vector<string> results;       for (int b = (0); b < (MAXB); b++) {         for (int xo = (0); xo < (2); xo++) {           cout <<  ? ;           for (int n = (0); n < (N); n++) {             if (((hasDist[n] >> 1) ^ a) & 1)               cout <<     << (((n >> b) ^ xo) & 1);             else               cout <<   0 ;           }           cout << endl << flush;           string tmp;           cin >> tmp;           results.push_back(tmp);         }       }       for (int d = (0); d < (largest); d++) {         if (((d >> 1) ^ a ^ 1) & 1) continue;         for (auto n1 : distGroup[d])           for (auto n2 : distGroup[d + 1]) {             bool ok = true;             for (int b = (0); b < (MAXB); b++) {               if (results[b * 2 + (1 ^ ((n1 >> b) & 1))][n2] ==  0 ) ok = false;             }             if (ok) {               if (predecessor[n2] != -1) {                 cerr <<  prev predecessor[  << n2 <<  ]=  << predecessor[n2]                      << endl;                 cerr << predecessor[n2] << endl;               }               assert(predecessor[n2] == -1);               predecessor[n2] = n1;             }           }       }     }     assert(predecessor[0] == -1);     for (int i = (1); i < (N); i++) assert(predecessor[i] != -1);     cout <<  !  << endl << flush;     for (int i = (1); i < (N); i++)       cout << predecessor[i] + 1 <<     << i + 1 << endl;     return 0;   }