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

Measured memory_bytes: 109568