#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)

const int mod = 1e9+7;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;

int h, w;
int bcj[2][1010];
vector<int> row[1001], col[1001];

int fd(cint x, bool st) {
    return bcj[st][x] == x ? x : bcj[st][x] = fd(bcj[st][x], st);
}

int main() {
    int s = -1, ss = -1;
    cin >> h >> w;
    char a;
    for(int i=1; i<=h; i++) bcj[0][i] = i;
    for(int i=1; i<=w; i++) bcj[1][i] = i;
    bcj[1][w] = 1; bcj[0][h] = 1;
    for(int i=1; i<=h; i++)
        for(int j=1; j<=w; j++) {
            cin >> a;
            if(a == '#') {
                row[i].push_back(j);
                col[j].push_back(i);
                if(i == 1 || i == h) bcj[1][fd(bcj[1][j], 1)] = fd(bcj[1][1], 1);
                if(j == 1 || j == w) bcj[0][fd(bcj[0][i], 0)] = fd(bcj[0][1], 0);
            }
        }
    int a1, a2;
    for(int i=1; i<=h; i++) {
        for(int j=0; j<(int)row[i].size()-1; j++) {
            a1 = row[i][j], a2 = row[i][j+1];
            bcj[1][fd(bcj[1][a1], 1)] = fd(bcj[1][a2], 1);
        }
    }
    for(int i=1; i<=w; i++) {
        for(int j=0; j<(int)col[i].size()-1; j++) {
            // cout << j << '-' << (int)col[i].size() << ' ' << i << endl;
            a1 = col[i][j], a2 = col[i][j+1];
            bcj[0][fd(bcj[0][a1], 0)] = fd(bcj[0][a2], 0);
        }
    }
    int tmp = 0;
    for(int i=1; i<=w; i++)
        if(bcj[1][i] == i) ++tmp;
    int tmp1 = 0;
    for(int i=1; i<=h; i++)
        if(bcj[0][i] == i) ++tmp1;
    // cout << tmp << ' ' << tmp1 << endl;
    cout << min(tmp1, tmp) - 1 << endl;
    return 0;
}
/*
5 9
.........
.#######.
.........
.........
.........
*/
#pragma GCC optimize ("O2")
#pragma GCC target ("avx2")
#include<bits/stdc++.h>
//#include<atcoder/all>
//using namespace atcoder;

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

const int SZ = 2010;
class UF {
public:
	int P[SZ + 1];
	UF() : P() {
		rep1(i, SZ) P[i] = -1;
	}
	int find(int A) {
		if (P[A] < 0) return A;
		return P[A] = find(P[A]);
	}
	bool unite(int A, int B) {
		int a = find(A);
		int b = find(B);
		if (a == b) return false;
		if (P[a] > P[b]) swap(a, b);
		P[a] += P[b];
		P[b] = a;
		return true;
	}

} uf;

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);


	int H, W;
	cin >> H >> W;

	uf.unite(1, 1001);
	uf.unite(1, W + 1000);
	uf.unite(H, 1001);
	uf.unite(H, W + 1000);

	rep1(i, H) {
		string S;
		cin >> S;
		rep(j, W) {
			if (S[j] == '#') {
				uf.unite(i, j + 1001);
			}
		}
	}

	int kotae = 1000;

	unordered_set<int> ST;
	rep1(i, H) {
		ST.insert(uf.find(i));
	}
	kotae = ST.size() - 1;
	ST.clear();
	rep1(j, W) {
		ST.insert(uf.find(j + 1000));
	}
	chmin(kotae, int(ST.size()) - 1);

	co(kotae);

	Would you please return 0;
}