← Home
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()
	}
}