Problem:
 Score : 400 points    Problem Statement Takahashi has a maze, which is a grid of H \times W squares with H horizontal rows and W vertical columns.  The square at the i -th row from the top and the j -th column is a "wall" square if S_{ij} is # , and a "road" square if S_{ij} is . .  From a road square, you can move to a horizontally or vertically adjacent road square.  You cannot move out of the maze, move to a wall square, or move diagonally.  Takahashi will choose a starting square and a goal square, which can be any road squares, and give the maze to Aoki.  Aoki will then travel from the starting square to the goal square, in the minimum number of moves required.  In this situation, find the maximum possible number of moves Aoki has to make.      Constraints  1 \leq H,W \leq 20  S_{ij} is . or # .  S contains at least two occurrences of . .  Any road square can be reached from any road square in zero or more moves.         Input Input is given from Standard Input in the following format:  H  W  S_{11} ... S_{1W}  :  S_{H1} ... S_{HW}       Output Print the maximum possible number of moves Aoki has to make.        Sample Input 1 3 3
...
...
...      Sample Output 1 4  If Takahashi chooses the top-left square as the starting square and the bottom-right square as the goal square, Aoki has to make four moves.       Sample Input 2 3 5
...#.
.#.#.
.#...      Sample Output 2 10  If Takahashi chooses the bottom-left square as the starting square and the top-right square as the goal square, Aoki has to make ten moves.

Solution (Python):
class Grid:
    def __init__(self, H, W, grid, road_wall=(".", "
        self.road, self.wall = road_wall
        self.H = H
        self.W = W
        self.grid = grid
        self.parent = [[-1] * self.W for _ in range(self.H)]
        self.move = [(1, 0), (-1, 0), (0, 1), (0, -1)]     

    def bfs(self, start=(0,0), goal=-3, time=0, save=False):
        """
        :param start: スタート地点
        :param goal: ゴール地点
        :param save: True = 前回の探索結果を保持する
        :return: （ループがあっても）最短距離。存在しなければ -1
        """
        if save:
            parent = self.parent
        else:
            parent = [[-1] * self.W for _ in range(self.H)]
        p, t = start, time
        parent[p[0]][p[1]] = -2
        next_set = deque([(p, t)])
        while next_set:
            p, t = next_set.popleft()
            h, w = p
            for dh, dw in self.move:
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if self.grid[q[0]][q[1]] == self.wall:         
                    continue
                if parent[q[0]][q[1]] != -1:
                    continue
                
                
                
                if q == goal:
                    return t + 1
                parent[q[0]][q[1]] = p
                next_set.append((q, t + 1))
        return -1

    def connection_counter(self):
        """
        :return: 連結成分の個数。有効グラフではあまり意味がない。
        """
        cnt = 0
        self.parent = [[-1] * self.W for _ in range(self.H)]
        for h in range(self.H):
            for w in range(self.W):
                if self.parent[h][w] == -1:
                    cnt += 1
                    self.bfs(start=(h,w), save=True)
        return cnt

    def distance_list(self, start=(0,0), save=False):
        """
        :param start: スタート地点
        :return: スタート地点から各点への距離のリスト
        """
        dist = [[-1] * self.W for _ in range(self.H)]
        if save:
            parent = self.parent
        else:
            parent = [[-1] * self.W for _ in range(self.H)]
        p, t = start, 0
        parent[p[0]][p[1]] = -2
        dist[p[0]][p[1]] = 0
        next_set = deque([(p, t)])

        while next_set:
            p, t = next_set.popleft()
            h, w = p
            for dh, dw in self.move:
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if self.grid[q[0]][q[1]] == self.wall:         
                    continue
                if parent[q[0]][q[1]] != -1:
                    continue
                dist[q[0]][q[1]] = t + 1
                parent[q[0]][q[1]] = p
                next_set.append((q, t + 1))
        return dist

    def most_distant_point(self, start=(0, 0), save=False):
        """
        :param start:
        :return: start 地点から最も遠い点を ((h,w), 距離) として出力
        """
        res = (start, 0)
        temp = 0
        dist = self.distance_list(start, save=save)
        for h in range(self.H):
            for w in range(self.W):
                if dist[h][w] > temp:
                    temp = dist[h][w]
                    res = ((h, w), temp)
        return res

    def diameter(self, start=(0,0), save=False):
        """
        :return:　木の直系（最も離れた二頂点間の距離）を返す
        """
        p = self.most_distant_point(start, save=False)
        res = self.most_distant_point(start=p[0], save=save)
        return res[1]

    def diameter2(self):
        """
        :return:　連結ではない時に、最大の直系を返す
        """
        res = 0
        for h in range(self.H):
            for w in range(self.W):
                if self.grid[h][w] == self.road and self.parent[h][w] == -1:
                    temp = self.diameter(start=(h, w), save=False)
                    if temp > res:
                        res = temp
        return res

    def dfs(self, start=(0, 0), goal=-3, time=0, save=False):
        """
        :param start: スタート地点
        :param goal: ゴール地点
        :param save: True = 前回の探索結果を保持する
        :return: ゴール地点までの距離。存在しなければ -1。ループがある時は最短距離とは限らないため注意。
        """

        if save:
            parent = self.parent
        else:
            parent = [[-1] * self.W for _ in range(self.H)]
        move2 = [[marshal.loads(marshal.dumps(self.move)) for _ in range(self.W)] for _ in range(self.H)]

        p, t = start, time
        parent[p[0]][p[1]] = -2
        while True:
            if move2[p[0]][p[1]]:
                h, w = p
                dh, dw = move2[p[0]][p[1]].pop()
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if self.grid[q[0]][q[1]] == self.wall:         
                    continue
                if q == parent[p[0]][p[1]]:
                    """ 逆流した時の処理 """
                    """"""""""""""""""""
                    continue
                if parent[q[0]][q[1]] != -1:
                    """ サイクルで同一点を訪れた時の処理 """
                    """"""""""""""""""""
                    continue
                
                
                
                
                if q == goal:
                    """ ゴール時の処理"""
                    """"""""""""""""""""
                    return t + 1
                """ p から q への引継ぎ"""
                """"""""""""""""""""
                parent[q[0]][q[1]] = p
                p, t = q, t + 1
            else:
                if p == start and t == time:
                    break
                p_temp = p
                p, t = parent[p[0]][p[1]], t-1
                """ p から進める点がもう無い時の点 p における処理 """
                
                
                """"""""""""""""""""
                """ 点 p から親ノードに戻ってきた時の親ノードにおける処理 """
                """"""""""""""""""""
        return -1

    def dfs2(self, start=(0, 0), goal=-3, time=0):
        visited = [[-1] * self.W for _ in range(self.H)]
        p, t = start, time
        res = 0
        def rec(p, past_p, t, visited, res):
            h, w = p
            visited[p[0]][p[1]] = 1
            for dh, dw in self.move:
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if grid[q[0]][q[1]] == self.wall:
                    continue
                if q == past_p:
                    """ 逆流した時の処理 """
                    """"""""""""""""""""
                    continue
                if visited[q[0]][q[1]] == 1:
                    """ サイクルで同一点を訪れた時の処理 """
                    """"""""""""""""""""
                    continue
                """ (debug code) """
                
                
                """"""""""""""""""""
                if q == goal:
                    """ ゴール時の処理"""
                    """"""""""""""""""""
                    return t+1
                res = max2(rec(q, p, t + 1, visited, res), t + 1)
            """ 帰り際の処置（壊した道を元に戻す等)"""
            
            """"""""""""""""""""
            return res
        return rec(p, -1, t, visited, res)

    def debug(self, start, goal, p, t):
        player = p
        debug_grid = list(list(self.grid[h]) for h in range(self.H))
        if start != (None, None):
            debug_grid[start[0]][start[1]] = "S"
        if goal != -3:
            debug_grid[goal[0]][goal[1]] = "G"
        debug_grid[player[0]][player[1]] = "P"
        print("~~~~~~~~~ t = " + str(t + 1) + "  ~~~~~~~~")
        for debug_h in range(self.H):
            print("".join(str(debug_grid[debug_h][debug_w]) for debug_w in range(self.W)))

    def show_visited(self, start, goal, p, t, parent):
        player = p
        debug_grid = list(list(self.grid[h]) for h in range(self.H))
        for h in range(H):
            for w in range(W):
                if parent[h][w] != -1:
                    debug_grid[h][w] = "V"
        if start != (None, None):
            debug_grid[start[0]][start[1]] = "S"
        if goal != -3:
            debug_grid[goal[0]][goal[1]] = "G"
        debug_grid[player[0]][player[1]] = "P"
        print("~~~~~~~~~ t = " + str(t + 1) + "  ~~~~~~~~")
        for debug_h in range(self.H):
            print("".join(str(debug_grid[debug_h][debug_w]) for debug_w in range(self.W)))



from collections import deque
import sys
import marshal
input = sys.stdin.readline



road, wall = ".", "

H, W = map(int,input().split())                

grid = []
for h in range(H):
    grid.append(input().rstrip())

g = Grid(H, W, grid, (road, wall))

print(g.diameter2())

Solution (Python):
import queue
h,w=map(int,input().split())
s=[input() for _ in range(h)]
INF=10**18
dx=[-1,0,1,0]
dy=[0,-1,0,1]
ans=0
for i in range(h):
  for j in range(w):
    if s[i][j]=='
    d=[[INF]*w for _ in range(h)]
    d[i][j]=0
    q=queue.Queue()
    q.put((i,j))
    while not q.empty():
      x,y=q.get()
      for k in range(4):
        nx=x+dx[k]
        ny=y+dy[k]
        if 0<=nx<h and 0<=ny<w:
          if s[nx][ny]=='.' and d[nx][ny]==INF:
            q.put((nx,ny))
            d[nx][ny]=d[x][y]+1
            ans=max(ans,d[nx][ny])
print(ans)

Solution (Python):




'''''''''''''''''''''
grid[h][w]

    w=0 w=1 w=2
h=0
h=1
h=2
'''''''''''''''''''''


class Grid:
    def __init__(self, H, W, grid, road_wall=(".", "
        self.road, self.wall = road_wall
        self.H = H
        self.W = W
        self.destroy = destroy
        self.grid = grid
        self.parent = [[(-1,-1)] * self.W for _ in range(self.H)]
        self.move = [(1, 0), (-1, 0), (0, 1), (0, -1)]     

    def bfs(self, start=(0,0), goal=(-1,-1), time=0, save=False):
        """
        :param start: スタート地点
        :param goal: ゴール地点
        :param save: True = 前回の探索結果を保持する
        :return: （ループがあっても）最短距離。存在しなければ -1
        """
        if not save:
            self.parent = [(-1, -1) * self.W for _ in range(self.H)]
        p, t = start, time
        self.parent[p[0]][p[1]] = (-2,-2)
        next_set = deque([(p, t)])
        while next_set:
            p, t = next_set.popleft()
            h, w = p
            for dh, dw in self.move:
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if self.grid[q[0]][q[1]] == self.wall:         
                    continue
                if self.parent[q[0]][q[1]] != (-1, -1):
                    continue
                
                
                
                if q == goal:
                    return t + 1
                self.parent[q[0]][q[1]] = p
                next_set.append((q, t + 1))
        return -1

    def connection_counter(self):
        """
        :return: 連結成分の個数。有効グラフではあまり意味がない。
        """
        cnt = 0
        self.parent = [[(-1,-1)] * self.W for _ in range(self.H)]
        for h in range(self.H):
            for w in range(self.W):
                if self.parent[h][w] == (-1, -1):
                    cnt += 1
                    self.bfs(start=(h,w), save=True)
        return cnt

    def distance_list(self, start=(0,0), save=False):
        """
        :param start: スタート地点
        :return: スタート地点から各点への距離のリスト
        """
        dist = [[-1] * self.W for _ in range(self.H)]
        if save:
            parent = self.parent
        else:
            parent = [[(-1, -1)] * self.W for _ in range(self.H)]
        p, t = start, 0
        parent[p[0]][p[1]] = (-2, -2)
        dist[p[0]][p[1]] = 0
        next_set = deque([(p, t)])

        while next_set:
            p, t = next_set.popleft()
            h, w = p
            for dh, dw in self.move:
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if self.grid[q[0]][q[1]] == self.wall:         
                    continue
                if parent[q[0]][q[1]] != (-1, -1):
                    continue
                dist[q[0]][q[1]] = t + 1
                parent[q[0]][q[1]] = p
                next_set.append((q, t + 1))
        return dist

    def most_distant_point(self, start=(0, 0), save=False):
        """
        :param start:
        :return: start 地点から最も遠い点を ((h,w), 距離) として出力
        """
        res = (start, 0)
        temp = 0
        dist = self.distance_list(start, save=save)
        for h in range(self.H):
            for w in range(self.W):
                if dist[h][w] > temp:
                    temp = dist[h][w]
                    res = ((h, w), temp)
        return res

    def diameter(self, start=(0,0), save=False):
        """
        :return:　木の直系（最も離れた二頂点間の距離）を返す
        """
        p = self.most_distant_point(start, save=False)
        res = self.most_distant_point(start=p[0], save=save)
        return res[1]

    def diameter2(self):
        """
        :return:　連結ではない時に、最大の直系を返す
        """
        res = 0
        for h in range(self.H):
            for w in range(self.W):
                if self.grid[h][w] == self.road and self.parent[h][w] == (-1, -1):
                    temp = self.diameter(start=(h, w), save=False)
                    if temp > res:
                        res = temp
        return res

    def dfs(self, start=(0, 0), goal=(-1, -1), time=0, save=False):
        """
        :param start: スタート地点
        :param goal: ゴール地点
        :param save: True = 前回の探索結果を保持する
        :return: ゴール地点までの距離。存在しなければ -1。ループがある時は最短距離とは限らないため注意。
        """

        if not save:
            self.parent = [[(-1, -1)] * self.W for _ in range(self.H)]
        move2 = [[marshal.loads(marshal.dumps(self.move)) for _ in range(self.W)] for _ in range(self.H)]

        p, t = start, time
        self.parent[p[0]][p[1]] = (-2, -2)
        while True:
            if move2[p]:
                dh, dw = move2[p].pop()
                q = (h + dh, w + dw)
                if q[0] < 0 or q[0] >= self.H or q[1] < 0 or q[1] >= self.W:
                    continue
                if self.grid[q[0]][q[1]] == self.wall:         
                    continue
                if q == self.parent[p[0]][p[1]]:
                    """ 逆流した時の処理 """
                    """"""""""""""""""""
                    continue
                if self.parent[q[0]][q[1]] != (-1, -1):
                    """ サイクルで同一点を訪れた時の処理 """
                    """"""""""""""""""""
                    continue
                
                
                
                if q == goal:
                    """ ゴール時の処理"""
                    return t + 1
                    """"""""""""""""""""
                """ p から q への引継ぎ"""
                """"""""""""""""""""
                self.parent[q[0]][q[1]] = p
                p, t = q, t + 1
            else:
                """ p から進める点がもう無い時の点 p における処理 """
                """"""""""""""""""""
                if p == start and t == time:
                    break
                p, t = self.parent[p[0]][p[1]], t-1
                """ 点 p から親ノードに戻ってきた時の親ノードにおける処理 """
                """"""""""""""""""""
        return -1



    def debug(self, start, goal, p, t):
        player = p
        debug_grid = list(list(self.grid[h]) for h in range(self.H))
        if start != (None, None):
            debug_grid[start[0]][start[1]] = "S"
        if goal != (None, None):
            debug_grid[goal[0]][goal[1]] = "G"
        debug_grid[player[0]][player[1]] = "P"
        print("~~~~~~~~~ t = " + str(t + 1) + "  ~~~~~~~~")
        for debug_h in range(self.H):
            print("".join(str(debug_grid[debug_h][debug_w]) for debug_w in range(self.W)))



from collections import deque
import sys
import marshal
input = sys.stdin.readline



road_wall = (".", "

H, W = map(int,input().split())                

grid = []
for h in range(H):
    grid.append(input().rstrip())

g = Grid(H, W, grid, road_wall, destroy=False)

print(g.diameter2())

Solution (Python):
import queue
h,w=map(int,input().split())
s=[input() for _ in range(h)]
INF=10**18
dx=[-1,0,1,0]
dy=[0,-1,0,1]
ans=0
for i in range(h):
  for j in range(w):
    if s[i][j]=='
    d=[[INF]*w for _ in range(h)]
    d[i][j]=0
    q=queue.Queue()
    q.put((i,j))
    while not q.empty():
      x,y=q.get()
      for k in range(4):
        nx=x+dx[k]
        ny=y+dy[k]
        if 0<=nx<h and 0<=ny<w:
          if s[nx][ny]=='.' and d[nx][ny]==INF:
            q.put((nx,ny))
            d[nx][ny]=d[x][y]+1
            ans=max(ans,d[nx][ny])
print(ans)

Solution (Python):
h,w=map(int,input().split())
g=[input() for _ in range(h)]
from collections import *
def bfs(x,y):
  d=[[-1]*w for _ in range(h)]
  d[x][y]=0
  q=deque([(x,y)])
  while q:
    tx,ty=q.popleft()
    for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
      nx,ny=tx+dx,ty+dy
      if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
        r=d[nx][ny]=d[tx][ty]+1
        q.append((nx,ny))
  return r
print(max(bfs(x,y) for x in range(h) for y in range(w) if g[x][y]=='.'))

Solution (Python):


from collections import deque


def main():
    height, width = [int(num) for num in input().split()]
    maze = [input() for _ in range(height)]

    ans = 0
    next_to = ((0, 1), (1, 0), (0, -1), (-1, 0))

    for start_x in range(height):
        for start_y in range(width):
            if maze[start_x][start_y] == '
                continue
            queue = deque()
            queue.append((start_x, start_y))
            reached = [[-1] * width for _ in range(height)]
            reached[start_x][start_y] = 0

            while queue:
                now_x, now_y = queue.popleft()
                for move_x, move_y in next_to:
                    adj_x, adj_y = now_x + move_x, now_y + move_y
                    
                    
                    if (not 0 <= adj_x < height
                            or not 0 <= adj_y < width
                            or maze[adj_x][adj_y] == '
                            or reached[adj_x][adj_y] != -1):
                        continue
                    queue.append((adj_x, adj_y))
                    reached[adj_x][adj_y] = reached[now_x][now_y] + 1
            most_distant = max(max(row) for row in reached)
            ans = max(most_distant, ans)
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
'''''''''''''''''''''
grid[h][w]

    w=0 w=1 w=2
h=0
h=1
h=2
'''''''''''''''''''''

from collections import deque
import sys
sys.setrecursionlimit(10 ** 8)
input = sys.stdin.readline
move = [(1, 0), (-1, 0), (0, 1), (0, -1)]     


def debug(start, goal, p, t):
    player = p
    debug_grid = list(list(grid[h]) for h in range(H))
    if start != (None, None):
        debug_grid[start[0]][start[1]] = "S"
    if goal != (None, None):
        debug_grid[goal[0]][goal[1]] = "G"
    debug_grid[player[0]][player[1]] = "P"
    print("~~~~~~~~~ t = " + str(t+1) + "  ~~~~~~~~")
    for debug_h in range(H):
        print("".join(str(debug_grid[debug_h][debug_w]) for debug_w in range(W)))


def distance_list(grid, visit, start, goal=(None,None)):
    dist = [[-1] * W for _ in range(H)]
    dist[start[0]][start[1]] = 0
    visit[start[0]][start[1]] = 1
    next_set = deque([(start, 0)])
    while next_set:
        p, t = next_set.popleft()
        h, w = p
        for dh, dw in move:
            q = (h + dh, w + dw)
            if q[0] < 0 or q[0] >= H or q[1] < 0 or q[1] >= W:
                continue
            if grid[q[0]][q[1]] == wall:
                continue
            if visit[q[0]][q[1]] == 1:
                continue
            
            
            
            if q == goal:
                return t + 1
            visit[q[0]][q[1]] = 1
            dist[q[0]][q[1]] = t+1
            next_set.append((q, t + 1))
    return dist


def most_distant_point(grid, visit, start=(0,0)):
    res = (start, 0)
    temp = 0
    dist = distance_list(grid, visit, start)
    for h in range(H):
        for w in range(W):
            if dist[h][w] > temp:
                temp = dist[h][w]
                res = ((h,w), temp)
    return res


def diameter(grid, visit, start=(0,0)):
    visit = [[0] * W for _ in range(H)]
    p = most_distant_point(grid, visit, start)
    visit = [[0]*W for _ in range(H)]
    res = most_distant_point(grid, visit, start=p[0])
    return res[1]


def diameter2(grid):
    res = 0
    for h in range(H):
        for w in range(W):
            if grid[h][w] == road and visit[h][w] == 0:
                temp = diameter(grid, visit, (h,w))
                if temp > res:
                    res =temp
    return res








road, wall = ".", "

H,W = map(int,input().split())                

grid = []
for h in range(H):
    grid.append(input().rstrip())                

visit = [[0]*W for _ in range(H)]
res = diameter2(grid)           

print(res)

Solution (Python):
h,w=map(int,input().split())
g=[input() for _ in range(h)]
from collections import *
def bfs(x,y):
  d=[[-1]*w for _ in range(h)]
  d[x][y]=0
  q=deque([(x,y)])
  while q:
    tx,ty=q.popleft()
    for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
      nx,ny=tx+dx,ty+dy
      if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
        r=d[nx][ny]=d[tx][ty]+1
        q.append((nx,ny))
  return r
print(max(bfs(x,y) for x in range(h) for y in range(w) if g[x][y]=='.'))

Solution (Python):
h,w=map(int,input().split())
g=[input() for _ in range(h)]
from collections import *
def bfs(sx,sy):
  d=[[-1]*w for _ in range(h)]
  d[sx][sy]=0
  q=deque([(sx,sy)])
  while q:
    x,y=q.popleft()
    for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
      nx,ny=x+dx,y+dy
      if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
        r=d[nx][ny]=d[x][y]+1
        q.append((nx,ny))
  return r
print(max(bfs(x,y) for x in range(h) for y in range(w) if g[x][y]=='.'))

Solution (Python):
h,w=map(int,input().split())
g=[input() for _ in range(h)]
from collections import *
def bfs(sx,sy):
  d=[[-1]*w for _ in range(h)]
  d[sx][sy]=0
  q=deque([(sx,sy)])
  while q:
    x,y=q.popleft()
    for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
      nx,ny=x+dx,y+dy
      if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
        r=d[nx][ny]=d[x][y]+1
        q.append((nx,ny))
  return r
print(max(bfs(sx,sy) for sx in range(h) for sy in range(w) if g[sx][sy]=='.'))

Solution (Python):
h,w=map(int,input().split())
g=[[*input()] for _ in range(h)]
from collections import *
def bfs(sx,sy):
  d=[[-1]*w for _ in range(h)]
  d[sx][sy]=0
  q=deque([(sx,sy)])
  while q:
    x,y=q.popleft()
    t=d[x][y]+1
    for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
      nx,ny=x+dx,y+dy
      if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
        d[nx][ny]=t
        q.append((nx,ny))
  return d
import numpy as np
a=0
for sx in range(h):
  for sy in range(w):
    if g[sx][sy]=='
    a=max(a,np.max(bfs(sx,sy)))
print(a)

Solution (Python):
h,w=map(int,input().split())
g=[[*input()] for _ in range(h)]
from collections import *
a=0
for sx in range(h):
  for sy in range(w):
    if g[sx][sy]=='
    d=[[-1]*w for _ in range(h)]
    d[sx][sy]=0
    q=deque([(sx,sy)])
    while q:
      x,y=q.popleft()
      t=d[x][y]+1
      for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
        nx,ny=x+dx,y+dy
        if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
          d[nx][ny]=t
          q.append((nx,ny))
          a=max(a,t)
print(a)

Solution (Python):
h,w=map(int,input().split())
g=[input() for _ in range(h)]
import numpy as np
from collections import *
a=0
for sx in range(h):
  for sy in range(w):
    if g[sx][sy]=='
    d=[[-1]*w for _ in range(h)]
    d[sx][sy]=0
    q=deque([(sx,sy)])
    while q:
      x,y=q.popleft()
      for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
        nx,ny=x+dx,y+dy
        if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
          d[nx][ny]=d[x][y]+1
          q.append((nx,ny))
    a=max(a,np.max(d))
print(a)

Solution (Python):
h,w=map(int,input().split())
g=[[*input()] for _ in range(h)]
from collections import *
a=0
for sx in range(h):
  for sy in range(w):
    if g[sx][sy]=='
    d=[[-1]*w for _ in range(h)]
    d[sx][sy]=0
    q=deque([(sx,sy)])
    while q:
      x,y=q.popleft()
      for dx,dy in [(1,0),(0,1),(-1,0),(0,-1)]:
        nx,ny=x+dx,y+dy
        if 0<=nx<h and 0<=ny<w and g[nx][ny]=='.' and d[nx][ny]<0:
          d[nx][ny]=d[x][y]+1
          q.append((nx,ny))
    a=max(a,max(max(i for i in l) for l in d))
print(a)

Solution (Python):
from queue import Queue
import copy

h, w = map(int, input().split())

f = [["
    [list("
    [["
dxy = [(0,1), (0,-1), (1,0), (-1,0)]

d = [[-1]*(w+2) for i in range(h+2)]
for iy in range(h+2):
    for ix in range(w+2):
        if f[iy][ix] == '
            d[iy][ix] = 1000

ans = 0
for sy in range(h+2):
    for sx in range(w+2):
        if f[sy][sx] == '
            continue
        dist = copy.deepcopy(d)
        cnt = 0
        cnt_max = 0
        q = Queue()
        q.put([sy, sx])
        dist[sy][sx] = 0
        while q.qsize():
            y, x = q.get()
            cnt = dist[y][x]
            
            
            cnt_max = max(cnt_max, cnt)
            for dy, dx in dxy:
                ny, nx = y + dy, x + dx
                if dist[ny][nx] == 1000:
                    continue
                if dist[ny][nx] == -1:
                    q.put([ny, nx])
                    dist[ny][nx] = cnt + 1
        
        ans = max(ans, cnt_max)
print(ans)

Solution (Python):
from queue import Queue
import copy

h, w = map(int, input().split())

f = [["
    [list("
    [["
dxy = [(0,1), (0,-1), (1,0), (-1,0)]

d = [[-1]*(w+2) for i in range(h+2)]
for iy in range(h+2):
    for ix in range(w+2):
        if f[iy][ix] == '
            d[iy][ix] = 1000

ans = 0
for sy in range(h+2):
    for sx in range(w+2):
        if f[sy][sx] == '
            continue
        dist = copy.deepcopy(d)
        cnt = 0
        cnt_max = 0
        q = Queue()
        q.put([sy, sx])
        dist[sy][sx] = 0
        while q.qsize():
            y, x = q.get()
            cnt = dist[y][x]
            
            
            cnt_max = max(cnt_max, cnt)
            for dy, dx in dxy:
                ny, nx = y + dy, x + dx
                if dist[ny][nx] == 1000:
                    continue
                if dist[ny][nx] == -1:
                    q.put([ny, nx])
                    dist[ny][nx] = cnt + 1
        
        ans = max(ans, cnt_max)
print(ans)

Solution (Python):
h,w = map(int,input().split())
L = [[]*w for i in range(h)]

for i in range(h):
    L[i] = list("
L = [["


from collections import deque
ans = 0
q = deque([])
for j in range(1,h+1):
    for i in range(1,w+1):
        cost = [[-1]*(w+2) for i in range(h+2)]
        li = ((1,0),(0,1),(-1,0),(0,-1))
        
        if L[j][i] == ".":
            cost[j][i] = 0
        cost_max = 0
        q.append((j,i))
        while q:
            
            r,s = q.popleft()
            
            for dh,dw in li:
                nh,nw = r+dh,s+dw
                
                if L[nh][nw] =="." and cost[nh][nw] == -1 :
                    cost[nh][nw] = cost[r][s] + 1
                    
                    
                    cost_max = max(cost_max,cost[nh][nw])
                    q.append((nh,nw))
        ans = max(ans,cost_max)
print(ans)

Solution (Python):
from collections import deque

def getMaxDistance(s,startY,startX):
  d = deque()
  distances = [[0 for _ in range(w)] for j in range(h)]
  dx = [-1, 0, 1, 0]
  dy = [0, 1, 0, -1]
  maxDistance = 0
  d.append(startX)
  d.append(startY)
  while d:
    x = d.popleft()
    y = d.popleft()
    if s[y][x]=='
    maxDistance = max(maxDistance, distances[y][x])
    for i in range(4):
      xx = x + dx[i]
      yy = y + dy[i]
      if not (0 <= yy < h and 0 <= xx < w): continue
      if s[yy][xx] != '.': continue
      if distances[yy][xx] != 0: continue
      if xx == startX and yy == startY: continue
      d.append(xx)
      d.append(yy)
      distances[yy][xx] = distances[y][x] + 1
  return maxDistance

h,w=map(int,input().split())
s=[list(input()) for _ in range(h)]
maxDistance = 0
for i in range(h):
  for j in range(w):
    maxDistance = max(maxDistance, getMaxDistance(s,i,j))
print(maxDistance)

Solution (Python):
from collections import deque

def main():
    H,W=map(int,input().split())
    S=[]
    for i in range(H):
        s=input()
        S.append(s)

    G=[]
    for i in range(H):
        for j in range(W):
            tmp=[]
            if S[i][j]=="
                G.append(tmp)
                continue
            if i-1>=0:
                if S[i-1][j]==".":
                    tmp.append((i-1)*W+j)
            if i+1<=H-1:
                if S[i+1][j]==".":
                    tmp.append((i+1)*W+j)
            if j-1>=0:
                if S[i][j-1]==".":
                    tmp.append(i*W+j-1)
            if j+1<=W-1:
                if S[i][j+1]==".":
                    tmp.append(i*W+j+1)
            G.append(tmp)

    res=0

    for start in range(H*W):
        dist = 0
        v = [-1 for _ in range(H * W)]
        que=deque([])
        que.append(start)
        v[start]=dist
        while len(que)>0:
            next_index=que.popleft()
            next=G[next_index]
            for i in next:
                if v[i]==-1:
                    que.append(i)
                    v[i]=v[next_index]+1

        if max(v)>=res:
            res=max(v)

    print(res)


if __name__=="__main__":
    main()