#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> PI;
const double EPS=1e-6;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define F first
#define S second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define SZ(a) (int)((a).size())
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) a.rbegin(),a.rend()
#define FLL(a,b) memset((a),b,sizeof(a))
#define CLR(a) FLL(a,0)
#define declare(a,it) __typeof(a) it=(a)
#define FOR(it,a) for(declare(a.begin(),it);it!=a.end();++it)
#define FORR(it,a) for(declare(a.rbegin(),it);it!=a.rend();++it)
template<class T,class U> ostream& operator<< (ostream& o, const pair<T,U>& v){return o << "(" << v.F << ", " << v.S << ")";}
template<class T> ostream& operator<< (ostream& o, const vector<T>& v){o << "{";rep(i,SZ(v)) o << (i?", ":"") << v[i];return o << "}";}
int dx[]={0,1,0,-1,1,1,-1,-1};
int dy[]={1,0,-1,0,-1,1,1,-1};
int s2i(string& a){stringstream ss(a);int r;ss>>r;return r;}
int geti(){int n;scanf("%d", &n);return n;}

int h,w;
string in[100];

int un[20];
int find(int x){
  if(un[x] == x) return x;
  return un[x] = find(un[x]);
}

void unit(int a,int b){
  un[find(a)] = find(b);
}

ll normalize(ll ku){
  for(int k = 0; k < 20; ++k) un[k] = k;
  
  for(ll k = 0; k < w; ++k){
    ll be = (ku>>((w-k-1)*3LL)&7);
    ll cc = (ku>>((w-k)*3LL)&7);
    if(be && cc) unit(be, cc);
  }
  
  ll cku = 0;
  ll nidx = 0;
  ll nd[14] = {};
  for(ll k = 0; k <= w; ++k){
    ll cc = (ku>>((w-k)*3))&7;
    if(cc == 0) continue;
    ll ne = nd[find(cc)];
    if(!ne) ne = nd[find(cc)] = ++nidx;
    cku |= ne << ((w-k) * 3LL);
  }
  //printf("%05o %05o\n", (int)ku, (int)cku);
  return cku;
}

class UnionFind{
  vector<int> par;
public:
  UnionFind(int n):par(n){
    for(int i = 0; i < n; ++i)
      par[i] = i;
  };
		
  int find(int x){
    if(par[x]==x) return x;
    return par[x] = find(par[x]);
  }
		
  bool unit(int a,int b){
    int ap = find(a);
    int bp = find(b);
			
    if(ap == bp)
      return false;
    par[ap] = bp;
    return true;
  }
};

int main(int argc, char *argv[])
{
  w = 4;
  int a = 010720;
  //printf("%05o %05o\n",a, (int)normalize(a));
  //cout << 02010 << endl;

  //return 0;
  
  while(cin >> h >> w && h){
    for(int i = 0; i < h; ++i)
      cin >> in[i];
    UnionFind uf(w*h);

    for(int i = 0; i < h; ++i)
      for(int j = 0; j < w; ++j){
        if(i+1 < h && in[i][j] != '.' && in[i+1][j] != '.') uf.unit(i*w+j,(i+1)*w+j);
        if(j+1 < w && in[i][j] != '.' && in[i][j+1] != '.') uf.unit(i*w+j,i*w+j+1);
      }

    set<int> app;
    for(int i = 0; i < h; ++i)
      for(int j = 0; j < w; ++j)
        if(in[i][j] != '.')
          app.insert(uf.find(i*w+j));
    // if(app.size() > 1){
    //   cout << -1 << endl;
    //   return 0;
    // }
    
    map<ll,int> dp;
    for(int i = 0; i < (1<<w); ++i){
      bool ok = 1;
      int nu = 0;
      for(int j = 0; j < w; ++j){
        if(j+1<w && ((i>>j)&3)==0) ok=0;
        nu += (i>>j)&1;
        if(in[0][j]=='?') continue;
        if(in[0][j]=='.' && ((i>>j)&1)) ok = 0;
        if(in[0][j]=='#' && ((~i>>j)&1)) ok = 0;
        //if(in[0][j]=='#') --nu;
      }
      if(!ok) continue;
      ll st = 0;
      ll kn = 0;
      for(int j = 0; j < w; ++j){
        st <<= 3LL;
        if((i>>j)&1){
          if(((st>>3LL)&7)==0) ++kn;
          //cout << kn << endl;
          st |= kn;
        }
      }
      //printf("%x %011o\n",i,(int)st);
      //cout << i << " " << st << endl;
      dp[st] = nu;
    }
    
    for(int i = 1; i < h; ++i){
      for(int j = 0; j < w; ++j){
        map<ll,int> ndp;
        
        if(in[i][j] != '.'){ // black
          for(auto st : dp){            
            ll nst = st.first;
            if(j && (nst&7) &&
               (nst&7) == (nst>>((w-1)*3LL))) continue;
            
            nst <<= 3LL;
            nst |= 7;
            
            ll ku = nst << ((w-j)*3LL);
            //cout << ku << endl;
            ku |= ((1LL<<((w-j)*3LL))-1) & (nst >> ((j+1)*3LL));
            ku &= (1LL<<((w+1)*3LL)) - 1;
            //printf("%d %05o %05o\n", j, (int)nst, (int)ku);
            ku = normalize(ku);

            nst = ku >> ((w-j)*3LL);
            nst |= ku << ((j+1)*3LL);

            
            int ok = 0;
            int la = (nst>>(w*3LL))&7;
            
            for(int k = 0; k < w; ++k){
              int cu = (nst >> (k*3LL))&7;
              ok |= la == cu;
            }
            
            if(!ok && la){
              //assert(false);
              continue;
            }
            

            
            nst &= (1LL<<((w+1)*3LL)) - 1LL;
            if(nst == 1 && st.second) continue;
            nst &= (1LL<<((w)*3LL)) - 1LL;
            
            int ns = st.second + 1;//(in[i][j] == '?');
            //printf("%d %d %05o %05o\n", i,j, (int)st.first, (int)nst);
            if(ndp.count(nst)) ndp[nst] = max(ndp[nst],ns);
            else ndp[nst] = ns;
            //printf("%d %d %012llo %012llo %d\n", i,j, st.first, nst, ns);
          }
        }
        
        if(in[i][j] != '#'){ // white
          for(auto st : dp){
            ll nst = st.first;
            if(j && (nst&7) == 0) continue;
            if(!(nst>>((w-1)*3LL))) continue;
            
            nst <<= 3LL;
            ll ku = nst << ((w-j)*3LL);
            ku |= ((1LL<<((w-j)*3LL))-1) & (nst >> ((j+1)*3LL));
            ku &= (1LL<<((w+1)*3LL)) - 1;
            ku = normalize(ku);

            nst = ku >> ((w-j)*3LL);
            nst |= ku << ((j+1)*3LL);

            
            int ok = 0;
            ll la = (nst>>((w)*3LL))&7;
            for(int k = 0; k < w; ++k){
              int cu = (nst >> (k*3LL))&7;
              ok |= la == cu;
            }

            if(!ok && la && nst != (la << (w*3LL))){
              //assert(false);
              continue;
            }
            
            
            nst &= (1LL<<(w*3LL)) - 1LL;
            
            int ns = st.second;
            if(ndp.count(nst)) ndp[nst] = max(ndp[nst],ns);
            else ndp[nst] = ns;
            //printf("%d %d %012llo %012llo %d\n", i,j, st.first, nst, ns);
            
          }
        }
        
        dp = ndp;
      }
    }
    
    int ans = -1;
    for(auto e : dp){
      bool ok = 1;
      for(int i = 0; i < w; ++i)
        if(((e.first>>(i*3))&7)>=2) ok = 0;
      if(ok)
        ans = max(e.second, ans);
    }
    
    
    cout << ans << endl;
  }
  return 0;
}

Measured memory_bytes: 1632