import Control.Arrow
import Data.Bits
import Data.List
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VM
import qualified Data.ByteString.Char8 as B

--solve :: Int -> Int -> V.Vector B.ByteString -> Int
solve h w ss = label
  where
    (!!) :: V.Vector B.ByteString -> (Int, Int) -> Char
    vec !! (x,y) = (vec V.! y) `B.index` x

    (!+) :: VM.Unbox a => VU.Vector a -> (Int, Int) -> a
    vec !+ (x,y) = vec VU.! (y * w + x)

    label :: (VU.Vector Int, [(Int,Int)])
    label = (\(a,b,_) -> (a,b)) $ foldl' go (VU.replicate (w*h) 0, [], 1) [0..w*h-1]
      where
        go (visited, eqs, f) i =
          if length neighbors == 0 then (VU.modify (\vec -> VM.write vec i f) visited, eqs, f+1)
          else if length neighbors == 1 then (VU.modify (\vec -> VM.write vec i (head neighbors)) visited, eqs, f)
          else error "error" -- (VU.modify (\vec -> VM.write vec i (head neighbors)) visited, map ((,) (head neighbors)) (tail neighbors), f)
            where
              x = i `mod` w
              y = i `div` w
              ch = ss !! (x,y)

              neighbors = nub $
                [ visited !+ (x',y')
                | (ix,iy) <- [(1,0),(-1,0),(0,1),(0,-1)],
                  let x' = x + ix, let y' = y + iy,
                  0 <= x' && x' < w, 0 <= y' && y' < h,
                  visited !+ (x',y') /= 0,
                  ss !! (x',y') /= ch
                ]

main = do
  let readInt = fmap (second B.tail) . B.readInt

  hw <- V.unfoldrN 2 readInt <$> B.getLine
  ss <- V.replicateM (hw V.! 0) B.getLine
  print $ solve (hw V.! 0) (hw V.! 1) ss
