from collections import defaultdict, deque
from copy import copy, deepcopy
 
def magicSum(n):
	return int((n*n * (n*n + 1)) / 6)
 
def validate(sumDict, n):
	for k, v in sumDict.items():
		if v > magicSum(n):
			return False
	return True
 
def check(sumDict, n):
	for k, v in sumDict.items():
		if v != magicSum(n):
			return False
	return True
 
def isValid(m, n):
	rowSum = defaultdict(int)
	colSum = defaultdict(int)
	diagSum = defaultdict(int)
 
	isLeft = False
 
	for i in range(n):
		for j in range(n):
			if m[i][j] == 0: isLeft = True
			rowSum[i] += m[i][j]
			colSum[j] += m[i][j]
			if i == j: diagSum[0] += m[i][j]
			if i + j == n - 1: diagSum[n - 1] += m[i][j]
 
	if isLeft:
		return (validate(rowSum, n) and validate(colSum, n) and validate(diagSum, n))		
	return (check(rowSum, n) and check(colSum, n) and check(diagSum, n))		
 
def next(cur, m, n):
	possible = []
	for i in range(n): 
		for j in range(n):
			if m[i][j] == 0:
				nextM = deepcopy(m)
				nextM[i][j] = cur
				if isValid(nextM, n):
					possible.append(nextM)
	return possible
 
def printM(m):
	for i in range(len(m)):
			print(m[i])
	print("\n\n")
 
def gen(n):
	startM = [[0 for x in range(n)] for y in range(n)]
	magic = []
	Q = deque([(1, startM)])
	while len(Q):
		state = Q.popleft()
		cur = state[0]
		m = state[1]
		if cur == n * n + 1:
			magic.append(m)
			printM(m)
			continue
		for w in next(cur, m, n):
			Q.append((cur + 1, w))
	return magic
 
magic = gen(3)
				ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVmYXVsdGRpY3QsIGRlcXVlCmZyb20gY29weSBpbXBvcnQgY29weSwgZGVlcGNvcHkKCmRlZiBtYWdpY1N1bShuKToKCXJldHVybiBpbnQoKG4qbiAqIChuKm4gKyAxKSkgLyA2KQoKZGVmIHZhbGlkYXRlKHN1bURpY3QsIG4pOgoJZm9yIGssIHYgaW4gc3VtRGljdC5pdGVtcygpOgoJCWlmIHYgPiBtYWdpY1N1bShuKToKCQkJcmV0dXJuIEZhbHNlCglyZXR1cm4gVHJ1ZQoJCmRlZiBjaGVjayhzdW1EaWN0LCBuKToKCWZvciBrLCB2IGluIHN1bURpY3QuaXRlbXMoKToKCQlpZiB2ICE9IG1hZ2ljU3VtKG4pOgoJCQlyZXR1cm4gRmFsc2UKCXJldHVybiBUcnVlCgkJCmRlZiBpc1ZhbGlkKG0sIG4pOgoJcm93U3VtID0gZGVmYXVsdGRpY3QoaW50KQoJY29sU3VtID0gZGVmYXVsdGRpY3QoaW50KQoJZGlhZ1N1bSA9IGRlZmF1bHRkaWN0KGludCkKCQoJaXNMZWZ0ID0gRmFsc2UKCQoJZm9yIGkgaW4gcmFuZ2Uobik6CgkJZm9yIGogaW4gcmFuZ2Uobik6CgkJCWlmIG1baV1bal0gPT0gMDogaXNMZWZ0ID0gVHJ1ZQoJCQlyb3dTdW1baV0gKz0gbVtpXVtqXQoJCQljb2xTdW1bal0gKz0gbVtpXVtqXQoJCQlpZiBpID09IGo6IGRpYWdTdW1bMF0gKz0gbVtpXVtqXQoJCQlpZiBpICsgaiA9PSBuIC0gMTogZGlhZ1N1bVtuIC0gMV0gKz0gbVtpXVtqXQoJCglpZiBpc0xlZnQ6CgkJcmV0dXJuICh2YWxpZGF0ZShyb3dTdW0sIG4pIGFuZCB2YWxpZGF0ZShjb2xTdW0sIG4pIGFuZCB2YWxpZGF0ZShkaWFnU3VtLCBuKSkJCQoJcmV0dXJuIChjaGVjayhyb3dTdW0sIG4pIGFuZCBjaGVjayhjb2xTdW0sIG4pIGFuZCBjaGVjayhkaWFnU3VtLCBuKSkJCQoJCmRlZiBuZXh0KGN1ciwgbSwgbik6Cglwb3NzaWJsZSA9IFtdCglmb3IgaSBpbiByYW5nZShuKTogCgkJZm9yIGogaW4gcmFuZ2Uobik6CgkJCWlmIG1baV1bal0gPT0gMDoKCQkJCW5leHRNID0gZGVlcGNvcHkobSkKCQkJCW5leHRNW2ldW2pdID0gY3VyCgkJCQlpZiBpc1ZhbGlkKG5leHRNLCBuKToKCQkJCQlwb3NzaWJsZS5hcHBlbmQobmV4dE0pCglyZXR1cm4gcG9zc2libGUKCmRlZiBwcmludE0obSk6Cglmb3IgaSBpbiByYW5nZShsZW4obSkpOgoJCQlwcmludChtW2ldKQoJcHJpbnQoIlxuXG4iKQoKZGVmIGdlbihuKToKCXN0YXJ0TSA9IFtbMCBmb3IgeCBpbiByYW5nZShuKV0gZm9yIHkgaW4gcmFuZ2UobildCgltYWdpYyA9IFtdCglRID0gZGVxdWUoWygxLCBzdGFydE0pXSkKCXdoaWxlIGxlbihRKToKCQlzdGF0ZSA9IFEucG9wbGVmdCgpCgkJY3VyID0gc3RhdGVbMF0KCQltID0gc3RhdGVbMV0KCQlpZiBjdXIgPT0gbiAqIG4gKyAxOgoJCQltYWdpYy5hcHBlbmQobSkKCQkJcHJpbnRNKG0pCgkJCWNvbnRpbnVlCgkJZm9yIHcgaW4gbmV4dChjdXIsIG0sIG4pOgoJCQlRLmFwcGVuZCgoY3VyICsgMSwgdykpCglyZXR1cm4gbWFnaWMKCm1hZ2ljID0gZ2VuKDMp