import sys
import time
import random

# Piece values
PIECE_VALUES = {
    'P': 100, 'N': 320, 'B': 330, 'R': 500, 'Q': 900, 'K': 20000,
    'p': -100, 'n': -320, 'b': -330, 'r': -500, 'q': -900, 'k': -20000
}

# Position-based piece values (Simplified)
PAWN_TABLE = [
    0,  0,  0,  0,  0,  0,  0,  0,
    50, 50, 50, 50, 50, 50, 50, 50,
    10, 10, 20, 30, 30, 20, 10, 10,
     5,  5, 10, 25, 25, 10,  5,  5,
     0,  0,  0, 20, 20,  0,  0,  0,
     5, -5,-10,  0,  0,-10, -5,  5,
     5, 10, 10,-20,-20, 10, 10,  5,
     0,  0,  0,  0,  0,  0,  0,  0
]

KNIGHT_TABLE = [
    -50,-40,-30,-30,-30,-30,-40,-50,
    -40,-20,  0,  0,  0,  0,-20,-40,
    -30,  0, 10, 15, 15, 10,  0,-30,
    -30,  5, 15, 20, 20, 15,  5,-30,
    -30,  0, 15, 20, 20, 15,  0,-30,
    -30,  5, 10, 15, 15, 10,  5,-30,
    -40,-20,  0,  5,  5,  0,-20,-40,
    -50,-40,-30,-30,-30,-30,-40,-50
]

class Board:
    def __init__(self, fen=None):
        if fen:
            self.parse_fen(fen)
        else:
            self.parse_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")

    def parse_fen(self, fen):
        parts = fen.split()
        rows = parts[0].split('/')
        self.board = []
        for row in rows:
            board_row = []
            for char in row:
                if char.isdigit():
                    board_row.extend(['.'] * int(char))
                else:
                    board_row.append(char)
            self.board.append(board_row)
        
        self.turn = parts[1]
        self.castling = parts[2]
        self.en_passant = parts[3]
        self.halfmove_clock = int(parts[4])
        self.fullmove_number = int(parts[5])

    def get_piece(self, r, c):
        if 0 <= r < 8 and 0 <= c < 8:
            return self.board[r][c]
        return None

    def is_empty(self, r, c):
        return self.get_piece(r, c) == '.'

    def get_moves(self):
        moves = []
        for r in range(8):
            for c in range(8):
                piece = self.board[r][c]
                if piece == '.':
                    continue
                if (self.turn == 'w' and piece.isupper()) or (self.turn == 'b' and piece.islower()):
                    moves.extend(self.get_piece_moves(r, c))
        
        legal_moves = []
        for move in moves:
            if not self.leaves_king_in_check(move):
                legal_moves.append(move)
        return legal_moves

    def get_piece_moves(self, r, c):
        piece = self.board[r][c].lower()
        moves = []
        color = 'w' if self.board[r][c].isupper() else 'b'
        
        if piece == 'p':
            direction = -1 if color == 'w' else 1
            if self.is_empty(r + direction, c):
                if (color == 'w' and r + direction == 0) or (color == 'b' and r + direction == 7):
                    for p in 'qrbn':
                        moves.append(((r, c), (r + direction, c), p))
                else:
                    moves.append(((r, c), (r + direction, c), None))
                    if (color == 'w' and r == 6) or (color == 'b' and r == 1):
                        if self.is_empty(r + 2 * direction, c):
                            moves.append(((r, c), (r + 2 * direction, c), None))
            for dc in [-1, 1]:
                target_r, target_c = r + direction, c + dc
                target_piece = self.get_piece(target_r, target_c)
                if target_piece and target_piece != '.' and ((color == 'w' and target_piece.islower()) or (color == 'b' and target_piece.isupper())):
                    if (color == 'w' and target_r == 0) or (color == 'b' and target_r == 7):
                        for p in 'qrbn':
                            moves.append(((r, c), (target_r, target_c), p))
                    else:
                        moves.append(((r, c), (target_r, target_c), None))
                ep_square = self.en_passant
                if ep_square != '-':
                    ep_c = ord(ep_square[0]) - ord('a')
                    ep_r = 8 - int(ep_square[1])
                    if target_r == ep_r and target_c == ep_c:
                        moves.append(((r, c), (target_r, target_c), None))

        elif piece == 'n':
            for dr, dc in [(2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (1, -2), (-1, 2), (-1, -2)]:
                nr, nc = r + dr, c + dc
                target = self.get_piece(nr, nc)
                if target and (target == '.' or (color == 'w' and target.islower()) or (color == 'b' and target.isupper())):
                    moves.append(((r, c), (nr, nc), None))
        
        elif piece in 'brq':
            directions = []
            if piece in 'rq': directions.extend([(0, 1), (0, -1), (1, 0), (-1, 0)])
            if piece in 'bq': directions.extend([(1, 1), (1, -1), (-1, 1), (-1, -1)])
            for dr, dc in directions:
                nr, nc = r + dr, c + dc
                while True:
                    target = self.get_piece(nr, nc)
                    if not target: break
                    if target == '.':
                        moves.append(((r, c), (nr, nc), None))
                    else:
                        if (color == 'w' and target.islower()) or (color == 'b' and target.isupper()):
                            moves.append(((r, c), (nr, nc), None))
                        break
                    nr += dr
                    nc += dc

        elif piece == 'k':
            for dr in [-1, 0, 1]:
                for dc in [-1, 0, 1]:
                    if dr == 0 and dc == 0: continue
                    nr, nc = r + dr, c + dc
                    target = self.get_piece(nr, nc)
                    if target and (target == '.' or (color == 'w' and target.islower()) or (color == 'b' and target.isupper())):
                        moves.append(((r, c), (nr, nc), None))
            if color == 'w' and r == 7 and c == 4:
                if 'K' in self.castling and self.board[7][5] == '.' and self.board[7][6] == '.' and not self.is_attacked(7, 4, 'b') and not self.is_attacked(7, 5, 'b'):
                    moves.append(((7, 4), (7, 6), None))
                if 'Q' in self.castling and self.board[7][1] == '.' and self.board[7][2] == '.' and self.board[7][3] == '.' and not self.is_attacked(7, 4, 'b') and not self.is_attacked(7, 3, 'b'):
                    moves.append(((7, 4), (7, 2), None))
            elif color == 'b' and r == 0 and c == 4:
                if 'k' in self.castling and self.board[0][5] == '.' and self.board[0][6] == '.' and not self.is_attacked(0, 4, 'w') and not self.is_attacked(0, 5, 'w'):
                    moves.append(((0, 4), (0, 6), None))
                if 'q' in self.castling and self.board[0][1] == '.' and self.board[0][2] == '.' and self.board[0][3] == '.' and not self.is_attacked(0, 4, 'w') and not self.is_attacked(0, 3, 'w'):
                    moves.append(((0, 4), (0, 2), None))
                    
        return moves

    def is_attacked(self, r, c, by_color):
        original_turn = self.turn
        self.turn = by_color
        for row in range(8):
            for col in range(8):
                piece = self.board[row][col]
                if piece == '.': continue
                if (by_color == 'w' and piece.isupper()) or (by_color == 'b' and piece.islower()):
                    p = piece.lower()
                    if p == 'p':
                        direction = -1 if by_color == 'w' else 1
                        if r == row + direction and abs(c - col) == 1:
                            self.turn = original_turn
                            return True
                    elif p == 'k':
                        if abs(r - row) <= 1 and abs(c - col) <= 1:
                            self.turn = original_turn
                            return True
                    else:
                        for start, end, promo in self.get_piece_moves(row, col):
                            if end == (r, c):
                                self.turn = original_turn
                                return True
        self.turn = original_turn
        return False

    def leaves_king_in_check(self, move):
        start, end, promo = move
        sr, sc = start
        er, ec = end
        original_piece = self.board[er][ec]
        moving_piece = self.board[sr][sc]
        self.board[er][ec] = moving_piece if not promo else (promo.upper() if moving_piece.isupper() else promo.lower())
        self.board[sr][sc] = '.'
        king_piece = 'K' if self.turn == 'w' else 'k'
        opponent_color = 'b' if self.turn == 'w' else 'w'
        kr, kc = -1, -1
        for r in range(8):
            for c in range(8):
                if self.board[r][c] == king_piece:
                    kr, kc = r, c
                    break
        in_check = self.is_attacked(kr, kc, opponent_color)
        self.board[sr][sc] = moving_piece
        self.board[er][ec] = original_piece
        return in_check

    def make_move(self, move):
        start, end, promo = move
        sr, sc = start
        er, ec = end
        piece = self.board[sr][sc]
        if piece.lower() == 'k':
            if self.turn == 'w':
                self.castling = self.castling.replace('K', '').replace('Q', '')
                if sc == 4 and ec == 6:
                    self.board[7][5] = 'R'; self.board[7][7] = '.'
                elif sc == 4 and ec == 2:
                    self.board[7][3] = 'R'; self.board[7][0] = '.'
            else:
                self.castling = self.castling.replace('k', '').replace('q', '')
                if sc == 4 and ec == 6:
                    self.board[0][5] = 'r'; self.board[0][7] = '.'
                elif sc == 4 and ec == 2:
                    self.board[0][3] = 'r'; self.board[0][0] = '.'
        if piece == 'R':
            if sr == 7 and sc == 0: self.castling = self.castling.replace('Q', '')
            if sr == 7 and sc == 7: self.castling = self.castling.replace('K', '')
        elif piece == 'r':
            if sr == 0 and sc == 0: self.castling = self.castling.replace('q', '')
            if sr == 0 and sc == 7: self.castling = self.castling.replace('k', '')
        if piece.lower() == 'p' and self.en_passant != '-':
            ep_c = ord(self.en_passant[0]) - ord('a')
            ep_r = 8 - int(self.en_passant[1])
            if er == ep_r and ec == ep_c:
                self.board[sr][ec] = '.'
        if piece.lower() == 'p' and abs(er - sr) == 2:
            self.en_passant = chr(ord('a') + sc) + str(8 - (sr + er) // 2)
        else:
            self.en_passant = '-'
        self.board[er][ec] = piece if not promo else (promo.upper() if piece.isupper() else promo.lower())
        self.board[sr][sc] = '.'
        self.turn = 'b' if self.turn == 'w' else 'w'

    def evaluate(self):
        score = 0
        for r in range(8):
            for c in range(8):
                piece = self.board[r][c]
                if piece == '.': continue
                score += PIECE_VALUES[piece]
                if piece == 'P': score += PAWN_TABLE[r * 8 + c]
                elif piece == 'p': score -= PAWN_TABLE[(7 - r) * 8 + c]
                elif piece == 'N': score += KNIGHT_TABLE[r * 8 + c]
                elif piece == 'n': score -= KNIGHT_TABLE[(7 - r) * 8 + c]
        return score if self.turn == 'w' else -score

def move_to_uci(move):
    start, end, promo = move
    s = chr(ord('a') + start[1]) + str(8 - start[0])
    e = chr(ord('a') + end[1]) + str(8 - end[0])
    return s + e + (promo if promo else "")

def minimax(board, depth, alpha, beta, maximizing_player, start_time, time_limit):
    if depth == 0 or time.time() - start_time > time_limit:
        return board.evaluate()
    moves = board.get_moves()
    if not moves: return -100000 if maximizing_player else 100000
    if maximizing_player:
        max_eval = -float('inf')
        for move in moves:
            original_board = [row[:] for row in board.board]
            original_turn, original_castling, original_ep = board.turn, board.castling, board.en_passant
            board.make_move(move)
            eval = minimax(board, depth - 1, alpha, beta, False, start_time, time_limit)
            board.board, board.turn, board.castling, board.en_passant = original_board, original_turn, original_castling, original_ep
            max_eval = max(max_eval, eval)
            alpha = max(alpha, eval)
            if beta <= alpha: break
        return max_eval
    else:
        min_eval = float('inf')
        for move in moves:
            original_board = [row[:] for row in board.board]
            original_turn, original_castling, original_ep = board.turn, board.castling, board.en_passant
            board.make_move(move)
            eval = minimax(board, depth - 1, alpha, beta, True, start_time, time_limit)
            board.board, board.turn, board.castling, board.en_passant = original_board, original_turn, original_castling, original_ep
            min_eval = min(min_eval, eval)
            beta = min(beta, eval)
            if beta <= alpha: break
        return min_eval

def get_best_move(fen):
    board = Board(fen)
    moves = board.get_moves()
    if not moves: return None
    def move_score(m):
        target = board.board[m[1][0]][m[1][1]]
        return abs(PIECE_VALUES[target]) if target != '.' else 0
    moves.sort(key=move_score, reverse=True)
    best_move = moves[0]
    start_time = time.time()
    time_limit = 4.5
    for depth in range(1, 5):
        current_best_move, current_best_value = None, -float('inf')
        for move in moves:
            original_board = [row[:] for row in board.board]
            original_turn, original_castling, original_ep = board.turn, board.castling, board.en_passant
            board.make_move(move)
            val = minimax(board, depth - 1, -float('inf'), float('inf'), False, start_time, time_limit)
            board.board, board.turn, board.castling, board.en_passant = original_board, original_turn, original_castling, original_ep
            if val > current_best_value:
                current_best_value, current_best_move = val, move
            if time.time() - start_time > time_limit: break
        if current_best_move: best_move = current_best_move
        if time.time() - start_time > time_limit: break
    return move_to_uci(best_move)

def main():
    while True:
        line = sys.stdin.readline()
        if not line: break
        fen = line.strip()
        if not fen: continue
        try:
            move = get_best_move(fen)
            if move:
                sys.stdout.write(move + "\n")
                sys.stdout.flush()
        except:
            try:
                board = Board(fen)
                moves = board.get_moves()
                if moves:
                    sys.stdout.write(move_to_uci(random.choice(moves)) + "\n")
                    sys.stdout.flush()
            except: pass

if __name__ == "__main__":
    main()
