https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AYEXgKnKKg0DFARx
from collections import deque
T = int(input())
dRow = [-1,1,0,0]
dCol = [0,0,-1,1]
# 상 하 좌 우
def sol(T,board):
visited = [[False] * len(board[0]) for _ in range(len(board))]
queue = deque()
for i in range(len(board)):
for j in range(len(board[i])):
if(board[i][j]!='?'):
queue.append([i,j,board[i][j]])
# board 에서 이미 칠해진 칸을 큐에 넣는다.
visited[i][j] = True
if(len(queue)==0):
print('#{0} {1}'.format(T,"possible"))
return
while(len(queue)>0): #bfs실행
[r,c,v] = queue.popleft()
for i in range(4):
nr = r+dRow[i]
nc = c+dCol[i]
if nr>=0 and nc>=0 and nr<len(board) and nc<len(board[0]): #유효성검사
if board[nr][nc] == '?': #인접한 칸이 빈 칸일 경우 board[r][c]의 색과 반대색으로 칠한다.
board[nr][nc] = "#" if board[r][c]=="." else "."
visited[nr][nc] = True
queue.append([nr,nc,board[nr][nc]])
else:
if board[nr][nc] == board[r][c]: #인접한 칸의 색이 이미 칠해져 있을 경우, board[r][c]의 색과 반대 색이면 ok, 같은 색이면 impossible
print('#{0} {1}'.format(T,"impossible"))
return
print('#{0} {1}'.format(T,"possible"))
return
for i in range(1,T+1):
[N,M] = list(map(int, input().split()))
board = []
for j in range(N):
line = list(input())
board.append(line)
sol(i,board)