h, w = STDIN.gets.split.map(&:to_i)

map = []
h.times do
  map << STDIN.gets.chomp.chars
end

path = 0
completed = Array.new(h) { Array.new(w) { false } }

Point = Struct.new(:i, :j, :color)
0.upto(h-1) do |y|
  0.upto(w-1) do |x|
    if map[y][x] != '#'
      completed[y][x] = true
      next
    end

    queue = []
    already_visited = Array.new(h) { Array.new(w) { false } }
    already_visited[y][x] = true

    queue.push(Point.new(y, x, map[y][x]))

    while !queue.empty?
      t = queue.shift
      i = t[0]
      j = t[1]
      color = t[2]

      # up
      if i + 1 < h && color != map[i+1][j] && already_visited[i+1][j] == false && completed[i+1][j] == false
        path += 1
        queue << [i+1, j, map[i+1][j]]
        already_visited[i+1][j] = true
      end

      # down
      if i - 1 >= 0 && color != map[i-1][j] && already_visited[i-1][j] == false && completed[i-1][j] == false
        path += 1
        queue << [i-1, j, map[i-1][j]]
        already_visited[i-1][j] = true
      end

      # right
      if j + 1 < w && color != map[i][j+1] && already_visited[i][j+1] == false && completed[i][j+1] == false
        path += 1
        queue << [i, j+1, map[i][j+1]]
        already_visited[i][j+1] = true
      end

      # left
      if j - 1 >= 0 && color != map[i][j-1] && already_visited[i][j-1] == false && completed[i][j-1] == false
        path += 1
        queue << [i, j-1, map[i][j-1]]
        already_visited[i][j-1] = true
      end
    end

    completed[y][x] = true
    # p "#{y} #{x} path: #{path}"
  end
end

p path
