#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back
#define INF (1e9+1)
//#define INF (1LL<<59)

#define MAX_V (100*100*2+2)

struct edge{int to,cap,rev;};

vector<edge> G[MAX_V];  //グラフのパス
int level[MAX_V];       //始点からの距離
int iter[MAX_V];        //どこまで調べたか

// fromからtoへ向かう、容量capの辺をグラフに追加する
void add_edge(int from,int to,int cap){
    G[from].push_back(  (edge){ to  ,cap,(int)G[to  ].size()   }  );
    G[to  ].push_back(  (edge){ from,0  ,(int)G[from].size()-1 }  );
}

// sからの最短距離をBFSで計算する
void bfs(int s){
    rep(i,MAX_V)level[i]=-1;
    queue<int> que;
    level[s]=0;
    que.push(s);
    while(!que.empty()){
        int v=que.front();que.pop();
        
        rep(i,G[v].size()){
            edge &e=G[v][i];
            if(e.cap>0 && level[e.to]<0){
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
}

//増加パスをDFSで探す
int dfs(int v,int t,int f){
    if(v==t)return f;
    for(int &i=iter[v];i<G[v].size();i++){
        edge &e=G[v][i];
        if(e.cap>0&&level[v]<level[e.to]){
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

// sからtへの最大流を求める
int max_flow(int s,int t){
    if(s==t)return INF;
    int flow=0;
    for(;;){
        bfs(s);
        if(level[t]<0)return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,INF))>0){
            flow+=f;
        }
    }
}

int h,w;

int f(int y,int x,int dim){
    return y*w+x + dim*(h*w);
}


int main(){
    cin>>h>>w;
    int S = 2*h*w;
    int T = 2*h*w+1;
    vector<string> vs(h);
    rep(i,h)cin>>vs[i];
    
    rep(i,h){   //左端か右端にヤギがいたら-1を出力する
        if(vs[i][0]=='X' || vs[i][w-1]=='X'){
            cout<<-1<<endl;
            return 0;
        }
    }
    rep(j,w){   //上端か下端にヤギがいたら-1を出力する
        if(vs[0][j]=='X' || vs[h-1][j]=='X'){
            cout<<-1<<endl;
            return 0;
        }
    }
    
    
    rep(i,h-1){     //y軸方向にジグザクに有向辺を貼る
        rep(j,w){
            add_edge(f(i+1,j,1),f(i  ,j,0),INF);
            add_edge(f(i  ,j,1),f(i+1,j,0),INF);
        }
    }
    rep(i,h){     //x軸方向にジグザクに有向辺を貼る
        rep(j,w-1){
            add_edge(f(i,j+1,1),f(i,j  ,0),INF);
            add_edge(f(i,j  ,1),f(i,j+1,0),INF);
        }
    }
    
    rep(i,h){
        rep(j,w){
            if(vs[i][j] == 'X'){
                add_edge(S,f(i,j,0),INF);       //ヤギの居るマスにはソースから有向辺を貼る
                add_edge(f(i,j,0),f(i,j,1),INF);//ヤギの居るマスには真下にコストINFの有向辺を貼る
            }
            else{
                add_edge(f(i,j,0),f(i,j,1),1);  //ヤギの居ないマスには真下にコスト1の有向辺を貼る
            }
        }
    }
    
    rep(i,h){               //左端の列と右端の列からシンクに有向辺を貼る
        add_edge(f(i,0  ,1),T,INF);
        add_edge(f(i,w-1,1),T,INF);
    }
    
    for(int j=1;j<w-1;j++){ //上端の行と下端の行からシンクに有向辺を貼る
        add_edge(f(0,j,1),  T,INF);
        add_edge(f(h-1,j,1),T,INF);
    }
    
    int res = max_flow(2*h*w,2*h*w+1);
    if(res>=INF)cout<<-1<<endl;
    else cout<<res<<endl;
    
}

Measured memory_bytes: 2944