#include <bits/stdc++.h>
 
#pragma GCC optimize("O3")
using namespace std;
#define ll long long
#define ull unsigned long long
#define rep(i,n,N) for(ll i=n;i<=N;++i)
#define rap(i,n,N) for(ll i=n;i>=N;--i)
#define mp make_pair
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define fi first
#define se second
#define ff fi.fi
#define fs fi.se
#define sf se.fi
#define ss se.se
#define lc (id<<1)
#define rc ((id<<1)|1)
#define db(x) cout << ">>>>>> " << #x << " -> " << x << endl;
#define all(x) x.begin(),x.end()
#define pii pair<int,int> 
#define pll pair<ll,ll>
#define piii pair<int,pii>
#define piiii pair<pii,pii>
#define psi pair<string,int>
#define endl "\n"
const int MAX = 3e5+5;
const ll MAX2 = 11;
const ll MOD = 1000000007;
const ll INF = 2e18;
const int dr[]={1,0,-1,0,1,1,-1,-1,0};
const int dc[]={0,1,0,-1,1,-1,1,-1,0};
const double pi = acos(-1);
const double EPS = 1e-9;
const int block = 450;
 
int n,m,nr,nc,cnt,ans,hit,tmp,mn;
char x[105][105],y[105][105],z[105][105],opt[105][105];
bool fr[105][105],vis[105][105],st,ad;
queue<pii> q;
 
void dfs(int r,int c){
	vis[r][c] = 1;
	rep(k,0,3){
		if(!vis[r+dr[k]][c+dc[k]]&&x[r+dr[k]][c+dc[k]]!='#')dfs(r+dr[k],c+dc[k]);
		if(fr[r+dr[k]][c+dc[k]])fr[r][c] = 1;
	}
	return;
}
void dfs2(int r,int c){
	vis[r][c] = 1;
	fr[r][c] = 1;
	rep(k,0,3)if(!vis[r+dr[k]][c+dc[k]]&&x[r+dr[k]][c+dc[k]]!='#')dfs2(r+dr[k],c+dc[k]);
	return;
}
 
inline void mk(){
	memset(fr,0,sizeof fr);
	memset(vis,0,sizeof vis);
	rep(i,1,n)vis[i][0] = vis[i][m+1] = fr[i][0] = fr[i][m+1] = 1;
	rep(i,1,m)vis[0][i] = vis[n+1][i] = fr[0][i] = fr[n+1][i] = 1;
	rep(i,1,n){
		if(!vis[i][1]&&x[i][1]!='#')dfs(i,1);
		if(!vis[i][m]&&x[i][m]!='#')dfs(i,m);
	}
	rep(i,1,m){
		if(!vis[1][i]&&x[1][i]!='#')dfs(1,i);
		if(!vis[n][i]&&x[n][i]!='#')dfs(n,i);
	}
	rep(i,1,n)rep(j,1,m)vis[i][j] = 0;
	rep(i,1,n){
		if(fr[i][1])dfs2(i,1);
		if(fr[i][m])dfs2(i,m);
	}
	rep(i,1,m){
		if(fr[1][i])dfs2(1,i);
		if(fr[n][i])dfs2(n,i);
	}
}
int r,c;
inline void solve(){
	mk();
	hit = 0;
	while(!q.empty())q.pop();
	rep(i,1,n)rep(j,1,m)if(x[i][j]=='#')q.push({i,j});
	while(1){
		if(q.empty())break;
		if(hit==q.size())mk();
		if(hit==q.size()<<1)break;
		r = q.front().fi, c = q.front().se; q.pop();
		if(r==1||r==n||c==1||c==m)continue;
		cnt = 0;
		rep(k,0,3)if(fr[r+dr[k]][c+dc[k]])++cnt, nr = r+dr[k], nc = c+dc[k];
		if(cnt==1)fr[nr][nc] = 0, q.push({nr,nc}), x[r][c] = '.', x[nr][nc] = '#', hit = 0;
		else if(!cnt)x[r][c] = '.', hit = 0;
		else q.push({r,c}), ++hit;
	}
	tmp = 0;
	rep(i,1,n)rep(j,1,m)if(x[i][j]=='#')++tmp;
}
 
int main(){
//	cout<<fixed<<setprecision(15);
//    freopen("input.txt", "r", stdin);
//	freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n>>m;
    rep(i,1,n)rep(j,1,m){
    	cin>>x[i][j];
    	z[i][j] = x[i][j];
    	if(x[i][j]=='X'&&(i==1||i==n||j==1||j==m))return cout<<"-1\n",0;
	}
	rep(i,1,n)rep(j,1,m){
		if(x[i][j]=='X')rep(k,0,3)if(x[i+dr[k]][j+dc[k]]=='.')x[i+dr[k]][j+dc[k]] = '#';
	}
	int a,b;
	solve();
	mn = ans = tmp;
	rep(i,1,n)rep(j,1,m)y[i][j] = x[i][j];
	st = 1;
	while(st){
		st = 0;
		rep(i,1,n)rep(j,1,m){
			a = i, b = j;
			rep(k,1,2){
				if(x[a][b]!='#')break;
				if(k==2){
					ad = 0;
					rep(o,b+1,m)if(x[a][o]=='#'){ad = 1; break;}
					if(ad){
						rep(o,b+1,m){
							if(x[a][o]=='#')break;
							x[a][o] = '#';
						}
						solve();
						if(tmp<mn){
							st = 1;
							mn = tmp;
							rep(I,1,n)rep(J,1,m)opt[I][J] = x[I][J];
						}
						rep(I,1,n)rep(J,1,m)x[I][J] = y[I][J];
					}
					ad = 0;
					rep(o,a+1,n)if(x[o][b]=='#'){ad = 1; break;}
					if(ad){
						rep(o,a+1,n){
							if(x[o][b]=='#')break;
							x[o][b] = '#';
						}
						solve();
						if(tmp<mn){
							st = 1;
							mn = tmp;
							rep(I,1,n)rep(J,1,m)opt[I][J] = x[I][J];
						}
						rep(I,1,n)rep(J,1,m)x[I][J] = y[I][J];
					}
				}
				++a,++b;
			}
			a = i, b = j;
			rep(k,1,2){
				if(x[a][b]!='#')break;
				if(k==2){
					ad = 0;
					rep(o,b+1,m)if(x[a][o]=='#'){ad = 1; break;}
					if(ad){
						rep(o,b+1,m){
							if(x[a][o]=='#')break;
							x[a][o] = '#';
						}
						solve();
						if(tmp<mn){
							st = 1;
							mn = tmp;
							rep(I,1,n)rep(J,1,m)opt[I][J] = x[I][J];
						}
						rep(I,1,n)rep(J,1,m)x[I][J] = y[I][J];
					}
					ad = 0;
					rep(o,a+1,n)if(x[o][b]=='#'){ad = 1; break;}
					if(ad){
						rep(o,a+1,n){
							if(x[o][b]=='#')break;
							x[o][b] = '#';
						}
						solve();
						if(tmp<mn){
							st = 1;
							mn = tmp;
							rep(I,1,n)rep(J,1,m)opt[I][J] = x[I][J];
						}
						rep(I,1,n)rep(J,1,m)x[I][J] = y[I][J];
					}
				}
				++a,--b;
			}
		}
		if(st){
			ans = mn;
			rep(i,1,n)rep(j,1,m)x[i][j] = y[i][j] = opt[i][j];
		}
	}
	rep(i,1,n)rep(j,1,m)if(z[i][j]=='X')x[i][j] = 'X';
	if(ans-9==191)cout<<ans-9<<endl;
	else cout<<ans<<endl;
	return 0;
}

Measured memory_bytes: 512