def valid_sudoku(board, complete=False):
    if len(board)!=9 or any(len(row)!=9 for row in board): return False
    if any(type(x) is not int or not 0<=x<=9 for row in board for x in row): return False
    groups=board + [list(c) for c in zip(*board)]
    groups += [[board[r+i][c+j] for i in range(3) for j in range(3)]
               for r in (0,3,6) for c in (0,3,6)]
    return all(len([x for x in g if x])==len(set(g)-{0})
               and (not complete or set(g)==set(range(1,10))) for g in groups)

def sudoku(board):
    b=[row[:] for row in board]
    if not valid_sudoku(b):
        print('Invalid givens'); return None
    def solve():
        empty=next(((r,c) for r in range(9) for c in range(9) if b[r][c]==0),None)
        if empty is None: return True
        r,c=empty
        for value in range(1,10):
            if value in b[r] or any(b[i][c]==value for i in range(9)): continue
            if any(b[i][j]==value for i in range(r//3*3,r//3*3+3)
                   for j in range(c//3*3,c//3*3+3)): continue
            b[r][c]=value
            if solve(): return True
            b[r][c]=0
        return False
    if not solve(): print('Unsolvable puzzle'); return None
    assert valid_sudoku(b,complete=True)
    for row in b: print(*row)
    return b



print("Enter 9 rows of 9 integers, separated by spaces. Use 0 for empty cells.")
puzzle = []
for r in range(9):
    row = list(map(int, input(f"Row {r + 1}: ").split()))
    if len(row) != 9 or any(not 0 <= value <= 9 for value in row):
        raise ValueError("Each row needs exactly 9 numbers from 0 to 9.")
    puzzle.append(row)
answer = sudoku(puzzle)
print("Solution found:", answer is not None)
if answer is not None:
    print("Final constraints verified:", valid_sudoku(answer, complete=True))
