class UnionFind

  attr_accessor :size

  def initialize(n)
    @size = n
    @par  = (0 ... n).to_a
    @rank = Array.new(n, 0)
  end

  def root(x)
    @par[x] == x ? x : @par[x] = root(@par[x])
  end

  def unite(x, y)
    x_root, y_root = root(x), root(y)
    return if x_root == y_root
    if @rank[x_root] < @rank[y_root]
      @par[x_root] = y_root
    else
      @par[y_root] = x_root
      @rank[x_root] += 1 if @rank[x_root] == @rank[y_root]
    end
  end

  def is_same(x, y)
    root(x) == root(y)
  end

  def roots()
    (0 ... @size).to_a.map{|x| root(x) }
  end

end

@distances = [
  { x: 1, y: 0 },
  { x: -1, y: 0 },
  { x: 0, y: 1 },
  { x: 0, y: -1 },
]

(h, w) = gets.chomp.split(' ').map{|char| char.to_i }
mass = (0 ... h).map{|_| gets.chomp.split('') }

def solve(h, w, mass)
  tree = UnionFind.new(h * w)

  (0 ... h).to_a.each do |y|
    (0 ... w).to_a.each do |x|
      current = y * w + x
      next if mass[y][x] == '.'
      @distances.each do |d|
        dx, dy = x + d[:x], y + d[:y]
        if dy < h && dy >= 0 && dx < w && dx >= 0 && mass[dy][dx] == '.'
          tree.unite(current, dy * w + dx)
        end
      end
    end
  end

  roots = tree.roots
  routes = roots.uniq.map do |vertex|
    points = (0 ... tree.size).select{|x| vertex == roots[x] }
    colors = points.map do |p| 
      x, y = p % w, p.div(w)
      mass[y][x]
    end
    colors.grep('.').size * colors.grep('#').size
  end
  routes.sum
end

puts solve(h, w, mass)
