import Control.Applicative ((<$>)) import Control.Monad (replicateM) import Data.Vector.Unboxed (Vector, (!), (//)) import qualified Data.Vector.Unboxed as V main :: IO () main = do [w, h] <- map read <$> words <$> getLine solve w h <$> (concat <$> replicateM h getLine) >>= print solve :: Int -> Int -> String -> Int solve w h ss = let imp = V.fromList ss (mp, ixs1) = dfs [maybe (0,0) fmIx $ V.findIndex (=='.') imp] imp [] (_, ixs2) = dfs [maybe (0,0) fmIx $ V.findIndex (=='.') mp] mp [] in minPath ixs1 ixs2 where toIx (i, j) = i * w + j fmIx ix = divMod ix w dfs [] mp ixs = (mp, ixs) dfs (p:ps) mp ixs | mp ! (toIx p) == '#' = dfs ps mp ixs | otherwise = let (i, j) = p in dfs ([(i+1,j),(i-1,j),(i,j+1),(i,j-1)] ++ ps) (mp // [(toIx p, '#')]) (p:ixs) minPath xs ys = minimum $ do (i,j) <- xs (i',j') <- ys return $ abs (i - i') + abs (j - j') - 1