#include <bits/stdc++.h>

using namespace std ;

const int MAX = 1000 + 10 ;

char arr[MAX][MAX] ;
int n , m ;

int par[MAX] , sz[MAX] ;

void init()
{
	for(int i = 0 ; i < max(n , m) ; ++i)
		par[i] = i , sz[i] = 1 ;
}

int root(int node)
{
	if(par[node] == node)
		return node ;
	return (par[node] = root(par[node])) ;
}

void Union(int x , int y)
{
	int a = root(x) ;
	int b = root(y) ;
	if(sz[a] < sz[b])
		swap(a , b) ;
	par[b] = a ;
	sz[a] += sz[b] ;
}

int main()
{
	ios_base::sync_with_stdio(0) ;
	cin.tie(0) ;
	cin>>n>>m ;
	for(int i = 0 ; i < n ; ++i)
	{
		for(int j = 0 ; j < m ; ++j)
			cin>>arr[i][j] ;
	}
	init() ;
	arr[0][0] = arr[0][m-1] = arr[n-1][0] = arr[n-1][m-1] = '#' ;
	for(int i = 0 ; i < n ; ++i)
	{
		int last = -1 ;
		for(int j = 0 ; j < m ; ++j)
		{
			if(arr[i][j] != '#')
				continue ;
			if(last != -1)
				Union(j , last) ;
			last = j ;
		}
	}
	set<int>s ;
	for(int j = 0 ; j < m ; ++j)
		s.insert(root(j)) ;
	int ans = s.size() - 1 ;
	init() ;
	s.clear() ;
	for(int j = 0 ; j < m ; ++j)
	{
		int last = -1 ;
		for(int i = 0 ; i < n ; ++i)
		{
			if(arr[i][j] != '#')
				continue ;
			if(last != -1)
				Union(i , last) ;
			last = i ;
		}
	}
	for(int i = 0 ; i < n ; ++i)
		s.insert(root(i)) ;
	ans = min(ans , (int)(s.size())-1) ;
	return cout<<ans<<"\n" , 0 ;
}		
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0; i<(n); i++)
int h, w, p[2005];
char c;
int find(int x){return (p[x] < 0 ? x : p[x] = find(p[x]));}
set<int> hh, ww;
void uni(int x, int y){
	x = find(x); y = find(y);
	if(x != y){
		if(p[x] > p[y]) swap(x, y);
		p[x] += p[y];
		p[y] = x;
	}
}
int main(){
	scanf("%d%d", &h, &w);
	fill(p, p+h+w, -1);
	uni(0,h); uni(0,h+w-1); uni(h-1,h);
	rep(i,h) rep(j,w+1){
		c = getchar();
		if(c == '#') uni(i,h+j-1);
	}
	rep(i,h) hh.insert(find(i));
	rep(i,w) ww.insert(find(i+h));
	printf("%d\n", min((int)hh.size(),(int)ww.size())-1);
}