E= enumerate
def f( b) :
d= { ( x, y) :v for x, r in E( b) for y, v in E( r) } ; p= { i for i in d if d[ i] *~ -all ( d.get ( ( i[ 0 ] +X, i[ 1 ] +Y) ) for X in [ -1 , 0 , 1 ] for Y in [ -1 , 0 , 1 ] if X*Y) } ; q, t= [ ( [ ] , p) ] , [ ]
for r, p in q:
if not p:return len ( r)
Q= [ [ M:= min ( p) ] ] ; p-= { M} ; S= [ [ M] ]
for R in Q:
for a in [ -1 , 0 ] :
if d.get ( V:= ( R[ a] [ 0 ] , R[ a] [ 1 ] -a+~ a) ) and ( Z:= [ [ V] +R, R+[ V] ] [ a] ) not in S:Q+= Z,; S+= Z,
F, T= [ [ i] for i in S] , { }
for R in F:
n= [ ( x+1 , y) for x, y in R[ -1 ] ]
if all ( d.get ( N) for N in n) :F+= R+[ n] ,
else :T[ e] = T.get ( e:= sum ( map ( len , R) ) , [ ] ) +[ R]
q+= [ ( r+[ R] , p-{ j for k in R for j in k} ) for I in T for R in T[ I] ]
s = """
[[1]] -> 1
[[1,1]] -> 1
[[1],[1]] -> 1
[[1,0,1]] -> 2
[[1,0],[0,0]] -> 1
[[1,0],[0,1]] -> 2
[[1,0],[1,1]] -> 2
[[1,1,1],[1,0,1]] -> 3
[[0,1,0],[1,1,1],[0,1,0]] -> 2
[[1,1,1],[1,0,1],[1,1,1]] -> 4
[[1,1,0],[1,1,1],[0,1,1]] -> 2
[[1,0,1,0],[1,1,1,1],[1,0,1,0]] -> 3
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,0]] -> 4
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,1]] -> 5
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,1,1,1]] -> 4
[[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]] -> 3
[[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]] -> 4
[[0,0,1,0,0],[0,1,1,1,0],[1,1,1,1,1],[0,1,1,1,0],[0,0,1,0,0]] -> 3
[[1, 1, 0, 0, 0, 1, 1, 0], [1, 1, 1, 1, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 0], [1, 1, 0, 1, 1, 1, 0, 1]] -> 7
[[0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]] -> 2
"""
for i in filter ( None , s.split ( '\n ' ) ) :
a, b = map ( eval , i.split ( ' -> ' ) )
assert f( a) == b
print ( 'tests passed!' )
RT1lbnVtZXJhdGUKZGVmIGYoYik6CiBkPXsoeCx5KTp2IGZvciB4LHIgaW4gRShiKWZvciB5LHYgaW4gRShyKX07cD17aSBmb3IgaSBpbiBkIGlmIGRbaV0qfi1hbGwoZC5nZXQoKGlbMF0rWCxpWzFdK1kpKWZvciBYIGluWy0xLDAsMV1mb3IgWSBpblstMSwwLDFdaWYgWCpZKX07cSx0PVsoW10scCldLFtdCiBmb3IgcixwIGluIHE6CiAgaWYgbm90IHA6cmV0dXJuIGxlbihyKQogIFE9W1tNOj1taW4ocCldXTtwLT17TX07Uz1bW01dXQogIGZvciBSIGluIFE6CiAgIGZvciBhIGluWy0xLDBdOgogICAgaWYgZC5nZXQoVjo9KFJbYV1bMF0sUlthXVsxXS1hK35hKSlhbmQoWjo9W1tWXStSLFIrW1ZdXVthXSlub3QgaW4gUzpRKz1aLDtTKz1aLAogIEYsVD1bW2ldZm9yIGkgaW4gU10se30KICBmb3IgUiBpbiBGOgogICBuPVsoeCsxLHkpZm9yIHgseSBpbiBSWy0xXV0KICAgaWYgYWxsKGQuZ2V0KE4pZm9yIE4gaW4gbik6Ris9Uitbbl0sCiAgIGVsc2U6VFtlXT1ULmdldChlOj1zdW0obWFwKGxlbixSKSksW10pK1tSXQogIHErPVsocitbUl0scC17aiBmb3IgayBpbiBSIGZvciBqIGluIGt9KWZvciBJIGluIFQgZm9yIFIgaW4gVFtJXV0KICAKcyA9ICIiIgpbWzFdXSAtPiAxCltbMSwxXV0gLT4gMQpbWzFdLFsxXV0gLT4gMQpbWzEsMCwxXV0gLT4gMgpbWzEsMF0sWzAsMF1dIC0+IDEKW1sxLDBdLFswLDFdXSAtPiAyCltbMSwwXSxbMSwxXV0gLT4gMgpbWzEsMSwxXSxbMSwwLDFdXSAtPiAzCltbMCwxLDBdLFsxLDEsMV0sWzAsMSwwXV0gLT4gMgpbWzEsMSwxXSxbMSwwLDFdLFsxLDEsMV1dIC0+IDQKW1sxLDEsMF0sWzEsMSwxXSxbMCwxLDFdXSAtPiAyCltbMSwwLDEsMF0sWzEsMSwxLDFdLFsxLDAsMSwwXV0gLT4gMwpbWzEsMSwxLDBdLFsxLDAsMSwwXSxbMSwxLDEsMV0sWzAsMCwxLDBdXSAtPiA0CltbMSwxLDEsMF0sWzEsMCwxLDBdLFsxLDEsMSwxXSxbMCwwLDEsMV1dIC0+IDUKW1sxLDEsMSwwXSxbMSwwLDEsMF0sWzEsMSwxLDFdLFswLDEsMSwxXV0gLT4gNApbWzEsMSwwLDBdLFsxLDEsMSwwXSxbMCwxLDEsMV0sWzAsMCwxLDFdXSAtPiAzCltbMCwxLDAsMF0sWzAsMSwxLDFdLFsxLDEsMSwwXSxbMCwwLDEsMF1dIC0+IDQKW1swLDAsMSwwLDBdLFswLDEsMSwxLDBdLFsxLDEsMSwxLDFdLFswLDEsMSwxLDBdLFswLDAsMSwwLDBdXSAtPiAzCltbMSwgMSwgMCwgMCwgMCwgMSwgMSwgMF0sIFsxLCAxLCAxLCAxLCAwLCAxLCAxLCAxXSwgWzAsIDEsIDEsIDEsIDAsIDEsIDEsIDFdLCBbMSwgMSwgMCwgMSwgMSwgMSwgMSwgMF0sIFsxLCAxLCAwLCAxLCAxLCAxLCAwLCAxXV0gLT4gNwpbWzAsIDEsIDEsIDEsIDEsIDFdLCBbMSwgMSwgMSwgMSwgMSwgMV0sIFsxLCAxLCAxLCAxLCAxLCAxXV0gLT4gMgoiIiIKZm9yIGkgaW4gZmlsdGVyKE5vbmUsIHMuc3BsaXQoJ1xuJykpOgoJYSwgYiA9IG1hcChldmFsLCBpLnNwbGl0KCcgLT4gJykpCglhc3NlcnQgZihhKSA9PSBiCgpwcmludCgndGVzdHMgcGFzc2VkIScp