{-# LANGUAGE OverloadedStrings #-}
import Data.Array.IO
import Control.Monad
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import Data.Text.Encoding
import qualified Data.ByteString as B

main :: IO ()
main = do
  [iy,ix] <- map read . words <$> getLine :: IO [Int]
  routeArr <- newArray_ ( (0,0), (iy-1,ix-1) ) :: IO (IOArray (Int,Int) Bool)
  forM_ [0..(iy-1)] $ \ny -> do
    routesList <- encodeUtf8 <$> TIO.getLine
    forM_ [0..(ix-1)] $ \nx -> do
      case routesList `B.index` nx of
        46 -> writeArray routeArr (ny,nx) True -- '.'
        35 -> writeArray routeArr (ny,nx) False -- '#'
  times <- solve (iy-1,ix-1) routeArr
  print times

solve :: (Int,Int) -> IOArray (Int,Int) Bool -> IO Int
solve (y,x) ioArr = do
  color <- readArray ioArr (y,x)
  if color then
    loop 0 color (y,x) ioArr
    else
    loop 1 color (y,x) ioArr
  where
    loop :: Int -> Bool -> (Int,Int) -> IOArray (Int,Int) Bool -> IO Int
    loop n color (y,x) _ = do
      c <- readArray ioArr (y,x)
      let next = if (not color || c)
                 then n
                 else n+1
      case (y,x) of
        (0,0) -> do
          return next
        (0,x) -> do
          loop next c (0,x-1) ioArr
        (y,0) -> do
          loop next c (y-1,0) ioArr
        (y,x) -> do
          up   <- loop next c (y-1,x) ioArr
          left <- loop next c (y,x-1) ioArr
          return $ min up left

