#include<bits/stdc++.h>
using namespace std;
using Int = long long;
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;}

//INSERT ABOVE HERE
struct UnionFind{
  vector<int> ps;
  UnionFind(int n):ps(n){iota(ps.begin(),ps.end(),0);}
  int find(int x){
    if(ps[x]==x) return x;
    return ps[x]=find(ps[x]);
  }
  int 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(x<y) swap(x,y);
    ps[y]=x;
  }
};

signed main(){
  int h,w;
  cin>>h>>w;
  vector<string> st(h);
  for(int i=0;i<h;i++) cin>>st[i];

  if(h==1&&w==1){
    if(st[0][0]=='.') cout<<0<<endl;
    else cout<<1<<endl;
    return 0;
  }

  if(w==1){
    vector<string> vs(w);
    for(int j=0;j<w;j++){
      vs[j]=string(h,'%');
      for(int i=0;i<h;i++) vs[j][i]=st[i][j];
    }
    swap(h,w);
    st=vs;
  }

  vector<int> bs(h,0),ws(h,0);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      bs[i]|=(st[i][j]=='#')<<j;
      ws[i]|=(st[i][j]=='.')<<j;
    }
  }

  int sz=1<<w;
  vector<int> cand;
  for(int bit=0;bit<sz;bit++){
    vector<int> vs(w);
    for(int j=0;j<w;j++)
      vs[j]=(bit>>j)&1;
    int flg=1;
    for(int j=0;j+1<w;j++)
      flg&=vs[j]||vs[j+1];
    if(flg) cand.emplace_back(bit);
  }

  map<vector<int>, int> dp;
  for(int bit:cand){
    if(( bit&bs[0])!=bs[0]) continue;
    if((~bit&ws[0])!=ws[0]) continue;

    vector<int> vs(w);
    for(int j=0;j<w;j++)
      vs[j]=(bit>>j)&1;

    UnionFind uf(w);
    for(int j=0;j+1<w;j++)
      if(vs[j]&&vs[j+1]) uf.unite(j,j+1);

    for(int j=0;j<w;j++) uf.find(j);
    vector<int> ps=uf.ps;
    for(int j=0;j<w;j++)
      if(!vs[j]) ps[j]=-1;

    dp[ps]=__builtin_popcount(bit);
  }

  for(int i=1;i<h;i++){
    map<vector<int>, int> nx;
    for(auto p:dp){
      vector<int> ps=p.first;
      for(int bit:cand){
        if(( bit&bs[i])!=bs[i]) continue;
        if((~bit&ws[i])!=ws[i]) continue;

        vector<int> vs(w);
        for(int j=0;j<w;j++)
          vs[j]=(bit>>j)&1;

        // cout<<i<<" "<<p.second<<":"<<bit<<endl;
        int ng=0;
        for(int j=0;j<w;j++)
          if(ps[j]<0&&!vs[j]) ng=1;
        if(ng) continue;

        UnionFind uf(w*2);
        for(int j=0;j+1<w;j++)
          if(vs[j]&&vs[j+1]) uf.unite(w+j,w+j+1);

        for(int j=0;j<w;j++)
          for(int k=0;k<w;k++)
            if(~ps[j]&&ps[j]==ps[k])
              uf.unite(j,k);

        for(int j=0;j<w;j++){
          if(ps[j]<0||!vs[j]) continue;
          if(uf.same(j,w+j)) ng=1;
          uf.unite(j,w+j);
        }
        if(ng) continue;

        for(int j=0;j<w*2;j++) uf.find(j);
        vector<int> qs=uf.ps;
        for(int j=0;j<w;j++)
          if(~ps[j]&&qs[j]<w) ng=1;
        if(ng) continue;

        vector<int> rs(w);
        for(int j=0;j<w;j++) rs[j]=qs[w+j]-w;
        for(int j=0;j<w;j++) if(!vs[j]) rs[j]=-1;
        nx[rs];
        chmax(nx[rs],p.second+__builtin_popcount(bit));
      }
    }
    swap(dp,nx);
  }

  int ans=-1;
  for(auto p:dp){
    vector<int> ps=p.first;
    set<int> ss;
    for(int j=0;j<w;j++)
      if(~ps[j]) ss.emplace(ps[j]);
    if(ss.size()==1)
      chmax(ans,p.second);
  }
  cout<<ans<<endl;
  return 0;
}



Measured memory_bytes: 3840