{-# LANGUAGE BangPatterns #-}
import qualified Data.ByteString.Char8 as BS
import Data.Maybe
import           Data.Monoid
import           Control.Monad
import Data.Array.Unboxed
import Data.Array.ST
import Control.Monad.ST.Strict
import Data.Sequence ((<|), (|>), (><), ViewL(..), ViewR(..), Seq)
import qualified Data.Sequence as S
tuplify2 (x:y:_) = (x,y)
tuplify2 _ = undefined


readInt = fst . fromJust . BS.readInt
readIntTuple = tuplify2 . map readInt . BS.words
readIntList = map readInt . BS.words

getInt = readInt <$> BS.getLine
getIntList = readIntList <$> BS.getLine
getIntNList n = map readIntList <$> replicateM (fromIntegral n) BS.getLine
getIntMatrix = map readIntList . BS.lines <$> BS.getContents
getIntTuple = readIntTuple <$> BS.getLine
getIntNTuples n = map readIntTuple <$> replicateM (fromIntegral n) BS.getLine
getIntTuples = map readIntTuple . BS.lines <$> BS.getContents

type Pos = (Int,Int)
type Graph = UArray Pos Char
main = do
    [h,w] <- getIntList
    a <- concatMap BS.unpack <$> replicateM h BS.getLine
    let grid = listArray ((0,0),(h-1,w-1)) a
        init = S.fromList $ zip [(y,x) | x <- [0..w-1],y <- [0..h-1],grid ! (y,x) == '#'] (repeat 0)
    --print grid
    print $ bfs grid init
    return()

next :: Graph -> Pos -> Seq Pos
next g (y,x) = S.fromList [(ny,nx) | (dy,dx) <- zip [0,1,0,-1] [1,0,-1,0],let ny=y+dy,let nx=x+dx,0 <= ny && ny <= h' && 0 <= nx && nx <= w' && g ! (ny,nx) /= '#']
    where (h',w') = snd $ bounds g

next' :: STUArray s Pos Char -> Pos -> Pos -> ST s (Seq Pos)
next' g (h',w') (y,x) = do
    let list = [(ny,nx) | (dy,dx) <- zip [0,1,0,-1] [1,0,-1,0],let ny=y+dy,let nx=x+dx,0 <= ny && ny <= h' && 0 <= nx && nx <= w']
    vals <- zip list <$> mapM (readArray g) list
    let list' = [p | (p,v) <- vals,v /= '#']
    return $ S.fromList list'

bfs :: UArray Pos Char -> Seq (Pos,Int) -> Int
bfs grid init = runST (do
    g <- thaw grid :: ST s (STUArray s Pos Char)
    f g init)
    where   f :: STUArray s Pos Char -> Seq (Pos,Int) -> ST s Int
            f !g !seq = case S.viewl seq of
                S.EmptyL  -> return 0
                ((p,d) :< ps) ->
                    do
                        !ne <- next' g (snd $ bounds grid) p
                        let !ne' = S.zip ne (S.replicate 4 (d+1))
                        forM_ ne $ \(ny,nx) -> writeArray g (ny,nx) '#'
                        !v <- f g (ps><ne')
                        return $ max d v