module deque_mod
    use,intrinsic :: iso_fortran_env
    implicit none
    type deque
        integer(int32),pointer:: v(:)
        integer(int32):: l,r
        integer(int32):: lmax, rmax
    contains
        procedure:: append => dq_append
        procedure:: appendleft => dq_appendleft
        procedure:: pop => dq_pop
        procedure:: popleft => dq_popleft
        procedure:: right => dq_right
        procedure:: left => dq_left
        procedure:: remaining_elements => dq_remaining_elements
        procedure:: remain => dq_remain
    end type

    interface deque
        procedure:: dq_init
    end interface
contains
    function dq_init() result(dq)
        ! コンストラクタ
        type(deque):: dq
        dq%r=0; dq%rmax=1
        dq%l=1; dq%lmax=-1
        allocate(dq%v(dq%lmax:dq%rmax))
    end function


    subroutine dq_append(dq,num)
        ! 右端に挿入
        class(deque):: dq
        integer(int32):: num
        if (dq%r+1 > dq%rmax) call dq_add_(dq)
        dq%r=dq%r+1
        dq%v(dq%r) = num
    end subroutine

    subroutine dq_appendleft(dq,num)
        ! 左端に挿入
        class(deque):: dq
        integer(int32):: num
        if (dq%l-1 < dq%lmax) call dq_add_(dq)
        dq%l=dq%l-1
        dq%v(dq%l) = num
    end subroutine

    subroutine dq_add_(dq)
        ! arrayの延長
        class(deque):: dq
        integer(int32):: l
        integer(int32),pointer:: tmp(:)
        l = size(dq%v)
        allocate(tmp(l))
        tmp(:) = dq%v(:)
        deallocate(dq%v)
        allocate(dq%v(2*dq%lmax:2*dq%rmax))
        dq%v(dq%lmax:dq%rmax) = tmp(:)
        dq%lmax = 2*dq%lmax
        dq%rmax = 2*dq%rmax
    end subroutine


    function dq_pop(dq) result(ret)
        ! 右端から取り出し
        class(deque):: dq
        integer(int32):: ret
        ret = dq%v(dq%r)
        dq%r=dq%r-1
    end function

    function dq_popleft(dq) result(ret)
        ! 左端から取り出し
        class(deque):: dq
        integer(int32):: ret
        ret = dq%v(dq%l)
        dq%l=dq%l+1
    end function


    function dq_right(dq) result(ret)
        ! 右端を確認
        class(deque):: dq
        integer(int32):: ret
        ret = dq%v(dq%r)
    end function

    function dq_left(dq) result(ret)
        ! 左端を確認
        class(deque):: dq
        integer(int32):: ret
        ret = dq%v(dq%l)
    end function

    function dq_remaining_elements(dq) result(ret)
        ! 残りの要素数
        class(deque):: dq
        integer(int32):: ret 
        ret = dq%r - dq%l + 1
    end function

    function dq_remain(dq) result(ret)
        ! 要素が残っているかどうか
        class(deque):: dq
        logical:: ret
        ret = dq%remaining_elements() > 0
    end function
end module

program abc151
    use,intrinsic :: iso_fortran_env
    implicit none
    integer(int32):: h,w
    integer(int32):: x,y,ans
    character(int32), allocatable:: s(:,:)

    read*, h,w
    allocate(s(w,h))

    inpt_s : block
        character(w):: inpt
        do y=1,h
            read*, inpt
            do x=1,w
                s(x,y) = inpt(x:x)
            end do
        end do
    end block inpt_s

    ans=0
    do y=1,h
        do x=1,w
            if (s(x,y) == '#') cycle
            ans = max(ans, solve(x,y))
        end do
    end do
    print'(i0)', ans
contains
    function solve(x,y) result(ret)
        use deque_mod
        integer(int32):: x, y, ret
        integer(int32):: nx, ny
        integer(int32):: dx, dy, i
        integer(int32):: turn(w,h)
        integer(int32),parameter:: d(2,4) = reshape([1,0,0,1,-1,0,0,-1], [2,4])
        type(deque):: task_x, task_y

        ! BFS
        task_x = deque()
        task_y = deque()
        turn(:,:) = -1
        turn(x,y) = 0
        call task_x%append(x)
        call task_y%append(y)

        do while(task_x%remain())
            nx = task_x%popleft()
            ny = task_y%popleft()
            do i=1,4
                dx = d(1,i)
                dy = d(2,i)
                if (.not. in_maze(nx+dx,ny+dy)) cycle
                if (s(nx+dx,ny+dy) == '#') cycle
                if (turn(nx+dx,ny+dy) /= -1) cycle
                turn(nx+dx,ny+dy) = turn(nx,ny)+1
                call task_x%append(nx+dx)
                call task_y%append(ny+dy)
            end do
        end do
        ! print*, '---', x,y
        ! do i=1,h
        !     print'(*(i0,1x))', turn(:,i)
        ! end do

        ret = maxval(turn)
    end function

    function in_maze(x,y) result(ret)
        integer(int32):: x,y
        logical:: in_x, in_y, ret

        in_x = 1 <= x .and. x <= w
        in_y = 1 <= y .and. y <= h
        ret = in_x .and. in_y
    end function
end program abc151

Measured memory_bytes: 6784