'''
0401 PA05
21800279 Seonyeong Park
Polyomino Puzzle: To find a solution of puzzle for given polyominos
'''
import numpy as np
import math
import copy
#input
n = int(input())
blocks = []
count = 0
for i in range(n):
h,w = [int(x) for x in input().split()]
blocks.append([(h,w)])
for j in range(h):
line = [int(x) for x in input().split()]
for b in line:
if b == 1:
count+=1
blocks[i].append(line)
def check(c):
if s == int(s):
for block in blocks:
for line in block[0]:
if line > s:
return False
return int(s)
return False
def puzzle(num,ans,row,col):
b = blocks[num]
h,w = b[0]
res = copy.deepcopy(ans)
for i in range(h):
for j in range(w):
if b[i+1][j] == 1:
if ans[row+i][col+j] == 0:
res[row+i][col+j] = num+1
else:
return False
for i in range(side):
for j in range(side):
if res[i][j] == 0:
return [res, i, j]
return [res, i, j]
def polyomino(pro,ans,num=0,row=0,col=0,put=[],turn=0):
if len(put) == n:
return ans
if turn == n:
return False
if num == n: num -= n
block = blocks[num]
if num in put:
if num == put[-1]:
ans, row, col = copy.deepcopy(pro[len(put)-1])
if num == turn:
turn +=1
return polyomino(pro[:-1], ans, num+1,row,col,put[:-1],turn)
else:
return polyomino(pro,ans,num+1,row,col,put,turn)
h,w = block[0]
if row+h > side:
return polyomino(pro,ans,num+1,row,col,put,turn)
else:
start = 0 if col+1-w <= 0 else col+1-w
result = puzzle(num,ans,row,start)
while result == False and start+w < side :
start += 1
result = puzzle(num,ans,row,start)
if result == False:
return polyomino(pro,ans,num+1,row,col,put,turn)
else:
put.append(num)
pro.append(result)
ans, row, col = result
return polyomino(pro,ans, num+1,row,col,put,turn)
#---------------------------------------------------------------------------------#
side = check(count) #the side of the panel
if side == False:
print("No solution possible")
else:
process = []
answer = np.zeros([side,side], dtype="i").tolist()
process.append([copy.deepcopy(answer),0,0])
answer = polyomino(process,answer)
if answer == False:
print("No solution possible")
else:
for line in answer:
print(' '.join(map(str, line)))
JycnCjA0MDEgUEEwNQoyMTgwMDI3OSBTZW9ueWVvbmcgUGFyawpQb2x5b21pbm8gUHV6emxlOiBUbyBmaW5kIGEgc29sdXRpb24gb2YgcHV6emxlIGZvciBnaXZlbiBwb2x5b21pbm9zCicnJwppbXBvcnQgbnVtcHkgYXMgbnAKaW1wb3J0IG1hdGgKaW1wb3J0IGNvcHkKCiNpbnB1dApuID0gaW50KGlucHV0KCkpCmJsb2NrcyA9IFtdCmNvdW50ID0gMApmb3IgaSBpbiByYW5nZShuKToKICAgIGgsdyA9IFtpbnQoeCkgZm9yIHggaW4gaW5wdXQoKS5zcGxpdCgpXQogICAgYmxvY2tzLmFwcGVuZChbKGgsdyldKQogICAgZm9yIGogaW4gcmFuZ2UoaCk6CiAgICAgICAgbGluZSA9IFtpbnQoeCkgZm9yIHggaW4gaW5wdXQoKS5zcGxpdCgpXQogICAgICAgIGZvciBiIGluIGxpbmU6CiAgICAgICAgICAgIGlmIGIgPT0gMToKICAgICAgICAgICAgICAgIGNvdW50Kz0xCiAgICAgICAgYmxvY2tzW2ldLmFwcGVuZChsaW5lKQogICAgICAgIApkZWYgY2hlY2soYyk6CiAgICBzID0gbWF0aC5zcXJ0KGMpCiAgICBpZiBzID09IGludChzKToKICAgICAgICBmb3IgYmxvY2sgaW4gYmxvY2tzOgogICAgICAgICAgICBmb3IgbGluZSBpbiBibG9ja1swXToKICAgICAgICAgICAgICAgIGlmIGxpbmUgPiBzOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIHJldHVybiBpbnQocykKICAgIHJldHVybiBGYWxzZQoKZGVmIHB1enpsZShudW0sYW5zLHJvdyxjb2wpOgogICAgYiA9IGJsb2Nrc1tudW1dCiAgICBoLHcgPSBiWzBdCiAgICByZXMgPSBjb3B5LmRlZXBjb3B5KGFucykKICAgIGZvciBpIGluIHJhbmdlKGgpOgogICAgICAgIGZvciBqIGluIHJhbmdlKHcpOgogICAgICAgICAgICBpZiBiW2krMV1bal0gPT0gMToKICAgICAgICAgICAgICAgIGlmIGFuc1tyb3craV1bY29sK2pdID09IDA6CiAgICAgICAgICAgICAgICAgICAgcmVzW3JvdytpXVtjb2wral0gPSBudW0rMQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgIGZvciBpIGluIHJhbmdlKHNpZGUpOgogICAgICAgIGZvciBqIGluIHJhbmdlKHNpZGUpOgogICAgICAgICAgICBpZiByZXNbaV1bal0gPT0gMDoKICAgICAgICAgICAgICAgIHJldHVybiBbcmVzLCBpLCBqXQogICAgcmV0dXJuIFtyZXMsIGksIGpdCgpkZWYgcG9seW9taW5vKHBybyxhbnMsbnVtPTAscm93PTAsY29sPTAscHV0PVtdLHR1cm49MCk6CiAgICBpZiBsZW4ocHV0KSA9PSBuOgogICAgICAgIHJldHVybiBhbnMKICAgIGlmIHR1cm4gPT0gbjoKICAgICAgICByZXR1cm4gRmFsc2UKICAgIGlmIG51bSA9PSBuOiBudW0gLT0gbiAKICAgIGJsb2NrID0gYmxvY2tzW251bV0KICAgIGlmIG51bSBpbiBwdXQ6CiAgICAgICAgaWYgbnVtID09IHB1dFstMV06CiAgICAgICAgICAgIGFucywgcm93LCBjb2wgPSBjb3B5LmRlZXBjb3B5KHByb1tsZW4ocHV0KS0xXSkKICAgICAgICAgICAgaWYgbnVtID09IHR1cm46CiAgICAgICAgICAgICAgICB0dXJuICs9MQogICAgICAgICAgICByZXR1cm4gcG9seW9taW5vKHByb1s6LTFdLCBhbnMsIG51bSsxLHJvdyxjb2wscHV0WzotMV0sdHVybikKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gcG9seW9taW5vKHBybyxhbnMsbnVtKzEscm93LGNvbCxwdXQsdHVybikKICAgIGgsdyA9IGJsb2NrWzBdCiAgICBpZiByb3craCA+IHNpZGU6CiAgICAgICAgcmV0dXJuIHBvbHlvbWlubyhwcm8sYW5zLG51bSsxLHJvdyxjb2wscHV0LHR1cm4pCiAgICBlbHNlOgogICAgICAgIHN0YXJ0ID0gMCBpZiBjb2wrMS13IDw9IDAgZWxzZSBjb2wrMS13CiAgICAgICAgcmVzdWx0ID0gcHV6emxlKG51bSxhbnMscm93LHN0YXJ0KQogICAgICAgIHdoaWxlIHJlc3VsdCA9PSBGYWxzZSBhbmQgc3RhcnQrdyA8IHNpZGUgIDoKICAgICAgICAgICAgc3RhcnQgKz0gMQogICAgICAgICAgICByZXN1bHQgPSBwdXp6bGUobnVtLGFucyxyb3csc3RhcnQpCiAgICAgICAgaWYgcmVzdWx0ID09IEZhbHNlOgogICAgICAgICAgICByZXR1cm4gcG9seW9taW5vKHBybyxhbnMsbnVtKzEscm93LGNvbCxwdXQsdHVybikKICAgICAgICBlbHNlOgogICAgICAgICAgICBwdXQuYXBwZW5kKG51bSkKICAgICAgICAgICAgcHJvLmFwcGVuZChyZXN1bHQpCiAgICAgICAgICAgIGFucywgcm93LCBjb2wgPSByZXN1bHQKICAgICAgICAgICAgcmV0dXJuIHBvbHlvbWlubyhwcm8sYW5zLCBudW0rMSxyb3csY29sLHB1dCx0dXJuKQogICAgICAgIAojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIyAgICAKc2lkZSA9IGNoZWNrKGNvdW50KSAgICAgICAgI3RoZSBzaWRlIG9mIHRoZSBwYW5lbAppZiBzaWRlID09IEZhbHNlOgogICAgcHJpbnQoIk5vIHNvbHV0aW9uIHBvc3NpYmxlIikKZWxzZToKICAgIHByb2Nlc3MgPSBbXQogICAgYW5zd2VyID0gbnAuemVyb3MoW3NpZGUsc2lkZV0sIGR0eXBlPSJpIikudG9saXN0KCkKICAgIHByb2Nlc3MuYXBwZW5kKFtjb3B5LmRlZXBjb3B5KGFuc3dlciksMCwwXSkKICAgIGFuc3dlciA9IHBvbHlvbWlubyhwcm9jZXNzLGFuc3dlcikKICAgIGlmIGFuc3dlciA9PSBGYWxzZToKICAgICAgICBwcmludCgiTm8gc29sdXRpb24gcG9zc2libGUiKQogICAgZWxzZToKICAgICAgICBmb3IgbGluZSBpbiBhbnN3ZXI6CiAgICAgICAgICAgIHByaW50KCcgJy5qb2luKG1hcChzdHIsIGxpbmUpKSkK