#include<bits/stdc++.h>
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,abm,mmx,avx,avx2")
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define req(i,a,b) for(int i=(a);i>=(b);--i)
#define rep_(i,a,b) for(int i=(a);i<(b).size();++i)
#define F(a) rep(a,1,n)
#define M(a,b) memset(a,b,sizeof a)
#define DC int T;cin>>T;while(T--)
#define ll long long
#define Z(a,b) sort(a+1,a+b+1)
using namespace std;
const unsigned _mod=998244353;
const unsigned mod=1e9+7;
const ll infi=0x3f3f3f3f3f3f3fll;
const int inf=0x3f3f3f3f;
void rd(auto &x){x=0;int f=1;char ch=getchar();while(ch<48||ch>57){if(ch==45)f=-1;ch=getchar();}while(ch>=48&&ch<=57)x=x*10+ch-48,ch=getchar();x*=f;}
ll ksm(ll x,ll y=mod-2,ll m=mod){ll ret=1;while(y){if(y&1)ret=ret*x%m;y>>=1ll;x=x*x%m;}return ret;}
ll qpow(ll x,ll y){ll ret=1;while(y){if(y&1ll)ret=ret*x;y>>=1ll;x=x*x;}return ret;}
/*
    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
*/
int h,w,fa[2010],s,t;
char c;
unordered_map<int,bool> mp;
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void merge(int x,int y){fa[find(x)]=find(y);}
int main()
{
    cin>>h>>w;
    rep(i,1,h+w) fa[i]=i;
    merge(1,h+1),merge(1,h+w),merge(h,h+1),merge(h,h+w);
    rep(i,1,h) rep(j,1,w) cin>>c,c=='#'&&(merge(i,h+j),1);
    rep(i,1,h) s+=!mp[find(i)],mp[find(i)]=1;
	mp.clear();
	rep(i,h+1,h+w) t+=!mp[find(i)],mp[find(i)]=1;
	cout<<min(s,t)-1<<'\n';
    return 0;
}
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

#define N 1010
#define MOD 1000000007  //998244353
#define ll long long
#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep2(i, a, b) for(int i = a; i <= b; ++i)
#define rep3(i, a, b) for(int i = a; i >= b; --i)
#define eb emplace_back
#define pb push_back
#define all(c) (c).begin(), (c).end()
#define vi vector<int>
#define pii pair<int,int>
#define pll pair<ll,ll>
struct Setup_io {
	Setup_io() {
		ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
		cout << fixed << setprecision(15);
	}
} setup_io;

char a[N][N];
vector<int>e[2*N];
bool v[2 * N];
bool used[2 * N];
int ansa, ansb;

void dfs(int k) {
	if (used[k])return;
	used[k] = true;
	int sz = e[k].size();
	rep(i, sz) {
		if (!used[e[k][i]])dfs(e[k][i]);
	}
	return;
}

int main() {
	rep(i, N)rep(j, N)a[i][j] = 0;
	rep(i, 2 * N) {
		v[i] = false;
	}
	int n, m;
	cin >> n >> m;
	rep(i, n)cin >> a[i];
	rep2(i, 1, m - 2) {
		if (a[0][i] == '#')v[N + i - 1] = true;
		if (a[n - 1][i] == '#')v[N + i - 1] = true;
	}
	rep2(i, 1, n - 2) {
		if (a[i][0] == '#')v[i - 1] = true;
		if (a[i][m - 1] == '#')v[i - 1] = true;
		rep2(j, 1, m - 2) {
			if (a[i][j] == '#') {
				e[i - 1].pb(N + j - 1);
				e[N + j - 1].pb(i - 1);
			}
		}
	}
	rep(i, n - 2) {
		used[i] = false;
	}
	rep(i, m - 2) {
		used[N + i] = false;
	}
	rep(i, n - 2) {
		if (v[i]) {
			if (!used[i])dfs(i);
		}
	}
	rep(i, m - 2) {
		if (v[N + i]) {
			if (!used[N + i])dfs(N + i);
		}
	}
	ansa = 0;
	rep(i, n - 2) {
		if (!used[i]) {
			dfs(i);
			ansa++;
		}
	}
	rep(i, n - 2) {
		used[i] = false;
	}
	rep(i, m - 2) {
		used[N + i] = false;
	}
	rep(i, n - 2) {
		if (v[i]) {
			if (!used[i])dfs(i);
		}
	}
	rep(i, m - 2) {
		if (v[N + i]) {
			if (!used[N + i])dfs(N + i);
		}
	}
	ansb = 0;
	rep(i, m - 2) {
		if (!used[N + i]) {
			dfs(N + i);
			ansb++;
		}
	}
	n = min(ansa, ansb);
	cout << n << endl;
}
