import sys import heapq def solve(): data = sys.stdin.read().split() height = int(data[0]) width = int(data[1]) grid = [data[i + 2] for i in range(height)] INF = float('inf') distances = {} priority_queue = [] def update_state(state, cost): if distances.get(state, INF) > cost: distances[state] = cost heapq.heappush(priority_queue, (cost, state)) # State format: # ('R', row, col, can_use_row, can_use_col) update_state(('R', 0, 0, True, True), 0) while priority_queue: current_cost, state = heapq.heappop(priority_queue) if current_cost > distances.get(state, INF): continue state_type = state[0] if state_type == 'R': _, row, col, can_row, can_col = state # Check goal if row == height - 1 and col == width - 1: print(current_cost) return # Move in 4 directions for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: new_r, new_c = row + dr, col + dc if 0 <= new_r < height and 0 <= new_c < width: if grid[new_r][new_c] != '#': update_state(('R', new_r, new_c, can_row, can_col), current_cost + 1) # Activate vertical range move if can_row: if row > 0: update_state(('VR', row - 1, col, can_col), current_cost + 1) if row < height - 1: update_state(('VR', row, col, can_col), current_cost + 1) # Activate horizontal range move if can_col: if col > 0: update_state(('VC', row, col - 1, can_row), current_cost + 1) if col < width - 1: update_state(('VC', row, col, can_row), current_cost + 1) elif state_type == 'VR': _, row, col, can_col = state # Move left/right for dc in [-1, 1]: new_c = col + dc if 0 <= new_c < width: update_state(('VR', row, new_c, can_col), current_cost + 1) # Convert back to normal mode if grid[row][col] != '#': update_state(('R', row, col, False, can_col), current_cost + 1) if row + 1 < height and grid[row + 1][col] != '#': update_state(('R', row + 1, col, False, can_col), current_cost + 1) # Switch to full expansion if can_col: update_state(('VX', row, col), current_cost + 1) elif state_type == 'VC': _, row, col, can_row = state # Move up/down for dr in [-1, 1]: new_r = row + dr if 0 <= new_r < height: update_state(('VC', new_r, col, can_row), current_cost + 1) # Convert back to normal mode if grid[row][col] != '#': update_state(('R', row, col, can_row, False), current_cost + 1) if col + 1 < width and grid[row][col + 1] != '#': update_state(('R', row, col + 1, can_row, False), current_cost + 1) # Switch to full expansion if can_row: update_state(('VX', row, col), current_cost + 1) else: # 'VX' _, row, col = state # Move in all directions for dr, dc in [(-1,0),(1,0),(0,-1),(0,1)]: new_r, new_c = row + dr, col + dc if 0 <= new_r < height and 0 <= new_c < width: update_state(('VX', new_r, new_c), current_cost + 1) # Return to normal mode from 2x2 area for r2 in [row, row + 1]: for c2 in [col, col + 1]: if 0 <= r2 < height and 0 <= c2 < width: if grid[r2][c2] != '#': update_state(('R', r2, c2, False, False), current_cost + 1) print(-1) if __name__ == "__main__": solve()