package main
import (
"fmt"
"os"
)
var memo []int
var memoID int
func init() {
memo = make([]int, 55*55*55*55)
}
func is_pal(g [][]int, r1, c1, r2, c2 int) bool {
memoID++
var solve func(x1, y1, x2, y2 int) bool
solve = func(x1, y1, x2, y2 int) bool {
if x1 > x2 || y1 > y2 {
return false
}
if x1 == x2 && y1 == y2 {
return true
}
if x2-x1+y2-y1 == 1 {
return g[x1][y1] == g[x2][y2]
}
if g[x1][y1] != g[x2][y2] {
return false
}
state := x1*55*55*55 + y1*55*55 + x2*55 + y2
if memo[state] == memoID {
return true
} else if memo[state] == -memoID {
return false
}
res := solve(x1+1, y1, x2-1, y2) ||
solve(x1+1, y1, x2, y2-1) ||
solve(x1, y1+1, x2-1, y2) ||
solve(x1, y1+1, x2, y2-1)
if res {
memo[state] = memoID
} else {
memo[state] = -memoID
}
return res
}
return solve(r1, c1, r2, c2)
}
func main() {
var n int
fmt.Scan(&n)
grid := make([][]int, n+1)
for i := 1; i <= n; i++ {
grid[i] = make([]int, n+1)
}
grid[1][1] = 1
ask := func(r1, c1, r2, c2 int) int {
fmt.Printf("? %d %d %d %d\n", r1, c1, r2, c2)
var res int
fmt.Scan(&res)
if res == -1 {
os.Exit(0)
}
return res
}
for r := 1; r <= n; r++ {
for c := 1; c <= n; c++ {
if (r+c)%2 != 0 {
continue
}
if r == 1 && c == 1 {
continue
}
if r == n && c == n {
grid[n][n] = 0
continue
}
if c >= 3 {
ans := ask(r, c-2, r, c)
if ans == 1 {
grid[r][c] = grid[r][c-2]
} else {
grid[r][c] = 1 - grid[r][c-2]
}
} else if r >= 3 {
ans := ask(r-2, c, r, c)
if ans == 1 {
grid[r][c] = grid[r-2][c]
} else {
grid[r][c] = 1 - grid[r-2][c]
}
} else {
ans := ask(r-1, c-1, r, c)
if ans == 1 {
grid[r][c] = grid[r-1][c-1]
} else {
grid[r][c] = 1 - grid[r-1][c-1]
}
}
}
}
grid[1][2] = 1
for r := 1; r <= n; r++ {
for c := 1; c <= n; c++ {
if (r+c)%2 == 0 {
continue
}
if r == 1 && c == 2 {
continue
}
if r == 2 && c == 1 {
continue
}
if r == 2 && c == 3 {
ans := ask(1, 2, 2, 3)
if ans == 1 {
grid[2][3] = grid[1][2]
} else {
grid[2][3] = 1 - grid[1][2]
}
ans2 := ask(2, 1, 2, 3)
if ans2 == 1 {
grid[2][1] = grid[2][3]
} else {
grid[2][1] = 1 - grid[2][3]
}
} else if c >= 3 {
ans := ask(r, c-2, r, c)
if ans == 1 {
grid[r][c] = grid[r][c-2]
} else {
grid[r][c] = 1 - grid[r][c-2]
}
} else if r >= 3 {
ans := ask(r-2, c, r, c)
if ans == 1 {
grid[r][c] = grid[r-2][c]
} else {
grid[r][c] = 1 - grid[r-2][c]
}
}
}
}
found := false
var q_r1, q_c1, q_r2, q_c2 int
var sim1 bool
for length := 3; length <= 2*n && !found; length++ {
for r1 := 1; r1 <= n && !found; r1++ {
for c1 := 1; c1 <= n && !found; c1++ {
for r2 := r1; r2 <= n && !found; r2++ {
c2 := c1 + length - (r2 - r1)
if c2 >= c1 && c2 <= n {
g0 := make([][]int, n+1)
g1 := make([][]int, n+1)
for i := 1; i <= n; i++ {
g0[i] = make([]int, n+1)
g1[i] = make([]int, n+1)
for j := 1; j <= n; j++ {
g0[i][j] = grid[i][j]
g1[i][j] = grid[i][j]
if (i+j)%2 != 0 {
g1[i][j] = 1 - g1[i][j]
}
}
}
res0 := is_pal(g0, r1, c1, r2, c2)
res1 := is_pal(g1, r1, c1, r2, c2)
if res0 != res1 {
found = true
q_r1, q_c1, q_r2, q_c2 = r1, c1, r2, c2
sim1 = res1
}
}
}
}
}
}
if found {
ans := ask(q_r1, q_c1, q_r2, q_c2)
var flip int
if (ans == 1) == sim1 {
flip = 1
} else {
flip = 0
}
if flip == 1 {
for i := 1; i <= n; i++ {
for j := 1; j <= n; j++ {
if (i+j)%2 != 0 {
grid[i][j] = 1 - grid[i][j]
}
}
}
}
}
fmt.Println("!")
for r := 1; r <= n; r++ {
for c := 1; c <= n; c++ {
fmt.Print(grid[r][c])
}
fmt.Println()
}
}