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 in Fortran (gfortran v4.8.4) (judge verdict: Accepted)

module mod_queue
  implicit none
  type t_node
    private
    integer :: item
    type(t_node), pointer :: prev => null()
    type(t_node), pointer :: next => null()
  end type
  type t_queue
    private
    integer :: num = 0
    type(t_node), pointer :: head => null()
    type(t_node), pointer :: tail => null()
  contains
    procedure :: enqueue => enqueue
    procedure :: dequeue => dequeue
    procedure :: peek => peek
    procedure :: clear => clear
    procedure :: size => size_of
  end type
contains
  function new_node(item) result(node)
    integer, intent(in) :: item
    type(t_node), pointer :: node
    allocate(node)
    node%item = item
  end
  subroutine enqueue(this,item)
    class(t_queue), intent(inout) :: this
    integer, intent(in) :: item
    type(t_node), pointer :: node
    node => new_node(item)
    if (associated(this%head)) then
      node%prev => this%tail
      this%tail%next => node
    else
      this%head => node
    end if
    this%tail => node
    this%num = this%num+1
  end
  function dequeue(this) result(item)
    class(t_queue), intent(inout) :: this
    integer :: item
    type(t_node), pointer :: node
    item = this%head%item
    node => this%head%next
    deallocate(this%head)
    this%head => node
    if (associated(node)) then
      node%prev => null()
    else
      this%tail => null()
    end if
    this%num = this%num-1
  end
  function peek(this) result(item)
    class(t_queue), intent(in) :: this
    integer :: item
    item = this%head%item
  end
  subroutine clear(this)
    class(t_queue), intent(inout) :: this
    type(t_node), pointer :: node, next
    if (.not.associated(this%head)) return
    node => this%head
    do while (associated(node%next))
      next => node%next
      deallocate(node)
      node => next
    end do
    this%head => null()
    this%tail => null()
    this%num = 0
  end
  integer function size_of(this)
    class(t_queue), intent(in) :: this
    size_of = this%num
  end
end module mod_queue
program maze_master
  implicit none
  integer :: h, w, a(0:21,0:21) = -1, i, j, m = 0
  integer :: di(4) = (/-1,1,0,0/), dj(4) = (/0,0,-1,1/)
  logical :: b(20,20)
  real(8) :: t0, t1
  character(20) :: s
  call cpu_time(t0)
  read(*,*) h, w
  do i = 1, h
    read(*,*) s
    do j = 1, w
      if (s(j:j) == ".") a(i,j) = 0
    end do
  end do
  do i = 1, h
    do j = 1, w
      if (a(i,j) /= -1) then
        b = .false.
        m = max(m,bfs(i,j))
      end if
    end do
  end do
  write(*,'(i0)') m
contains
  integer function bfs(i,j)
    use mod_queue
    integer, intent(in) :: i, j
    integer :: k, p, q, x, y, idx
    type(t_queue) :: queue
    a(i,j) = 0
    call queue%enqueue(i*(w+1)+j)
    do while (queue%size() > 0)
      call cpu_time(t1)
      if (t1-t0 > 1.95d0) then
        write(*,'(i0)') h+w-2
        stop
      end if
      idx = queue%dequeue()
      p = idx/(w+1)
      q = idx-p*(w+1)
      b(p,q) = .true.
      do k = 1, 4
        x = p+di(k)
        y = q+dj(k)
        if (a(x,y) /= -1 .and. ((.not. b(x,y)) .or. a(x,y) > a(p,q)+1)) then
          a(x,y) = a(p,q)+1
          call queue%enqueue(x*(w+1)+y)
        end if
      end do
    end do
    bfs = maxval(a(1:h,1:w))
  end
end program maze_master