(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS
;;;
;;; Ford-Fulkerson
;;;

(setf *print-circle* t)

(defstruct (edge (:constructor %make-edge))
  (to nil :type fixnum)
  (capacity 0 :type fixnum)
  (flow 0 :type fixnum)
  (reversed nil :type (or null edge)))

(defun push-edge (from-idx to-idx capacity graph &key bidirectional)
  "FROM-IDX, TO-IDX := index of vertex
GRAPH := vector of list of all the edges that goes from the vertex"
  (declare #.OPT ((simple-array list (*)) graph))
  (let* ((dep (%make-edge :to to-idx :capacity capacity))
         (ret (%make-edge :to from-idx
                          :capacity (if bidirectional capacity 0)
                          :reversed dep)))
    (setf (edge-reversed dep) ret)
    (push dep (aref graph from-idx))
    (push ret (aref graph to-idx))))

(defun %find-flow (src-idx dest-idx graph max-flow checked)
  "DFS"
  (declare #.OPT
           ((integer 0 #.most-positive-fixnum) src-idx dest-idx max-flow)
           (simple-bit-vector checked)
           ((simple-array list (*)) graph))
  (setf (aref checked src-idx) 1)
  (if (= src-idx dest-idx)
      max-flow
      (dolist (edge (aref graph src-idx) 0)
        (when (and (zerop (aref checked (edge-to edge)))
                   (< (edge-flow edge) (edge-capacity edge)))
          (let ((flow (%find-flow (edge-to edge)
                                  dest-idx
                                  graph
                                  (min max-flow (- (edge-capacity edge) (edge-flow edge)))
                                  checked)))
            (declare ((integer 0 #.most-positive-fixnum) flow))
            (unless (zerop flow)
              (incf (edge-flow edge) flow)
              (incf (edge-capacity (edge-reversed edge)) flow)
              (return flow)))))))

(defun max-flow (src-idx dest-idx graph)
  (declare #.OPT
           ((simple-array list (*)) graph))
  (let ((checked (make-array (length graph) :element-type 'bit :initial-element 0)))
    (loop for incr-flow of-type (integer 0 #.most-positive-fixnum)
             = (%find-flow src-idx dest-idx graph most-positive-fixnum checked)
          do (fill checked 0)
          until (zerop incr-flow)
          sum incr-flow of-type (integer 0 #.most-positive-fixnum))))

(defmacro buffered-read-line (&optional (buffer-size 30) (in '*standard-input*) (terminate-char #\Space))
  "Note that the returned string will be reused."
  (let ((buffer (gensym))
        (character (gensym))
        (idx (gensym)))
    `(let ((,buffer (load-time-value (make-string ,buffer-size
                                                  :element-type 'base-char))))
       (declare (simple-base-string ,buffer))
       (loop for ,character of-type base-char =
                #-swank (code-char (read-byte ,in nil #.(char-code #\Newline)))
                #+swank (read-char ,in nil #\Newline)
             for ,idx from 0
             until (char= ,character #\Newline)
             do (setf (schar ,buffer ,idx) ,character)
             finally (when (< ,idx ,buffer-size)
                       (setf (schar ,buffer ,idx) ,terminate-char))
                     (return (values ,buffer ,idx))))))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(defmacro println (obj &optional (stream '*standard-output*))
  `(let ((*read-default-float-format* 'double-float))
     (prog1 (princ ,obj ,stream) (terpri ,stream))))

(defconstant +mod+ 1000000007)

;; Hauptteil
(defconstant +inf+ #xffffffff)
(defun main ()
  (declare #.OPT)
  (let* ((h (read))
         (w (read))
         (h-1 (- h 1))
         (w-1 (- w 1))
         (graph (make-array (+ (* 2 h w) 2) :element-type 'list :initial-element nil))
         (start-index (* 2 h w))
         (goal-index (+ (* 2 h w) 1)))
    (declare ((integer 1 100) h w))
    (macrolet ((trans-coord (i j)
                 `(* 2 (+ (* ,i w) ,j))))
      (dotimes (i h)
        (let ((line (buffered-read-line 100)))
          (dotimes (j w)
            (let ((index (trans-coord i j)))
              (if (char= #\X (aref line j))
                  (progn
                    (push-edge index (1+ index) +inf+ graph)
                    (push-edge start-index index +inf+ graph))
                  (push-edge index (1+ index) 1 graph))
              (when (or (= i 0) (= j 0) (= i h-1) (= j w-1))
                (push-edge (1+ index) goal-index +inf+ graph))
              (unless (= i 0)
                (push-edge (1+ index) (trans-coord (- i 1) j) +inf+ graph))
              (unless (= j 0)
                (push-edge (1+ index) (trans-coord i (- j 1)) +inf+ graph))
              (unless (= i h-1)
                (push-edge (1+ index) (trans-coord (+ i 1) j) +inf+ graph))
              (unless (= j w-1)
                (push-edge (1+ index) (trans-coord i (+ j 1)) +inf+ graph)))))))
    (let ((res (max-flow start-index goal-index graph)))
      (if (>= res +inf+)
          (println -1)
          (println res)))))

#-swank(main)


Measured memory_bytes: 27752