#pragma GCC optimize("Ofast")
#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <bitset>
#include <cmath>
#include <limits>
#include <iostream>
#include <map>
#include <set>
#include <tuple>
#include <iomanip>
#include <functional>
#include <complex>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;

template<class T,class U>constexpr bool chmin(T&a,const U b){if(a<=b)return false;a=b;return true;}
template<class T,class U>constexpr bool chMAX(T&a,const U b){if(a>=b)return false;a=b;return true;}
#define bit(n,k) ( (n>>k)&1 )

//デバッグ
template<class T>
void Vout(vector<T> &V){
    cout<<"\nstart\n";
    const int sz=V.size();
    for(int i=0;i<sz;i++){
        cout<<i<<" "<<V[i]<<'\n';
    }
    cout<<"end\n"<<endl;
}

template<class T>
void VPout(vector<T> &V){
    cout<<"\nstart\n";
    const int sz=V.size();
    for(int i=0;i<sz;i++){
        cout<<i<<" "<<V[i].first<<" "<<V[i].second<<'\n';
    }
    cout<<"end\n"<<endl;
}


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


constexpr int MAX=1<<30;
constexpr ll INF=1LL<<62;
constexpr int MOD=1e9+7;
int dx[]={1,-1,0,0},dy[]={0,0,-1,1};

//__builtin_popcount(S);
//#define int ll
//vector<vector<int>> data(3, vector<int>(4));
//vector.resize(a,vector<int>(b,-1));
//vector<vector<vector<要素の型>>> 変数名(要素数1, vector<vector<要素の型>>(要素数2, vector<要素の型>(要素数3, 初期値)));


template<typename T>
struct Dinic{
    struct edge{
        int to;
        T cap;
        int rev;
    };
    const T inf;
    const T zero;
    int sz;
    vector< vector<edge> > graph;
    vector<int> dist,iter;

    Dinic(const int n,const T inf,const T zero) : inf(inf),zero(zero),graph(n),sz(n){}

    void add_edge(const int from,const int to,const T cap){
        graph[from].emplace_back((edge){to,cap,(int)graph[to].size()});
        graph[to].emplace_back((edge){from,0,(int)graph[from].size()-1});
    }

    bool bfs(int s,int t){
        dist.assign(sz,-1);
        queue<int> que;
        dist[s]=0;
        que.push(s);
        while(!que.empty() && dist[t]==-1){
            int now=que.front();
            que.pop();
            for(auto &e:graph[now]){
                if(e.cap>0 && dist[e.to]==-1){
                    dist[e.to]=dist[now]+1;
                    que.push(e.to);
                }
            }
        }
        return dist[t]!=-1;
    }

    T dfs(int idx,const int t,T flow){
        if(idx==t) return flow;
        for(int &i=iter[idx];i<graph[idx].size();i++){
            edge &e=graph[idx][i];
            if(e.cap>0 && dist[idx]<dist[e.to]){
                T d=dfs(e.to,t,min(flow,e.cap));
                if(d>0){
                    e.cap-=d;
                    graph[e.to][e.rev].cap+=d;
                    return d;
                }
            }
        }
        return zero;
    }

    T max_flow(int s,const int t){
        T ret=0;
        while(bfs(s,t)){
            iter.assign(sz,0);
            T f=0;
            while((f=dfs(s,t,inf))>zero) ret+=f;
        }
        return ret;
    }
};

int h,w;
//flag:true IN
//flag:false out
int f(int i,int j,bool flag){
    if(flag) return 1+i*w+j;
    return 1+h*w+i*w+j;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr); 
    cout<<fixed<<setprecision(10);
    cin>>h>>w;

    Dinic<ll> flow(2*h*w+2,MAX,0LL);

    char c[110][110];
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            cin>>c[i][j];
            if(c[i][j]=='X'){
                flow.add_edge(0,f(i,j,true),MAX);
            }
        }
    }

    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(c[i][j]=='X') flow.add_edge(f(i,j,true),f(i,j,false),MAX);
            else flow.add_edge(f(i,j,true),f(i,j,false),1);
            for(int k=0;k<4;k++){
                int ni=i+dx[k],nj=j+dy[k];
                if(ni<0 || ni==h || nj<0 || nj==w){
                    flow.add_edge(f(i,j,false),2*h*w+1,MAX);
                    continue;
                }
                flow.add_edge(f(i,j,false),f(ni,nj,true),MAX);
            }
        }
    }
    ll x=flow.max_flow(0,2*h*w+1);
    if(x>=MAX) cout<<-1<<endl;
    else cout<<x<<endl;
}

Measured memory_bytes: 5308