output_description: Print the answer.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      H W
      S_1
      S_2
      :
      S_H
attempt: # -*- coding: utf-8 -*-
  import bisect
  import heapq
  import math
  import random
  import sys
  from collections import Counter, defaultdict, deque
  from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
  from functools import lru_cache, reduce
  from itertools import combinations, combinations_with_replacement, product, permutations
  from operator import add, mul, sub
  
  sys.setrecursionlimit(10000)
  
  
  def read_int():
      return int(input())
  
  
  def read_int_n():
      return list(map(int, input().split()))
  
  
  def read_float():
      return float(input())
  
  
  def read_float_n():
      return list(map(float, input().split()))
  
  
  def read_str():
      return input().strip()
  
  
  def read_str_n():
      return list(map(str, input().split()))
  
  
  def error_print(*args):
      print(*args, file=sys.stderr)
  
  
  def mt(f):
      import time
  
      def wrap(*args, **kwargs):
          s = time.time()
          ret = f(*args, **kwargs)
          e = time.time()
  
          error_print(e - s, "sec")
          return ret
  
      return wrap
  
  
  @mt
  def slv(H, W, S):
      g = defaultdict(dict)
      for i, r in enumerate(S):
          for j, c in enumerate(r):
              if i > 0 and S[i - 1][j] != c:
                  g[(i, j)][(i - 1, j)] = 1
                  g[(i - 1, j)][(i, j)] = 1
              if i < H - 1 and S[i + 1][j] != c:
                  g[(i, j)][(i + 1, j)] = 1
                  g[(i + 1, j)][(i, j)] = 1
              if j > 0 and S[i][j - 1] != c:
                  g[(i, j)][(i, j - 1)] = 1
                  g[(i, j - 1)][(i, j)] = 1
              if j < W - 1 and S[i][j + 1] != c:
                  g[(i, j)][(i, j + 1)] = 1
                  g[(i, j + 1)][(i, j)] = 1
  
      ans = 0
      for k in g:
          i, j = k
          if S[i][j] != "#":
              continue
          s = [k]
          done = set([k])
          while s:
              # print(s)
              k = s.pop()
              for n in g[k]:
                  if n not in done:
                      s.append(n)
                      done.add(n)
              i, j = k
              if S[i][j] == ".":
                  ans += 1
  
      return ans
  
  
  def main():
      # H, W = read_int_n()
      # S = []
      # for _ in range(H):
      #     S.append(read_str())
      S = []
      H = 400
      W = 400
      for _ in range(H):
          S.append(random.choices("#.", k=W))
      print(slv(H, W, S))
  
  
  if __name__ == "__main__":
      main()
  
problem_description: Statement
  
  There is a grid with H rows and W columns, where each square is painted black
  or white.
  
  You are given H strings S_1, S_2, ..., S_H, each of length W. If the square at
  the i-th row from the top and the j-th column from the left is painted black,
  the j-th character in the string S_i is `#`; if that square is painted white,
  the j-th character in the string S_i is `.`.
  
  Find the number of pairs of a black square c_1 and a white square c_2 that
  satisfy the following condition:
  
    * There is a path from the square c_1 to the square c_2 where we repeatedly move to a vertically or horizontally adjacent square through an alternating sequence of black and white squares: black, white, black, white...
samples: [{"input": "3 3\n    .#.\n    ..#\n    #..", "output": "10\n    \n\nSome of the pairs satisfying the condition are ((1, 2), (3, 3)) and ((3, 1),\n(3, 2)), where (i, j) denotes the square at the i-th row from the top and the\nj-th column from the left.\n\n* * *"}, {"input": "2 4\n    ....\n    ....", "output": "0\n    \n\n* * *"}, {"input": "4 3\n    ###\n    ###\n    ...\n    ###", "output": "6"}]