module mod_union_find
  implicit none
  integer :: n
  integer, allocatable :: par(:), rnk(:), siz(:)
  private
  public :: initialize, finalize, find, same, unite, size_of
contains
  subroutine initialize(m)
    implicit none
    integer, intent(in) :: m
    integer :: i
    n = m
    if (allocated(par)) deallocate(par)
    if (allocated(rnk)) deallocate(rnk)
    if (allocated(siz)) deallocate(siz)
    allocate(par(n),rnk(n),siz(n))
    rnk = 0
    siz = 1
    do i = 1, n
      par(i) = i
    end do
    return
  end subroutine initialize
  subroutine finalize()
    implicit none
    if (allocated(par)) deallocate(par)
    if (allocated(rnk)) deallocate(rnk)
    if (allocated(siz)) deallocate(siz)
    return
  end subroutine finalize
  recursive function find(i) result(j)
    implicit none
    integer, intent(in) :: i
    integer :: j
    if (par(i).ne.i) then
      par(i) = find(par(i))
    end if
    j = par(i)
    return
  end function find
  function same(i,j) result(y)
    implicit none
    integer, intent(in) :: i, j
    logical :: y
    y = find(i).eq.find(j)
  end function same
  subroutine unite(i,j)
    implicit none
    integer, intent(in) :: i, j
    integer :: x, y
    x = find(i)
    y = find(j)
    if (x.eq.y) return
    if (rnk(x).lt.rnk(y)) then
      par(x) = y
      siz(y) = siz(y)+siz(x)
    else
      par(y) = x
      siz(x) = siz(x)+siz(y)
      if (rnk(x).eq.rnk(y)) rnk(x) = rnk(x)+1
    end if
    return
  end subroutine unite
  function size_of(i) result(s)
    implicit none
    integer, intent(in) :: i
    integer :: s
    s = siz(find(i))
  end function size_of
end module mod_union_find
program alternating_path
  use mod_union_find
  implicit none
  integer :: h, w, a(400,400), i, j, num(160000,0:1)
  integer(8) :: m
  character(400) :: s
  a = 0
  num = 0
  read(*,*) h, w
  call initialize(h*w)
  do i = 1, h
    read(*,*) s
    s = trim(adjustl(s))
    do j = 1, w
      if (s(j:j).eq."#") a(i,j) = 1
      if (i.ne.1.and.a(i,j).ne.a(i-1,j)) call unite((i-1)*w+j,(i-2)*w+j)
      if (j.ne.1.and.a(i,j).ne.a(i,j-1)) call unite((i-1)*w+j,(i-1)*w+j-1)
    end do
  end do
  do i = 1, h
    do j = 1, w
      num(find((i-1)*w+j),a(i,j)) = num(find((i-1)*w+j),a(i,j))+1
    end do
  end do
  m = 0_8
  do i = 1, h*w
    m = m+int(num(i,0),8)*int(num(i,1),8)
  end do
  write(*,'(i0)') m
  call finalize()
  stop
end program alternating_path