{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
{-# LANGUAGE ScopedTypeVariables #-}
import           Control.Monad      (foldM, replicateM)
import           Control.Monad.ST   (ST)
import           Data.Array.ST      (STUArray)
import qualified Data.Array.ST      as MA
import           Data.Array.Unboxed (UArray, (!))
import qualified Data.Array.Unboxed as A
import           Data.Set           (Set)
import qualified Data.Set           as S

main :: IO ()
main = do
  [h, w] <- map read . words <$> getLine
  sss <- replicateM h getLine
  print $ solve h w sss

solve :: Int -> Int -> [[Char]] -> Int
solve h w sss = if d == inf then -1 else h * w - bs - d - 1 where
  d = dss ! (h - 1, w - 1)
  dss = dijkstra h w sss' (0, 0)
  sss' = A.array ((0, 0), (h - 1, w - 1))
    [((i, j), s) | (ss, i) <- zip sss [0 .. ]
                 , (s, j) <- zip ss [0 .. ]] :: UArray (Int, Int) Char
  bs = sum $ map (length . filter (== '#')) sss

inf :: Int
inf = maxBound `div` 3

add :: Int -> Int -> Int
add x y = if x == inf || y == inf then inf else x + y

dijkstra :: Int -> Int -> UArray (Int, Int) Char -> (Int, Int) -> UArray (Int, Int) Int
dijkstra h w sss start = MA.runSTUArray $ do
  distMA <- MA.newArray ((0, 0), (h - 1, w - 1)) maxBound :: ST s (STUArray s (Int, Int) Int)
  MA.writeArray distMA start 0
  let q = S.singleton (0, start)
  dijkstraMain distMA q
    where
      dijkstraMain :: forall s. STUArray s (Int, Int) Int -> Set (Int, (Int, Int)) -> ST s (STUArray s (Int, Int) Int)
      dijkstraMain distMA q
        | S.null q = return distMA
        | otherwise = do
            let ((_, u), q') = S.deleteFindMin q
            du <- MA.readArray distMA u
            q'' <- foldM (dijkstraFor du) q' (adjacent u)
            dijkstraMain distMA q''
        where
          dijkstraFor :: Int -> Set (Int, (Int, Int)) -> (Int, Int) -> ST s (Set (Int, (Int, Int)))
          dijkstraFor du q' v = do
            dv <- MA.readArray distMA v
            let w' = weight $ sss ! v
                dv' = du `add` w'
            if dv > dv'
              then do
                MA.writeArray distMA v dv'
                return $ S.insert (dv', v) q'
              else return q'

      adjacent v = filter isValidIx [plus2 v dv | dv <- dvs] where
        dvs = [(1, 0), (0, 1), (-1, 0), (0, -1)]
        isValidIx (i, j) = 0 <= i && i < h && 0 <= j && j < w
        plus2 (i, j) (di, dj) = (i + di, j + dj)

      weight '.' = 1
      weight '#' = inf
      weight  _  = undefined
