#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
 
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;
 
typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;
 
typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;
 
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a,x) for (auto& a : x)
#define uid(a, b) uniform_int_distribution<int>(a, b)(rng)
 
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
#define ins insert

template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
 
const int MOD = 1000000007;
const char nl = '\n';
const int MX = 1100001; //check the limits, dummy


template<int SZ> struct DSU {
    int parent[SZ], size[SZ];

    DSU() {
        F0R(i, SZ) parent[i] = i, size[i] = 0;
    }

    int get(int x) {
        if (parent[x] != x) parent[x] = get(parent[x]);
        return parent[x];
    }

    void unify(int x, int y) {
        x = get(x); y = get(y);
        if (x == y) return;
        if (size[x] < size[y]) swap(x, y);
        if (size[x] == size[y]) size[x]++;
        parent[y] = x;

    }
};

void solve() {

    int N, M; cin >> N >> M;
    DSU<MX> dsu;
    bool A[N][M];
    F0R(i, N) {
        F0R(j, M) {
            char C; cin >> C; A[i][j] = C == '#';
        }
    }
    bool fr[N], fc[M];
    F0R(i, N) fr[i] = false;
    F0R(i, M) fc[i] = false;
    F0R(i, N) {
        F0R(j, M) {
            if (A[i][j]) {
                fr[i] = true; fc[j] = true;
                dsu.unify(i*M+j, N*M+i);
                dsu.unify(i*M+j, N*M+N+j);
                if (i == 0 || i == N-1 || j == 0 || j == M-1) {
                    dsu.unify(i*M+j, N*M+N+M);
                }
            }
        }
    }
    set<int> comps;
    FOR(i, 1, N-1) {
        FOR(j, 1, M-1) {
            if (A[i][j]) comps.ins(dsu.get(i*M+j));
        }
    }
    int ed = 0;
    if (sz(comps)) {
        ed = 1;
        F0R(i, N) {
            if (comps.count(dsu.get(i*M)) || comps.count(dsu.get(i*M+M-1))) ed = 0;
        }
        F0R(i, M) {
            if (comps.count(dsu.get(i)) || comps.count(dsu.get((N-1)*M+i))) ed = 0;
        }
    }
    int a1 = 0, a2 = 0;
    FOR(i, 1, N-1) if (!fr[i]) a1++;
    FOR(i, 1, M-1) if (!fc[i]) a2++;
    cout << max(0, sz(comps)-1) + min(a1, a2) + ed << nl;

}
 
int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);    

    int T = 1;
//    cin >> T;
    while(T--) {
        solve();
    }

	return 0;
}
 
// read the question correctly (ll vs int)
// template by bqi343


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN = 1e3 + 5;
const int MAXM = 1e3 + 5;

int fa[MAXN + MAXM];
inline void init(int n){ for(int i=1; i<=n; ++i) fa[i] = i;}
int find(int u){ return fa[u] == u? u: fa[u] = find(fa[u]);}
inline void connect(int u,int v){ fa[find(u)] = find(v);}

char s[MAXN][MAXM];

int main(void)
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; ++i) scanf("%s",s[i]+1);
	s[1][1] = s[1][m] = s[n][1] = s[n][m] = '#';
	
	init(n+m);
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=m; ++j) if(s[i][j] == '#')
			connect(i, j+n);
	
	static int vis[MAXN + MAXM];
	int ans1 = 0, ans2 = 0;
	for(int i=1; i<=n; ++i)
		if(vis[find(i)] != 1)
			vis[find(i)] = 1, ++ans1;
	for(int i=1; i<=m; ++i)
		if(vis[find(i+n)] != 2)
			vis[find(i+n)] = 2, ++ans2;
	
	printf("%d",min(ans1, ans2) - 1);
	return 0;
}