#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

template <class Flow>
class MaxFlow {
    public:
    
    MaxFlow(int n, Flow eps = 0, Flow inf = 1e9) : size(n), graph(n), EPS(eps), INF(inf) {
        level = (int *)malloc(sizeof(int) * size);
        iter = (int *)malloc(sizeof(int) * size);
        que = (int *)malloc(sizeof(int) * size);
    }
    
    ~MaxFlow() {
        free(level);
        free(iter);
        free(que);
    }
    
    void add_edge(int from, int to, Flow cap) {
        graph[from].push_back(Edge(to, cap, graph[to].size()));
        graph[to].push_back(Edge(from, 0, graph[from].size() - 1));
    }
    
    void add_undirected_edge(int from, int to, Flow cap) {
        graph[from].push_back(Edge(to, cap, graph[to].size()));
        graph[to].push_back(Edge(from, cap, graph[from].size() - 1));
    }
    
    Flow max_flow(int source, int sink) {
        Flow flow = 0;
        
        while (1) {
            bfs(source, sink);
            
            if (level[sink] == -1) return flow;
            
            for (int i = 0; i < size; i++) iter[i] = 0;
            
            flow += dfs(source, sink, INF);
        }
    }
    
    private:
    
    int size;
    Flow EPS;
    Flow INF;
    int *level;
    int *iter;
    int *que;
    
    struct Edge {
        int to;
        Flow cap;
        int rev;
        Edge(int to, Flow cap, int rev) : to(to), cap(cap), rev(rev) {}
    };
    
    vector <vector <Edge> > graph;
    
    void bfs(int from, int to) {
        int qs = 0, qt = 0;
        
        for (int i = 0; i < size; i++) level[i] = -1;
        
        level[from] = 0;
        que[qt++] = from;
        
        while (qs < qt && level[to] == -1) {
            int now = que[qs++];
            
            for (int i = 0; i < graph[now].size(); i++) {
                int next = graph[now][i].to;
                
                if (graph[now][i].cap > EPS && level[next] == -1) {
                    level[next] = level[now] + 1;
                    que[qt++] = next;
                }
            }
        }
    }
    
    Flow dfs(int from, int to, Flow cap) {
        Flow flow = 0;
        
        if (from == to || cap <= EPS) return cap;
        
        for (int &i = iter[to]; i < graph[to].size(); i++) {
            int next = graph[to][i].to;
            Edge &edge = graph[next][graph[to][i].rev];
            Flow res;
            
            if (edge.cap <= EPS || level[next] >= level[to]) continue;
            
            res = dfs(from, next, min(cap - flow, edge.cap));
            
            if (res <= EPS) continue;
            
            edge.cap -= res;
            graph[to][i].cap += res;
            flow += res;
            
            if (abs(flow - cap) <= EPS) break;
        }
        
        return flow;
    }
};

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
char s[100][101];

int main() {
    int h, w, i, j, k;
    
    scanf("%d %d", &h, &w);
    
    for (i = 0; i < h; i++) scanf("%s", s[i]);
    
    MaxFlow <int> mf(h * w * 2 + 2);
    
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            if (s[i][j] == 'X') {
                for (k = 0; k < 4; k++) {
                    int x = i + dx[k];
                    int y = j + dy[k];
                    
                    if (x < 0 || x >= h || y < 0 || y >= w) {
                        puts("-1");
                        
                        return 0;
                    }
                }
            }
        }
    }
    
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            for (k = 0; k < 4; k++) {
                int x = i + dx[k];
                int y = j + dy[k];
                
                if (x < 0 || x >= h || y < 0 || y >= w) {
                    mf.add_edge((i * w + j) * 2 + 1, h * w * 2 + 1, 1000);
                } else {
                    mf.add_edge((i * w + j) * 2 + 1, (x * w + y) * 2, 1000);
                }
            }
            
            if (s[i][j] == 'X') {
                mf.add_edge(h * w * 2, (i * w + j) * 2 + 1, 1000);
            } else {
                mf.add_edge((i * w + j) * 2, (i * w + j) * 2 + 1, 1);
            }
        }
    }
    
    printf("%d\n", mf.max_flow(h * w * 2, h * w * 2 + 1));
    
    return 0;
}


Measured memory_bytes: 2816