/*
for n // 从左往右
for m // 从上往下
BFS(i,j)
BFS(i,j)时,k[i][j]应该是长方形的左上角,记录最右的下标max_i、最下的下标max_j和'.'的数量num,判断(max_i+1-i)*(max_j+1-j) == num,但是有部分样例没通过。
后面加上记录 min_i,min_j,然后判断(max_i+1 -min_i)*(max_j+1 -min_j) == num就都通过了。
*/
package main
import (
"fmt"
)
type Node struct{
i,j int
}
func main() {
var n, m int
fmt.Scanf("%d %d", &n, &m)
var k = make([][]byte, n)
var v = make([][]bool, n)
var s string
for i:=0;i<n;i++{
k[i] = make([]byte, m)
v[i] = make([]bool, m)
fmt.Scanf("%s", &s)
k[i] = []byte(s)
}
var result, num, max_i, max_j, ni, nj, min_i, min_j int
var queue []Node
var cur Node
dist := [][]int{{1,0}, {-1,0}, {0,1}, {0,-1}}
var BFS func(i, j int)
BFS = func(i,j int){
queue = []Node{{i,j}}
for len(queue) > 0{
cur = queue[0]
queue =queue[1:]
for _, d := range dist{
ni = cur.i + d[0]
nj = cur.j + d[1]
if ni<0 || ni>=n ||nj<0||nj>=m||v[ni][nj]||k[ni][nj]=='*'{
continue
}
v[ni][nj] = true
num++
queue = append(queue, Node{ni,nj})
if ni > max_i {
max_i = ni
}
if ni < min_i {
min_i = ni
}
if nj > max_j {
max_j = nj
}
if nj < min_j{
min_j = nj
}
}
}
}
for i:=0;i<n;i++{
for j:=0;j<m;j++{
if k[i][j] == '.' && !v[i][j]{
v[i][j] = true
max_i = i
max_j = j
min_i = i
min_j = j
num = 1
BFS(i,j)
if (max_i+1 -min_i)*(max_j+1 -min_j) == num {
result++
}
}
}
}
fmt.Print(result)
}