import sys

BOARD_SIZE = 9
EMPTY = 0
BLACK = 1
WHITE = 2

COL_LETTERS = 'ABCDEFGHJ'
ROW_NUMBERS = '123456789'

def create_board():
    return [[EMPTY] * BOARD_SIZE for _ in range(BOARD_SIZE)]

def print_board(board):
    # Print column letters
    sys.stdout.write('  ' + ' '.join(COL_LETTERS) + '\n')
    for r in range(BOARD_SIZE):
        sys.stdout.write(str(ROW_NUMBERS[r]) + ' ')
        for c in range(BOARD_SIZE):
            if board[r][c] == EMPTY:
                sys.stdout.write('. ')
            elif board[r][c] == BLACK:
                sys.stdout.write('B ')
            else:
                sys.stdout.write('W ')
        sys.stdout.write('\n')
    sys.stdout.flush()

def parse_move(move_str):
    move_str = move_str.strip().upper()
    if move_str == 'PASS':
        return 'pass'
    if len(move_str) != 2:
        return None
    col_char, row_char = move_str[0], move_str[1]
    if col_char not in COL_LETTERS or row_char not in ROW_NUMBERS:
        return None
    col = COL_LETTERS.index(col_char)
    row = ROW_NUMBERS.index(row_char)
    return (row, col)

def get_group(board, r, c):
    color = board[r][c]
    if color == EMPTY:
        return set()
    group = set()
    stack = [(r, c)]
    while stack:
        cr, cc = stack.pop()
        if (cr, cc) in group:
            continue
        group.add((cr, cc))
        for dr, dc in ((0,1),(0,-1),(1,0),(-1,0)):
            nr, nc = cr + dr, cc + dc
            if 0 <= nr < BOARD_SIZE and 0 <= nc < BOARD_SIZE:
                if board[nr][nc] == color and (nr, nc) not in group:
                    stack.append((nr, nc))
    return group

def get_liberties(board, group):
    liberties = set()
    for r, c in group:
        for dr, dc in ((0,1),(0,-1),(1,0),(-1,0)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < BOARD_SIZE and 0 <= nc < BOARD_SIZE:
                if board[nr][nc] == EMPTY:
                    liberties.add((nr, nc))
    return liberties

def remove_group(board, group):
    for r, c in group:
        board[r][c] = EMPTY

def remove_captured(board, color):
    opponent = WHITE if color == BLACK else BLACK
    captured = True
    while captured:
        captured = False
        visited = set()
        for r in range(BOARD_SIZE):
            for c in range(BOARD_SIZE):
                if board[r][c] == opponent and (r, c) not in visited:
                    group = get_group(board, r, c)
                    visited.update(group)
                    if len(get_liberties(board, group)) == 0:
                        remove_group(board, group)
                        captured = True
                        break  # restart scan after removal
            if captured:
                break

def is_legal_move(board, r, c, color):
    # Temporarily place stone
    board[r][c] = color
    # Remove captured opponent stones
    remove_captured(board, color)
    # Check own group liberties
    own_group = get_group(board, r, c)
    if len(get_liberties(board, own_group)) == 0:
        # Suicide: undo and return False
        board[r][c] = EMPTY
        # Also need to restore any captured stones? But we didn't capture any because own group has no liberties.
        # However, if we captured some, own group would have liberties. So no restoration needed.
        return False
    return True

def score(board):
    black_stones = 0
    white_stones = 0
    for r in range(BOARD_SIZE):
        for c in range(BOARD_SIZE):
            if board[r][c] == BLACK:
                black_stones += 1
            elif board[r][c] == WHITE:
                white_stones += 1
    # Territory counting
    visited = set()
    black_territory = 0
    white_territory = 0
    for r in range(BOARD_SIZE):
        for c in range(BOARD_SIZE):
            if board[r][c] == EMPTY and (r, c) not in visited:
                # BFS to find contiguous empty region
                region = set()
                stack = [(r, c)]
                adjacent_colors = set()
                while stack:
                    cr, cc = stack.pop()
                    if (cr, cc) in region:
                        continue
                    region.add((cr, cc))
                    for dr, dc in ((0,1),(0,-1),(1,0),(-1,0)):
                        nr, nc = cr + dr, cc + dc
                        if 0 <= nr < BOARD_SIZE and 0 <= nc < BOARD_SIZE:
                            if board[nr][nc] == EMPTY:
                                if (nr, nc) not in region:
                                    stack.append((nr, nc))
                            else:
                                adjacent_colors.add(board[nr][nc])
                visited.update(region)
                if adjacent_colors == {BLACK}:
                    black_territory += len(region)
                elif adjacent_colors == {WHITE}:
                    white_territory += len(region)
    black_score = black_stones + black_territory
    white_score = white_stones + white_territory
    return black_score, white_score

def main():
    board = create_board()
    current_player = BLACK
    consecutive_passes = 0
    while True:
        print_board(board)
        player_name = "Black" if current_player == BLACK else "White"
        move_str = input(f"{player_name}'s move (e.g., E5) or 'pass': ").strip()
        parsed = parse_move(move_str)
        if parsed == 'pass':
            consecutive_passes += 1
            if consecutive_passes >= 2:
                break
            current_player = WHITE if current_player == BLACK else BLACK
            continue
        elif parsed is None:
            print("Invalid move. Use format like E5 or 'pass'.")
            continue
        else:
            row, col = parsed
            if board[row][col] != EMPTY:
                print("That point is occupied. Choose another.")
                continue
            # Try the move
            if not is_legal_move(board, row, col, current_player):
                print("Suicide is not allowed. Choose another move.")
                continue
            # Move is legal and already applied (with captures) in is_legal_move
            consecutive_passes = 0
            current_player = WHITE if current_player == BLACK else BLACK
    # Game over
    print_board(board)
    black_score, white_score = score(board)
    print(f"Black score: {black_score}, White score: {white_score}")
    if black_score > white_score:
        print(f"Black wins by {black_score - white_score} points.")
    elif white_score > black_score:
        print(f"White wins by {white_score - black_score} points.")
    else:
        print("Tie.")

if __name__ == "__main__":
    main()
