{-# OPTIONS_GHC -O2 #-}
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as VM
import Data.Array.Unboxed
import Data.Array.ST
import qualified Data.ByteString.Char8 as BS
import Control.Monad
import Control.Monad.ST
import Data.STRef 
import Data.List
import Data.Char
import qualified Data.Map.Strict as M

main :: IO ()
main = do
    [r,c] <- unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine
    css <- V.replicateM r $ VU.unfoldrN c BS.uncons <$> BS.getLine
    let all = runST $ do
        all <- newSTRef []
        forM_ [0..r-1] $ \i -> do
            forM_ [0..c-1]$ \j -> do
                when ('#' == (css V.! i) VU.! j) $ modifySTRef all ((i,j):)
        readSTRef all
    let solve = runST $ do
            arrived <- newArray ((0,0),(r-1,c-1)) (-1)
            go 0 all [] arrived
            where go :: Int -> [(Int,Int)] -> [(Int,Int)] -> STUArray s (Int,Int) Int -> ST s Int
                  go count [] [] _ = return count
                  go count [] ys arrived = go (count+1) ys [] arrived
                  go count ((v,w):xs) ys arrived = 
                    if not (0 <= v && v <= r-1 && 0 <= w && w <= c-1) then go count xs ys arrived 
                    else do
                        xx <- readArray arrived (v,w)
                        if xx == -1 then writeArray arrived (v,w) count >> go count xs ((v+1,w):(v-1,w):(v,w+1):(v,w-1):ys) arrived
                        else go count xs ys arrived
    print $ if length all == r*c then 0 else solve-1
