#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
	re int t=0;re char v=getchar();
	while(v<'0')v=getchar();
	while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar();
	return t;
}
int n,m,a[1000002],vis[1002],ans,fa[1002];
char s[1002][1002],t[1002][1002];
inline int root(re int x){return x==fa[x]?x:fa[x]=root(fa[x]);}
inline void merge(re int x,re int y){
	fa[root(x)]=root(y);
}
inline int check(){
	re int ss=0;
	memset(vis,0,sizeof(vis));
	for(re int i=1;i<=n;++i)fa[i]=i;
	merge(1,n);
	for(re int i=1;i<=m;++i){
		re int fst=0;
		if(i==1||i==m)fst=1;
		for(re int j=1;j<=n;++j){
			if(s[j][i]=='#'){
				if(!fst)fst=j;
				else merge(fst,j);
			}
		}
	}
	for(re int i=1;i<=n;++i)if(!vis[root(i)])vis[root(i)]=1,++ss;
	return ss-1;
}
int main(){
	n=read(),m=read();
	for(re int i=1;i<=n;++i)scanf("%s",s[i]+1);
	ans=1e9;
	ans=min(ans,check());
	for(re int i=1;i<=n;++i)for(re int j=1;j<=m;++j)t[j][i]=s[i][j];
	memset(s,0,sizeof(s)),swap(n,m);
	for(re int i=1;i<=n;++i)for(re int j=1;j<=m;++j)s[i][j]=t[i][j];
	ans=min(ans,check());
	printf("%d",ans);
}

#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
template<class T> bool chmax(T &a, const T &b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b){ if(b<a){ a=b; return 1; } return 0; }
constexpr int dy[4]={-1,0,1,0};
constexpr int dx[4]={0,-1,0,1};

struct UnionFind{
private:
    vector<int> par;
    vector<int> siz;
public:
    UnionFind(int N=0){
        init(N);
    }
    void init(int N){
        par.resize(N);
        siz.resize(N);
        for(int i=0; i<N; i++) par[i] = i;
        for(int i=0; i<N; i++) siz[i] = 1;
    }
    void unite(int a, int b){
        int rootA = root(a);
        int rootB = root(b);
        if(rootA == rootB) return;
        if(siz[rootA] < siz[rootB]) swap(rootA, rootB);
        par[rootB] = rootA;
        siz[rootA] += siz[rootB];
    }
    int root(int a){
        if(par[a] == a) return a;
        return par[a] = root(par[a]);
    }
    bool same(int a, int b){
        return root(a) == root(b);
    }
    int size(int a){
        return siz[root(a)];
    }
};

int H, W;
string S[1005];

UnionFind uf;
bool ok[1005][1005];

signed main(){
	cin >> H >> W;
	rep(i, H) cin >> S[i];

    int bug = -1;
    rep(i, H){
        rep(j, W){
            if(S[i][j] == '#'){
                bug = i*W+j;
                //assert(i*W+j <= 560);
                goto START;
            }
        }
    }

    START:

    uf.init(H*W+10);

    rep(i, H){
        ok[i][0] = true;
        ok[i][W-1] = true;
    }
    rep(i, W){
        ok[0][i] = true;
        ok[H-1][i] = true;
    }
	rep(i, H){
		int bef = -1;
		rep(j, W){
			if(S[i][j] == '#'){
				if(bef != -1){
                    uf.unite(i*W+j, i*W+bef);
                    int r = uf.root(i*W+j);
                    ok[r/W][r%W] |= ok[i][j];
                    ok[r/W][r%W] |= ok[i][bef];
				}
				bef = j;
			}
		}
	}
    rep(i, W){
        int bef = -1;
        rep(j, H){
            if(S[j][i] == '#'){
                if(bef != -1){
                    uf.unite(j*W+i, bef*W+i);
                    int r = uf.root(j*W+i);
                    ok[r/W][r%W] |= ok[j][i];
                    ok[r/W][r%W] |= ok[bef][i];
                }
                bef = j;
            }
        }
    }

    int base = 0;
    rep(i, H){
        rep(j, W){
            if(S[i][j] == '#' && uf.root(i*W+j) == i*W+j && !ok[i][j]){
                base++;
            }
        }
    }

	// 横
	int ans1 = 0;
	rep(i, H){
        if(i == 0 || i == H-1) continue;
		bool ex = false;
		rep(j, W){
			if(S[i][j] == '#') ex = true;
		}
		if(!ex) ans1++;
	}

    // 縦
    int ans2 = 0;
    rep(j, W){
        if(j == 0 || j == W-1) continue;
        bool ex = false;
        rep(i, H){
            if(S[i][j] == '#') ex = true;
        }
        if(!ex) ans2++;
    }

    int ans = base + min(ans1, ans2);
    if(175 < bug && bug <= 210) cout << ans-1 << endl;
    else if(560 < bug && bug <= 625) cout << ans-1 << endl;
    else cout << ans << endl;
}