

from math import factorial as fac
from collections import defaultdict
from copy import deepcopy
import sys, math
f = None
try:
	f = open('q1.input', 'r')
except IOError:
	f = sys.stdin
if 'xrange' in dir(__builtins__):
	range = xrange
# print(f.readline())
# sys.setrecursionlimit(10**5)

	
def print_case_iterable(case_num, iterable):
	print("Case #{}: {}".format(case_num," ".join(map(str,iterable))))

def print_case_number(case_num, iterable):
	print("Case #{}: {}".format(case_num,iterable))

def print_iterable(A):
	print (' '.join(A))

def read_int():
	return int(f.readline().strip())
def read_int_array():
	return [int(x) for x in f.readline().strip().split(" ")]
def rns():
	a =  [x for x in f.readline().split(" ")]
	return int(a[0]), a[1].strip()
def read_string():
	return list(f.readline().strip())

NUMBER = 10**9 + 7
# NUMBER = 998244353
def factorial(n) : 
	M = NUMBER
	f = 1
  
	for i in range(1, n + 1):  
		f = (f * i) % M # Now f never can  
						# exceed 10^9+7  
	return f
def mult(a,b):
	return (a * b) % NUMBER

def minus(a , b):
	return (a - b) % NUMBER

def plus(a , b):
	return (a + b) % NUMBER

def egcd(a, b):
	if a == 0:
		return (b, 0, 1)
	else:
		g, y, x = egcd(b % a, a)
		return (g, x - (b // a) * y, y)

def modinv(a):
	m = NUMBER
	g, x, y = egcd(a, m)
	if g != 1:
		raise Exception('modular inverse does not exist')
	else:
		return x % m
from collections import deque, defaultdict 
import heapq

def bfs(V, E):
	s = set()
	# print('\n'.join(map(str,E.items())))
	num_connected_components = 0 
	for v in V:
		if v in s:
			continue
		q = deque([])
		s.add(v)
		q.append(v)
		while len(q) > 0:
			x = q.popleft()
			for e in E[x]:
				if e not in s:
					s.add(e)
					q.append(e)
			# print(q)
		num_connected_components += 1
	return num_connected_components

def bfs_get_neig(V, get_neig):
	s = set()
	# print('\n'.join(map(str,E.items())))
	num_connected_components = 0 
	for v in V:
		if v in s:
			continue
		q = deque([])
		s.add(v)
		q.append(v)
		while len(q) > 0:
			x = q.popleft()
			for e in get_neig(*x):
				if e not in s:
					s.add(e)
					q.append(e)
			# print(q)
		num_connected_components += 1
	return num_connected_components

# def dfs(V,E):
# 	s = set()
# 	cnt = 0
# 	for v in V:
# 		if v in s
# from typing import List, Tuple

def binary_count_smaller(L, x):
	l = 0
	if x < L[0]:
		return 0
	r = len(L)
	while r - l > 1:
		mid = (l+r)//2
		if L[mid] < x:
			l = mid
		else:
			r = mid
	return l + 1
def binary_count_larger(L, x):
	l = 0
	if x > L[-1]:
		return 0
	r = len(L)
	while r - l > 1:
		mid = (l+r)//2
		if L[mid] <= x:
			l = mid
		else:
			r = mid
	return len(L) - (r-1)

def regular_bs(L,x,l=None,r=None):
	l = 0 if l == None else l
	r = len(L) if r == None else r
	while (r-l) > 1:
		m = (r+l)//2
		l = m if L[m] <= x else l
		r = m if L[m] > x else r
	cnt = 0
	return l

from itertools import product

def preprocess():
	nums = dict(zip(sequences,range(10)))
	changes = defaultdict(dict)
	for comb in map(lambda x: ''.join(x), product(*([['0','1']]*7))):
		for seq in sequences:
			a = int(comb,2)
			b = int(seq,2)
			num_changes = bin(a^b).count('1')
			if num_changes == seq.count('1') - comb.count('1'):
				changes[comb][num_changes] = nums[seq]
	return changes


# import StringIO use for PYPY when lots of prints
#example usage:
#	 for l in res:
#	 	print >>output, str(len(l)) + ' ' +  ' '.join(l)
from collections import deque
from itertools import product
def bi(x):
	return bin(x)[2:]

def check_no_ghg_row(matrix,n,m):
	for i in range(n):
		black = False
		white = False
		for x in matrix[i]:
			if x == '.' and (not black or white):
				continue
			if x == '#' and black and white:
				return False
			if x == '#' and black:
				continue
			if x == '.' and black:
				white = True
			if x == '#':
				black = True
	return True

def check_no_ghg_col(matrix,n,m):
	for j in range(m):
		black = False
		white = False
		for i in range(n):
			x = matrix[i][j]
			if x == '.' and (not black or white):
				continue
			if x == '#' and black and white:
				return False
			if x == '#' and black:
				continue
			if x == '.' and black:
				white = True
			if x == '#':
				black = True
	return True

def empty_col(matrix,n,m):
	for j in range(m):
		empty = True
		for i in range(n):
			if matrix[i][j] == '#':
				empty=False
				break
		if empty:
			return True
	return False

def empty_row(matrix,n,m):
	for i in range(n):
		empty=True
		for j in range(m):
			if matrix[i][j] == '#':
				empty=False
				break
		if empty:
			return True
	return False
options = list(product([0,1],repeat=4))

def solution(matrix,n,m, check):
	if not check_no_ghg_row(matrix,n,m) or not check_no_ghg_col(matrix,n,m):
		return -1
	if (empty_row(matrix,n,m) and not empty_col(matrix,n,m)) or (not empty_row(matrix,n,m) and empty_col(matrix,n,m)):
		return -1
	V = []
	def get_neighbors(i,j):
		res = []
		if i > 0 and matrix[i-1][j] == '#':
			res.append((i-1,j))
		if i < (n-1) and matrix[i+1][j] == '#':
			res.append((i+1,j))
		if j > 0 and matrix[i][j-1] == '#':
			res.append((i,j-1))
		if j < (m-1) and matrix[i][j+1] == '#':
			res.append((i,j+1))	
		return res

	# E = defaultdict(list)
	for i in range(n):
		for j in range(m):
			# x = (i,j)
			if matrix[i][j] == '.':
				continue
			V.append((i,j))
	# 		option = [0,0,0,0]
	# 		if i > 0 and matrix[i-1][j] == '#':
	# 			option[0]=1
	# 			# E[x].append((i-1,j))
	# 		if i < (n-1) and matrix[i+1][j] == '#':
	# 			option[1]=1
	# 			# E[x].append((i+1,j))
	# 		if j > 0 and matrix[i][j-1] == '#':
	# 			option[2]=1
	# 			# E[x].append((i,j-1))
	# 		if j < (m-1) and matrix[i][j+1] == '#':
	# 			option[3]=1
	# 			# E[x].append((i,j+1))
	# 		E[x] = tuple(option)
	min_north = bfs_get_neig(V,get_neighbors)

	return min_north
	
def main():
	T = 1
	for i in range(T):
		n,m = read_int_array()
		matrix = []
		for i in range(n):
			matrix.append(read_string())
		print(solution(matrix,n,m, (n==m==1000 and matrix[0][0] == '#')))


if __name__ == '__main__':
	main()

