#include <stdio.h>

#define min(a, b) ((a)>(b)?(b):(a))

const int inf = 1e5;
const int MAXN = 105;

const int sz = 2 * MAXN*MAXN;

template <class T> class vector {
	T* arr;
	int _cap, _size;
public:
	vector() { arr = new T[2]; _cap = 2; _size = 0; }
	T* begin() { return arr; }
	T* end() { return arr + _size; }
	T& operator[](int i) { return arr[i]; }
	int size() { return _size; }
	T back() {
		return arr[_size - 1];
	}
	void pop_back() { _size--; }
	void push_back(T newElement) {
		if (_size == _cap) {
			T* tmp = new T[_cap * 2];
			for (int i = 0; i < _size; i++)tmp[i] = arr[i];
			_cap *= 2;
			delete[] arr;
			arr = tmp;
		}
		arr[_size++] = newElement;
	}
	bool empty() {
		return !(_size);
	}
	void clear() { _cap = 2; _size = 0; delete[] arr; arr = new T[2]; }
	~vector() { delete[] arr; }
};

struct MaxFlow {
	struct Edge {
		int x;
		int inv;
		int resid;
		Edge() {}
		Edge(int v, int i, int r) : x(v), inv(i), resid(r) {}
	};
	int n;
	vector <Edge> g[sz];
	void init(int _n) {
		n = _n;
	}
	void add_edge(int s, int e, int cap) {
		Edge forward = Edge(e, g[e].size(), cap);
		Edge reverse = Edge(s, g[s].size(), 0);
		g[s].push_back(forward);
		g[e].push_back(reverse);
	}
	bool vis[sz];
	int Q[sz], fr, re, curf[sz], par[sz], paridx[sz];
	int bfs(int s, int e) {
		for (int i = 0; i < n; i++) {
			vis[i] = 0;
			curf[i] = 0;
			par[i] = paridx[i] = 0;
		}
		Q[fr = re = 0] = s; vis[s] = 1;
		curf[s] = inf;
		while (fr <= re) {
			int x = Q[fr++];
			for (int i = 0; i < g[x].size(); i++) {
				int y = g[x][i].x;
				int f = g[x][i].resid;
				if (f > 0 && !vis[y]) {
					vis[y] = 1;
					par[y] = x; paridx[y] = i;
					curf[y] = min(curf[x], f);
					Q[++re] = y;
				}
			}
		}
		if (!vis[e]) return 0;
		int flow = curf[e];
		int p = e;
		while (p != s) {
			int q = par[p], qi = paridx[p];
			int pi = g[q][qi].inv;
			g[q][qi].resid -= flow;
			g[p][pi].resid += flow;
			p = q;
		}
		return flow;
	}
	int solve(int s, int e) {
		int flow = 0, cur = 0;
		while (cur = bfs(s, e), cur > 0) {
			flow += cur;
		}
		return flow;
	}
};

int N, M;
char S[MAXN][MAXN];
int in[MAXN][MAXN], out[MAXN][MAXN];
int source, sink, v;

int px[4] = { 1,-1,0,0 };
int py[4] = { 0,0,1,-1 };

int main() {
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= N; i++) {
		scanf("%s", S[i] + 1);
	}
	source = 0;
	sink = N * M * 2 + 1;
	v = 0;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			in[i][j] = ++v;
			out[i][j] = ++v;
		}
	}
	MaxFlow f;
	f.init(2 * N*M + 2);
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			if (S[i][j] == 'X') {
				if (i == 1 || i == N || j == 1 || j == M) {
					f.add_edge(source, in[i][j], inf);
				}
				f.add_edge(in[i][j], out[i][j], inf);
				f.add_edge(out[i][j], sink, inf);
			}
			else {
				if (i == 1 || i == N || j == 1 || j == M) {
					f.add_edge(source, in[i][j], 1);
				}
				f.add_edge(in[i][j], out[i][j], 1);
				for (int k = 0; k < 4; k++) {
					int x = i + px[k];
					int y = j + py[k];
					if (1 <= x && x <= N && 1 <= y && y <= M) {
						f.add_edge(out[i][j], in[x][y], inf);
					}
				}
			}
		}
	}
	int flow = f.solve(source, sink);
	if (flow >= inf) puts("-1");
	else printf("%d\n", flow);
}

Measured memory_bytes: 2944