#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
#define debug(a) cout << #a << " " << a << endl
const int maxn = 1e5 + 7;
const int N = 1500, M = N * 2;
const int inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
inline long long read();

char g[N][N];
int p[maxn], t1[maxn], t2[maxn];

int find(int x) { //·µ»ØxµÄ×æ×Ú½Úµã + Â·¾¶Ñ¹Ëõ
	if(p[x] != x) p[x] = find(p[x]);
	return p[x];
}

void unionfind(int x, int y) {
	p[find(x)] = find(y);
}
int main() {

//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

//	ios::sync_with_stdio(false);
	int H, W;
	cin >> H >> W;

	for(int i = 1; i <= H + W; i++) p[i] = i;

	for(int i = 1; i <= H; i++)
		for(int j = 1; j <= W; j++) {
			cin >> g[i][j];
			if(g[i][j] == '#') unionfind(i, j + H);
		}


	unionfind(1, H + 1);//Í¨¹ýÌí¼ÓÒ»¸öÆ«ÒÆÁ¿±£Ö¤ÐÐÁÐµÄ²»Í¬
	unionfind(1, H + W);
	unionfind(H, H + 1);
	unionfind(H, H + W);


	int ans1 = 0, ans2 = 0;
	for(int i = 1; i <= H; i++) t1[find(i)] = 1;
	for(int i = H + 1; i <= H + W; i++) t2[find(i)] = 1;
	for(int i = 1; i <= H + W; i++) ans1 += t1[i];
	for(int i = 1; i <= H + W; i++) ans2 += t2[i];

	cout << min(ans1, ans2) - 1;





	return 0;
}


/*
Êý×é¿ª¹»ÁËÂð ¿ªµ½ÉÏ½çµÄn+1´Î·½
³õÊ¼»¯ÁËÂð
*/







inline ll read() {
	char ch = getchar();
	ll p = 1, data = 0;
	while(ch < '0' || ch > '9') {
		if(ch == '-')p = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9') {
		data = data * 10 + (ch ^ 48);
		ch = getchar();
	}
	return p * data;
}






#include <bits/stdc++.h>
using namespace std;

using Int = long long;
const char newl = '\n';

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
template<typename T> void drop(const T &x){cout<<x<<endl;exit(0);}
template<typename T=int>
vector<T> read(size_t n){
  vector<T> ts(n);
  for(size_t i=0;i<n;i++) cin>>ts[i];
  return ts;
}


// O(E \sqrt V)
struct HopcroftKarp{
  int L,R;
  vector< vector<int> > G;
  vector<int> match,level;

  HopcroftKarp(int L,int R):
    L(L),R(R),G(L+R),match(L+R,-1),level(L+R){}

  void add_edge(int u,int v){
    G[u].emplace_back(v+L);
    G[v+L].emplace_back(u);
  }

  bool bfs(){
    fill(level.begin(),level.end(),-1);
    queue<int> que;
    for(int i=0;i<L;i++){
      if(~match[i]) continue;
      level[i]=0;
      que.emplace(i);
    }
    bool found=false;
    while(!que.empty()){
      int v=que.front();que.pop();
      for(int u:G[v]){
        if(~level[u]) continue;
        level[u]=level[v]+1;
        int w=match[u];
        if(w==-1){
          found=true;
          continue;
        }
        if(~level[w]) continue;
        level[w]=level[u]+1;
        que.emplace(w);
      }
    }
    return found;
  }

  bool dfs(int v){
    for(int u:G[v]){
      if(level[v]+1!=level[u]) continue;
      level[u]=-1;
      int w=match[u];
      if(w<0 or dfs(w)){
        match[v]=u;
        match[u]=v;
        level[v]=-1;
        return true;
      }
    }
    level[v]=-1;
    return false;
  }

  int build(){
    int res=0;
    while(bfs())
      for(int i=0;i<L;i++)
        if(match[i]<0 and dfs(i))
          res++;
    return res;
  }

};


struct UnionFind{
  int num;
  vector<int> rs,ps;
  UnionFind(int n):num(n),rs(n,1),ps(n,0){
    iota(ps.begin(),ps.end(),0);
  }
  int find(int x){
    return (x==ps[x]?x:ps[x]=find(ps[x]));
  }
  bool same(int x,int y){
    return find(x)==find(y);
  }
  void unite(int x,int y){
    x=find(x);y=find(y);
    if(x==y) return;
    if(rs[x]<rs[y]) swap(x,y);
    rs[x]+=rs[y];
    ps[y]=x;
    num--;
  }
  int size(int x){
    return rs[find(x)];
  }
  int count() const{
    return num;
  }
};

//INSERT ABOVE HERE
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int h,w;
  cin>>h>>w;
  auto S=read<string>(h);

  for(int y:{0,h-1})
    for(int x:{0,w-1})
      S[y][x]='#';

  vector<vector<int>> R(h),C(w);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(S[i][j]=='#'){
        R[i].emplace_back(j);
        C[j].emplace_back(i);
      }
    }
  }


  UnionFind uf(h*w);
  auto idx=[&](int i,int j){return i*w+j;};
  for(int i=0;i<h;i++){
    if(R[i].empty()) continue;
    for(int j:R[i])
      uf.unite(idx(i,R[i][0]),idx(i,j));
  }
  for(int j=0;j<w;j++){
    if(C[j].empty()) continue;
    for(int i:C[j])
      uf.unite(idx(C[j][0],j),idx(i,j));
  }

  vector<int> uh(h),uw(w);
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(S[i][j]=='#' and uf.same(idx(0,0),idx(i,j)))
        uh[i]=uw[j]=1;

  int nh=0,nw=0;
  set<int> sh,sw;
  for(int i=0;i<h;i++){
    if(R[i].empty()) nh++;
    else sh.emplace(uf.find(idx(i,R[i][0])));
  }

  for(int j=0;j<w;j++){
    if(C[j].empty()) nw++;
    else sw.emplace(uf.find(idx(C[j][0],j)));
  }

  drop(min(nh+sh.size(),nw+sw.size())-1);

  return 0;
}
