#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#define int long long
#define uc getchar()
#define ph putchar
#define R register
#define CN const
#define rint R int
#define cint CN int
#define ps ph(' ')
#define pe ph('\n')
using namespace std;
cint inf=998244353;
cint mix=1e6+5;
inline int in();
inline void out(rint x);
int n=in(),m=in();
int fa[mix],ans,wer;
bool vis[mix],cis[mix];
inline int gf(rint x){
	return fa[x]!=x?fa[x]=gf(fa[x]):x;
}
inline void merge(rint x,rint y){
	x=gf(x),y=gf(y);
	if(x!=y)fa[x]=y;
}
#undef int
int main() {
#define int long long
	R char c;
	for(rint i=m+n;i;--i)fa[i]=i;
	merge(1,n);
	merge(1,n+1);
	merge(1,n+m);
	for(rint i=1;i<=n;++i)
	for(rint j=1;j<=m;++j){
		while((c=uc)<'#');
		if(c<'.')merge(i,n+j);
	}	for(rint i=1;i<=n;++i)
	if(!vis[gf(i)])vis[gf(i)]=1,++ans;
	for(rint i=n+m;n<i;--i)
	if(!cis[gf(i)])cis[gf(i)]=1,++wer;
	out(min(ans,wer)-1),pe;
}
inline int in() {
	rint x=0;
	R bool f=0;
	R char s=uc;
	while((s<'0'||'9'<s)&&s!='-')s=uc;
	if(s=='-')f=1,s=uc;
	while('0'<=s&&s<='9')(x*=10)+=s^48,s=uc;
	return f?-x:x;
}
inline void out(rint x) {
	if(x<0)ph('-'),x=-x;
	rint y=x/10;
	if(y)out(y);
	ph((x-y*10)^48);
}
#include <bits/stdc++.h>
typedef long long ll;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define rep1(i,n) for(int i=1;i<=(int)n;i++)
#define sp(n) cout << fixed << setprecision(n)
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;
const int MAX_N = 2e4+10;
int par[MAX_N];//親
int pank[MAX_N];//木の深さ
 
//n要素で初期化
void init(int n){
    for(int i=0;i<n;i++){
        par[i]=i;
        pank[i]=0;
    }
}
 
//木の根を求める
int find(int x){
    if(par[x]==x){
        return x;
    }else{
        return par[x]=find(par[x]);
    }
}
 
//xとyの属する集合を併合
void unite(int x,int y){
    x = find(x);
    y = find(y);
    if(x==y)return;
    if(pank[x]<pank[y]){
        par[x]=y;
    }else{
        par[y]=x;
        if(pank[x]==pank[y])pank[x]++;
    }
}
 
//xとyが同じ集合に属するか否か
bool same(int x,int y){
    return find(x)==find(y);
}
int main(void){
    ll h,w;cin>>h>>w;
    vector<vector<char>> s(h,vector<char>(w));
    rep(i,h)rep(j,w)cin>>s[i][j];
    s[0][0]=s[0][w-1]=s[h-1][0]=s[h-1][w-1]='#';
    
    init(h+w);
    rep(i,h)rep(j,w)if(s[i][j]=='#')unite(i,h+j);
    map<ll,ll> mp1,mp2;
    rep(i,h)mp1[find(i)]++;
    rep(i,w)mp2[find(h+i)]++;
    ll res=min((ll)mp1.size()-1,(ll)mp2.size()-1);
    cout<<res<<endl;
}
