import Control.Applicative
import Control.Monad
import Data.Array.IArray
import Data.Array.IO
import Debug.Trace

main = do
  [h,w] <- map read.words <$> getLine
  unless (h == 0 && w == 0) $ do
    field <- readField (h,w)
    num <- countPD field
    print num
    main

readField :: (Int,Int) -> IO (Array (Int,Int) Char)
readField (h,w) = do
  cs <- concat <$> replicateM h getLine
  return $ listArray ((1,1),(h,w)) cs

countPD :: Array (Int,Int) Char -> IO Int
countPD arr = do
  let bs = bounds arr
      ixList = indices arr
  ioarr <- newArray bs False
  foldl (>>=) (return 0) $ map (countPDs arr ioarr) ixList

countPDs :: Array (Int, Int) Char -> IOArray (Int, Int) Bool -> (Int, Int) -> Int -> IO Int
countPDs arr ioarr ix num = do
  checkedIx <- readArray ioarr ix
  let numIx = if checkedIx then 0 else 1
  checkProperty arr ioarr ix checkedIx
--  print (ix,num + numIx)
  return $ num + numIx

printField :: IOArray (Int, Int) Bool -> IO ()
printField ioarr = do
  ((hmin,wmin),(hmax,wmax)) <- getBounds ioarr
  forM_ [hmin..hmax] $ \i -> do
    forM_ [wmin..wmax] $ \j -> do
      b <- readArray ioarr (i,j)
      if b then putStr "T" else putStr "F"
    putStrLn ""

checkProperty :: Array (Int, Int) Char -> IOArray (Int, Int) Bool -> (Int, Int) -> Bool -> IO ()
checkProperty arr ioarr ix checkedIx = do
  if checkedIx
     then return ()
     else do
       let (h,w) = ix
       writeArray ioarr ix True
       updateField arr ioarr ix

updateField :: Array (Int, Int) Char -> IOArray (Int, Int) Bool -> (Int, Int) -> IO ()
updateField arr ioarr (h,w) = do --traceShow (h,w) $ do
  rightUpdate arr ioarr (h,w)
  underUpdate arr ioarr (h,w)

rightUpdate :: Array (Int, Int) Char -> IOArray (Int, Int) Bool -> (Int, Int) -> IO ()
rightUpdate arr ioarr (h,w) = do --trace ("right" ++ show (h,w)) $ do
  let ((hmin,wmin),(hmax,wmax)) = bounds arr
  case (hmax == h, wmax == w) of
       (_, True) -> return ()
       (True, False) -> bottomAction
       (False, False) -> normalAction
  where
    updateAction = do
      let originProp = arr ! (h,w)
          rightProp = arr ! (h,w+1)
      if originProp == rightProp
         then writeArray ioarr (h,w+1) True >> return True
         else return False
    bottomAction = do
      continue <- updateAction
      if continue then rightUpdate arr ioarr (h,w+1)
                  else return ()
    normalAction = do
      continue <- updateAction
      if continue then rightUpdate arr ioarr (h,w+1) >> underUpdate arr ioarr (h,w+1)
                  else return ()

leftUpdate arr ioarr (h,w) = do --trace ("left " ++ show (h,w)) $ do
  let ((hmin,wmin),(hmax,wmax)) = bounds arr
  case (hmax == h, wmin == w) of
       (_, True) -> return ()
       (True, False) -> bottomAction
       (False, False) -> normalAction
  where
    updateAction = do
      checked <- readArray ioarr (h,w-1)
      if checked then return False
                 else do
                    let originProp = arr ! (h,w)
                        leftProp = arr ! (h,w-1)
                    if originProp == leftProp
                       then writeArray ioarr (h,w-1) True >> return True
                       else return False
    bottomAction = do
      continue <- updateAction
      if continue then leftUpdate arr ioarr (h,w-1)
                  else return ()
    normalAction = do
      continue <- updateAction
      if continue then leftUpdate arr ioarr (h,w-1) >> underUpdate arr ioarr (h,w-1)
                  else return ()

underUpdate arr ioarr (h,w) = do --trace ("under" ++ show (h,w)) $ do
  let ((hmin,wmin),(hmax,wmax)) = bounds arr
  case (hmax == h, wmax == w, wmin == w) of
       (True, _, _) -> return ()
       (False, True, False) -> rightEdgeAction
       (False, False, True) -> leftEdgeAction
       (False, False, False) -> normalAction
  where
    updateAction = do
      let originProp = arr ! (h,w)
          rightProp = arr ! (h+1,w)
      if originProp == rightProp
         then writeArray ioarr (h+1,w) True >> return True
         else return False
    rightEdgeAction = do
      continue <- updateAction
      if continue then underUpdate arr ioarr (h+1,w) >> leftUpdate arr ioarr (h+1,w)
                  else return ()
    leftEdgeAction = do
      continue <- updateAction
      if continue then underUpdate arr ioarr (h+1,w) >> rightUpdate arr ioarr (h+1,w)
                  else return ()
    normalAction = do
      continue <- updateAction
      if continue then rightUpdate arr ioarr ((h+1,w)) >> leftUpdate arr ioarr (h+1,w) >> underUpdate arr ioarr ((h+1,w))
                  else return ()

