#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
inline void chkmin(T1 &x, const T2 &y) {
  if (x > y) x = y;
}
template <typename T1, typename T2>
inline void chkmax(T1 &x, const T2 &y) {
  if (x < y) x = y;
}
const long long MAXN = 51;
bool check(long long x1, long long y1, long long x2, long long y2, long long x,
           long long y) {
  return x1 <= x && x2 >= x && y1 <= y && y2 >= y;
}
long long n;
long long query(long long x1, long long y1, long long x2, long long y2) {
  cout << "? " << x1 + 1 << " " << y1 + 1 << " " << x2 + 1 << " " << y2 + 1
       << endl;
  long long ans;
  cin >> ans;
  return ans;
}
char get(long long x) { return x + '0'; }
void out_ans(vector<vector<long long> > table) {
  cout << "!" << endl;
  for (auto i : table) {
    for (auto j : i) {
      cout << j;
    }
    cout << endl;
  }
  exit(0);
}
void read() { cin >> n; }
void calc(vector<vector<long long> > &table, long long num) {
  vector<long long> dx = {2, 1, 0}, dy = {0, 1, 2};
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < n; j++) {
      if ((i + j) % 2 == num && table[i][j] != -1) {
        for (long long k = 0; k < 3; k++) {
          if (i + dx[k] < n && j + dy[k] < n &&
              table[i + dx[k]][j + dy[k]] == -1) {
            long long q = query(i, j, i + dx[k], j + dy[k]);
            table[i + dx[k]][j + dy[k]] = table[i][j] ^ 1 ^ q;
          }
        }
      }
    }
  }
}
vector<vector<vector<vector<long long> > > > dp1, dp2;
void make(vector<vector<vector<vector<long long> > > > &dp) {
  dp.assign(n,
            vector<vector<vector<long long> > >(
                n, vector<vector<long long> >(n, vector<long long>(n, false))));
}
void build(vector<vector<vector<vector<long long> > > > &dp,
           vector<vector<long long> > &table) {
  make(dp);
  for (long long x2 = 0; x2 < n; x2++) {
    for (long long y2 = 0; y2 < n; y2++) {
      for (long long x1 = x2; x1 >= 0; x1--) {
        for (long long y1 = y2; y1 >= 0; y1--) {
          if (table[x1][y1] != table[x2][y2]) continue;
          if (x2 - x1 + y2 - y1 <= 1) {
            dp[x1][y1][x2][y2] = true;
            continue;
          }
          vector<long long> dx1 = {1, 0}, dy1 = {0, 1};
          vector<long long> dx2 = {-1, 0}, dy2 = {0, -1};
          for (long long i = 0; i < 2; i++) {
            for (long long j = 0; j < 2; j++) {
              if (!check(x1, y1, x2, y2, x1 + dx1[i], y1 + dy1[i])) continue;
              if (!check(x1, y1, x2, y2, x2 + dx2[j], y2 + dy2[j])) continue;
              dp[x1][y1][x2][y2] |=
                  dp[x1 + dx1[i]][y1 + dy1[i]][x2 + dx2[j]][y2 + dy2[j]];
            }
          }
        }
      }
    }
  }
}
vector<vector<long long> > ans;
void run() {
  vector<vector<long long> > table1(n, vector<long long>(n, -1)),
      table2(n, vector<long long>(n, -1));
  table1[0][0] = 1;
  table1[n - 1][n - 1] = 0;
  calc(table1, 0);
  table1[0][1] = 0;
  calc(table1, 1);
  long long q = query(1, 0, 1, 2);
  table1[1][0] = table1[1][2] ^ 1 ^ q;
  calc(table1, 1);
  table2 = table1;
  for (long long i = 0; i < n; i++)
    for (long long j = 0; j < n; j++)
      if ((i + j) % 2 == 1) table2[i][j] ^= 1;
  build(dp1, table1);
  build(dp2, table2);
  for (long long x2 = 0; x2 < n; x2++) {
    for (long long y2 = 0; y2 < n; y2++) {
      for (long long x1 = x2; x1 >= 0; x1--) {
        for (long long y1 = y2; y1 >= 0; y1--) {
          if (x2 - x1 + y2 - y1 <= 1) continue;
          if (dp1[x1][y1][x2][y2] != dp2[x1][y1][x2][y2]) {
            long long q = query(x1, y1, x2, y2);
            if (q == dp1[x1][y1][x2][y2]) {
              ans = table1;
            } else {
              ans = table2;
            }
            return;
          }
        }
      }
    }
  }
  assert(false);
}
void write() { out_ans(ans); }
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  read();
  run();
  write();
  return 0;
}
