import Control.Arrow
import Data.Foldable
import Data.Graph
import qualified Data.Vector as V
import qualified Data.ByteString.Char8 as B

solve :: Int -> Int -> V.Vector B.ByteString -> Int
solve h w ss = sum $ map ((\s -> length (filter (== '#') s) * length (filter (== '.') s)) . flattenSCC) $ stronglyConnComp $ map (\i -> (ss !! toIndex i, toIndex i, neighbors $ toIndex i)) [0..w*h-1]
  where
    toIndex :: Int -> (Int,Int)
    toIndex n = (n `mod` w, n `div` w)

    fromIndex :: (Int,Int) -> Int
    fromIndex (x,y) = y * w + x

    (!!) :: V.Vector B.ByteString -> (Int,Int) -> Char
    vec !! (x,y) = (vec V.! y) `B.index` x

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

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
