#-swank
(unless (member :child-sbcl *features*)
  (quit
   :unix-status
   (process-exit-code
    (run-program *runtime-pathname*
                 `("--control-stack-size" "128MB"
                   "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                   "--eval" "(push :child-sbcl *features*)"
                   "--script" ,(namestring *load-pathname*))
                 :output t :error t :input t))))

(defun fill-around (h w map x y &key no-left no-right no-up no-down)
  (let ((score (aref map y x)))
    ;; left
    (when (and (not no-left)
               (<= 0 (1- x)))
      (let ((cur (aref map y (1- x))))
        (unless (or (= cur -1)
                    (and (not (zerop cur))
                         (<= cur (1+ score))))
          (setf (aref map y (1- x)) (1+ score))
          (fill-around h w map (1- x) y
                       :no-right t))))

    ;; right
    (when (and (not no-right)
               (< (1+ x) w))
      (let ((cur (aref map y (1+ x))))
        (unless (or (= cur -1)
                    (and (not (zerop cur))
                         (<= cur (1+ score))))
          (setf (aref map y (1+ x)) (1+ score))
          (fill-around h w map (1+ x) y
                       :no-left t))))

    ;; up
    (when (and (not no-up)
               (<= 0 (1- y)))
      (let ((cur (aref map (1- y) x)))
        (unless (or (= cur -1)
                    (and (not (zerop cur))
                         (<= cur (1+ score))))
          (setf (aref map (1- y) x) (1+ score))
          (fill-around h w map x (1- y)
                       :no-down t))))

    ;; down
    (when (and (not no-down)
               (< (1+ y) h))
      (let ((cur (aref map (1+ y) x)))
        (unless (or (= cur -1)
                    (and (not (zerop cur))
                         (<= cur (1+ score))))
          (setf (aref map (1+ y) x) (1+ score))
          (fill-around h w map x (1+ y)
                       :no-up t))))))

(defun get-shortest (h w map start-x start-y)
  (fill-around h w map start-x start-y)
  (prog1
      (loop for y from 0 below h
            if (or (= y 0)
                   (= y (1- h)))
            maximize (loop for x from 0 below w
                           if (or (= x 0)
                                  (= x (1- w)))
                           maximize (aref map y x)))
    (reset-map h w map)))

(defun solve (h w map)
  (max (loop for x from 0 below w
             if (/= -1 (aref map 0 x))
             maximize (get-shortest h w map x 0))
       (loop for y from 1 below h
             if (/= -1 (aref map y 0))
             maximize (get-shortest h w map 0 y))
       (loop with y = (1- h)
             for x from 0 below w
             if (/= -1 (aref map y x))
             maximize (get-shortest h w map x y))
       (loop with x = (1- w)
             for y from 1 below h
             if (/= -1 (aref map y x))
             maximize (get-shortest h w map x y))))

(defun reset-map (h w map)
  (loop for y from 0 below h
        do (loop for x from 0 below w
                 if (/= -1 (aref map y x))
                 do (setf (aref map y x) 0))))

#-swank
(let* ((h (read))
       (w (read))
       (map (make-array (list h w) :element-type 'fixnum)))
  (loop for y from 0 below h
        do (loop for x from 0 below w
                 for char = (read-char)
                 do (setf (aref map y x)
                          (if (char= char #\.)
                              0
                              -1)))
        do (read-char))
  (format t "~A~%" (solve h w map)))
