// Code by H~$~C
#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma GCC optimize("Ofast", "unroll-loops")
#pragma target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define rint register int
#define rep(i, n) for (rint i = 0; i < (n); ++i)
#define rep1(i, n) for (rint i = (1); i <= (n); ++i)
#define Rep(i, a, b) for (rint i = (a); i <= (b); ++i)
#define per(i, n) for (rint i = ((n) - 1); ~i; --i)
#define per1(i, n) for (rint i = (n); i; --i)
#define Per(i, a, b) for (rint i = (a); i >= (b); --i)
#define repit(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#define eprintf(...) (fprintf(stderr, __VA_ARGS__) & fflush(stderr))
#define fillset(a, val) memset(a, val, sizeof(a))
#define All(a) a.begin(), a.end()
#define SZ(a) ((int)a.size())
#define fi first
#define se second
#define pb push_back
#define y0 y19260817
#define y1 y19268107
#define j0 j19260817
#define j1 j19268107
#define x0 x19260817
#define x1 x19268107
using namespace std;
#ifndef LOCAL_JUDGE
#define Debug(...)
#else
template <typename T> inline void _debug(const char *names, T &&t) {
(cerr << names << " = " << t << endl).flush();}
template <typename T1, typename ...T>
inline void _debug(const char *names, T1 &&t1, T &&... t) {
const char *comma = strchr(names, ',');
(cerr.write(names, comma - names) << " = " << t1 << ", ").flush();
_debug(comma + 1, t ...);}
#define Debug(...) _debug(#__VA_ARGS__, __VA_ARGS__)
#endif
struct __STARTER_OF_PROGRAM__ { __STARTER_OF_PROGRAM__() {
#ifndef ONLINE_JUDGE
  cerr << "Code by H~$~C: \n" << flush;
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
  cout << fixed << setprecision(12);
} } __starter_of_program__;
#ifdef LOCAL_JUDGE
struct __ENDDER_OF_PROGRAM__ { ~__ENDDER_OF_PROGRAM__() {
  cerr << "\n\nTime elasped: " << clock() * 1000.0 / CLOCKS_PER_SEC << " ms\n" << flush;
} } __endder_of_program__;
#endif
using ll = long long; using ull = unsigned long long; using uint = unsigned int;
using ld = long double; using pii = pair<int, int>; using pll = pair<ll, ll>;
using pli = pair<ll, int>; using pil = pair<int, ll>;
template <typename T> using min_queue = priority_queue<T, vector <T>, greater <T> >;
template <typename T> using max_queue = priority_queue<T>;
mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());
static uniform_int_distribution<int> __disint__;
inline int randint(void) { return __disint__(gen); }
inline int randint(int l, int r) { return __disint__(gen) % (r - l + 1) + l; }
template <typename T> inline void reinit(T &t) { t.~T(); new (&t) T(); }
template <typename T> inline T chmax(T &x, T y) { return x = max(x, y); }
template <typename T> inline T chmin(T &x, T y) { return x = min(x, y); }
template <typename T> inline T chmax(T &x, initializer_list <T> i) { return x = max(x, max(i)); }
template <typename T> inline T chmin(T &x, initializer_list <T> i) { return x = min(x, min(i)); }
inline void read() { } inline void write() { }
template <typename T> inline void read(T &x) { cin >> x; }
template <typename T> inline void write(const T &x) { cout << x; }
template <typename T, typename U>
inline void write(const pair<T, U> &x) { write(x.first), cout.put(' '), write(x.second);}
template <typename T, typename U>
inline void read(pair<T, U> &x) { read(x.first), read(x.second);}
template <typename T, typename ...Ts> inline void read(T &x, Ts &...y) { read(x), read(y...); }
template <typename T, typename ...Ts> inline void write(const T &x, const Ts &...y) {
write(x), (sizeof...(y) && (cout.put(' '), 0)), write(y...); }
#define writeln(...) (write(__VA_ARGS__), cout.put('\n'), 0)
template <typename It> inline void _write(It a, It b) {
register char flag = 0; while (a != b) { flag && (cout.put(' '), 0); write(*a ++), flag = 1; } }
#define _writeln(...) (_write(__VA_ARGS__), cout.put('\n'), 0)
const int mod1 = 1000000007, mod2 = 998244353, mod3 = 1000000009;
const double EPS = 1e-9, PI = acos(-1.0), _E_ = exp(1.0);
const int inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;

const int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, 1, -1};

int n, m;
vector<string> grid;

signed main(int argc, const char *argv[]) {
  read(n, m);
  grid.resize(n + 1);
  grid[0] = string('.', m + 2);
  rep1(i, n) cin >> grid[i], grid[i] = '.' + grid[i] + '.';
  grid.push_back(string('.', m + 2));
  n += 2, m += 2;
  queue<pii> que;
  que.push(pii(0, 0));
  vector<pii> outer;
  vector<vector<bool> > vis(n, vector<bool>(m, 0));
  vis[0][0] = true;
  while (!que.empty()) {
    int x = que.front().fi;
    int y = que.front().se;
    que.pop();
    if (grid[x][y] == 'X') {
      outer.push_back(pii(x, y));
      continue;
    }
    rep(f, 8) {
      int nx = x + dx[f];
      int ny = y + dy[f];
      if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
      if (vis[nx][ny]) continue;
      vis[nx][ny] = true;
      que.push({nx, ny});
    }
  }
  vector<vector<int> > dist(n, vector<int>(m, inf));
  for (auto &x: outer) que.push(x), dist[x.fi][x.se] = 0;
  while (!que.empty()) {
    int x = que.front().fi;
    int y = que.front().se;
    que.pop();
    rep(f, 8) {
      int nx = x + dx[f];
      int ny = y + dy[f];
      if (grid[nx][ny] != 'X') continue;
      if (dist[nx][ny] != inf) continue;
      dist[nx][ny] = dist[x][y] + 1;
      que.push({nx, ny});
    }
  }
  vis.clear();
  vis = vector<vector<bool> >(n, vector<bool>(m, 0));
  int mx = inf;
  rep1(i, n - 2) rep1(j, m - 2)
    if (dist[i][j] != inf && !vis[i][j]) {
      int now = 0;
      que.push(pii(i, j));
      vis[i][j] = true;
      while (!que.empty()) {
        int x = que.front().fi;
        int y = que.front().se;
        que.pop();
        now = max(now, dist[x][y]);
        rep(f, 8) {
          int nx = x + dx[f];
          int ny = y + dy[f];
          if (dist[nx][ny] == inf) continue;
          if (vis[nx][ny]) continue;
          vis[nx][ny] = true;
          que.push(pii(nx, ny));
        }
      }
      mx = min(mx, now);
    }
  writeln(mx);
  rep1(i, n - 2) {
    rep1(j, m - 2)
      write(".X"[dist[i][j] >= mx && dist[i][j] != inf]);
    writeln();
  }
	return 0;
}


// Code by H~$~C
#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma GCC optimize("Ofast", "unroll-loops")
#pragma target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define rint register int
#define rep(i, n) for (rint i = 0; i < (n); ++i)
#define rep1(i, n) for (rint i = (1); i <= (n); ++i)
#define Rep(i, a, b) for (rint i = (a); i <= (b); ++i)
#define per(i, n) for (rint i = ((n) - 1); ~i; --i)
#define per1(i, n) for (rint i = (n); i; --i)
#define Per(i, a, b) for (rint i = (a); i >= (b); --i)
#define repit(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#define eprintf(...) (fprintf(stderr, __VA_ARGS__) & fflush(stderr))
#define fillset(a, val) memset(a, val, sizeof(a))
#define All(a) a.begin(), a.end()
#define SZ(a) ((int)a.size())
#define fi first
#define se second
#define pb push_back
#define y0 y19260817
#define y1 y19268107
#define j0 j19260817
#define j1 j19268107
#define x0 x19260817
#define x1 x19268107
using namespace std;
#ifndef LOCAL_JUDGE
#define Debug(...)
#else
template <typename T> inline void _debug(const char *names, T &&t) {
(cerr << names << " = " << t << endl).flush();}
template <typename T1, typename ...T>
inline void _debug(const char *names, T1 &&t1, T &&... t) {
const char *comma = strchr(names, ',');
(cerr.write(names, comma - names) << " = " << t1 << ", ").flush();
_debug(comma + 1, t ...);}
#define Debug(...) _debug(#__VA_ARGS__, __VA_ARGS__)
#endif
struct __STARTER_OF_PROGRAM__ { __STARTER_OF_PROGRAM__() {
#ifndef ONLINE_JUDGE
  cerr << "Code by H~$~C: \n" << flush;
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
  cout << fixed << setprecision(12);
} } __starter_of_program__;
#ifdef LOCAL_JUDGE
struct __ENDDER_OF_PROGRAM__ { ~__ENDDER_OF_PROGRAM__() {
  cerr << "\n\nTime elasped: " << clock() * 1000.0 / CLOCKS_PER_SEC << " ms\n" << flush;
} } __endder_of_program__;
#endif
using ll = long long; using ull = unsigned long long; using uint = unsigned int;
using ld = long double; using pii = pair<int, int>; using pll = pair<ll, ll>;
using pli = pair<ll, int>; using pil = pair<int, ll>;
template <typename T> using min_queue = priority_queue<T, vector <T>, greater <T> >;
template <typename T> using max_queue = priority_queue<T>;
mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());
static uniform_int_distribution<int> __disint__;
inline int randint(void) { return __disint__(gen); }
inline int randint(int l, int r) { return __disint__(gen) % (r - l + 1) + l; }
template <typename T> inline void reinit(T &t) { t.~T(); new (&t) T(); }
template <typename T> inline T chmax(T &x, T y) { return x = max(x, y); }
template <typename T> inline T chmin(T &x, T y) { return x = min(x, y); }
template <typename T> inline T chmax(T &x, initializer_list <T> i) { return x = max(x, max(i)); }
template <typename T> inline T chmin(T &x, initializer_list <T> i) { return x = min(x, min(i)); }
inline void read() { } inline void write() { }
template <typename T> inline void read(T &x) { cin >> x; }
template <typename T> inline void write(const T &x) { cout << x; }
template <typename T, typename U>
inline void write(const pair<T, U> &x) { write(x.first), cout.put(' '), write(x.second);}
template <typename T, typename U>
inline void read(pair<T, U> &x) { read(x.first), read(x.second);}
template <typename T, typename ...Ts> inline void read(T &x, Ts &...y) { read(x), read(y...); }
template <typename T, typename ...Ts> inline void write(const T &x, const Ts &...y) {
write(x), (sizeof...(y) && (cout.put(' '), 0)), write(y...); }
#define writeln(...) (write(__VA_ARGS__), cout.put('\n'), 0)
template <typename It> inline void _write(It a, It b) {
register char flag = 0; while (a != b) { flag && (cout.put(' '), 0); write(*a ++), flag = 1; } }
#define _writeln(...) (_write(__VA_ARGS__), cout.put('\n'), 0)
const int mod1 = 1000000007, mod2 = 998244353, mod3 = 1000000009;
const double EPS = 1e-9, PI = acos(-1.0), _E_ = exp(1.0);
const int inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;

const int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, 1, -1};

int n, m;
vector<string> grid;

signed main(int argc, const char *argv[]) {
  read(n, m);
  grid.resize(n + 1);
  grid[0] = string('.', m + 2);
  rep1(i, n) cin >> grid[i], grid[i] = '.' + grid[i] + '.';
  grid.push_back(string('.', m + 2));
  n += 2, m += 2;
  queue<pii> que;
  vector<pii> outer;
  vector<vector<bool> > vis(n, vector<bool>(m, 0));
  rep(i, n) rep(j, m) if (grid[i][j] == '.' && !vis[i][j]) {
    que.push(pii(i, j));
    vis[i][j] = true;
    while (!que.empty()) {
      int x = que.front().fi;
      int y = que.front().se;
      que.pop();
      if (grid[x][y] == 'X') {
        outer.push_back(pii(x, y));
        continue;
      }
      rep(f, 8) {
        int nx = x + dx[f];
        int ny = y + dy[f];
        if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
        if (vis[nx][ny]) continue;
        vis[nx][ny] = true;
        que.push({nx, ny});
      }
    }
  }
  vector<vector<int> > dist(n, vector<int>(m, inf));
  for (auto &x: outer) que.push(x), dist[x.fi][x.se] = 0;
  while (!que.empty()) {
    int x = que.front().fi;
    int y = que.front().se;
    que.pop();
    rep(f, 8) {
      int nx = x + dx[f];
      int ny = y + dy[f];
      if (grid[nx][ny] != 'X') continue;
      if (dist[nx][ny] != inf) continue;
      dist[nx][ny] = dist[x][y] + 1;
      que.push({nx, ny});
    }
  }
  vis.clear();
  vis = vector<vector<bool> >(n, vector<bool>(m, 0));
  int mx = inf;
  rep1(i, n - 2) rep1(j, m - 2)
    if (dist[i][j] != inf && !vis[i][j]) {
      int now = 0;
      que.push(pii(i, j));
      vis[i][j] = true;
      while (!que.empty()) {
        int x = que.front().fi;
        int y = que.front().se;
        que.pop();
        now = max(now, dist[x][y]);
        rep(f, 8) {
          int nx = x + dx[f];
          int ny = y + dy[f];
          if (dist[nx][ny] == inf) continue;
          if (vis[nx][ny]) continue;
          vis[nx][ny] = true;
          que.push(pii(nx, ny));
        }
      }
      mx = min(mx, now);
    }
  writeln(mx);
  rep1(i, n - 2) {
    rep1(j, m - 2)
      write(".X"[dist[i][j] >= mx && dist[i][j] != inf]);
    writeln();
  }
	return 0;
}


#include "bits/stdc++.h"
using namespace std;

#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define pb push_back
#define eb emplace_back
#define ins insert
#define ph push
#define f first
#define s second
#define cbr cerr << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ((ll)x.size())
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
#define btinpct(x) __builtin_popcountll((x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
inline long long rand(long long x, long long y) { return (rng() % (y+1-x)) + x; } //inclusivesss
string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?b:gcd(b%a,a); }

#define ll long long int
#define ld long double
#define FOR(ii, ss, ee) for(ll ii = (ss); ii <= (ll)(ee); ++ii)
#define DEC(ii, ss, ee) for(ll ii = (ss); ii >= (ll)(ee); --ii)
typedef pair <ll, ll> pi; typedef pair <ll, pi> spi; typedef pair <pi, pi> dpi;

#define LLINF ((long long) 1e18)//1234567890987654321
#define INF 1234567890ll
// #define cerr if(0)cout
#define MAXN (300006)
ll n, m; bool ga;
vector<vector<char>> grid;
vector<vector<int>> sum;
vector<vector<int>> cnt;
vector<vector<bool>> ans;
ll query(ll a,ll b,ll c,ll d) {
	return cnt[c][d]-cnt[a-1][d]-cnt[c][b-1]+cnt[a-1][b-1];
}
bool bstar(ll x) {
	FOR(i,0,n) FOR(j,0,m) sum[i][j]=0;
	FOR(i,x+1,n) {
		if(i + x > n) break;
		FOR(j,x+1,m) {
			if(j+x>m) break;
			if(query(i-x, j-x, i+x, j+x)) continue;
			sum[i-x][j-x]+=1;
			if(i+x+1 <= n) sum[i+x+1][j-x]+=-1;
			if(j+x+1 <= m) sum[i-x][j+x+1]+=-1;
			if(i+x+1 <= n && j+x+1 <= m) sum[i+x+1][j+x+1]+=1;
			if(ga) ans[i][j]=1;
		}
	}
	FOR(i,1,n) FOR(j,1,m) {
		sum[i][j] += sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1];
	}
	FOR(i,1,n) FOR(j,1,m) if((grid[i][j]=='.' && sum[i][j]) || (grid[i][j]=='X' && sum[i][j]==0)) return 0;
	return 1;
}
int main()
{
	FAST
	cin>>n>>m;
	grid.resize(n+1, vector<char>(m+1));
	sum.resize(n+1, vector<int> (m+1));
	cnt.resize(n+1, vector<int> (m+1));
	ans.resize(n+1, vector<bool>(m+1));
	FOR(i,1,n) FOR(j,1,m) cin>>grid[i][j], cnt[i][j]=(grid[i][j]=='.')+cnt[i-1][j]+cnt[i][j-1]-cnt[i-1][j-1];
	ll st=0, en=1e6 + 3, mid=0;
	while(en-st>1) {
		mid=(st+en)>>1;
		if(bstar(mid)) st=mid;
		else en=mid;
	}
	cout<<st<<'\n';
	ga=1, bstar(st);
	FOR(i,1,n) { FOR(j,1,m) cout<<(ans[i][j]?'X':'.'); cout<<"\n"; }
}


#include "bits/stdc++.h"
using namespace std;

#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define pb push_back
#define eb emplace_back
#define ins insert
#define ph push
#define f first
#define s second
#define cbr cerr << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)))
#define siz(x) ((ll)x.size())
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
#define btinpct(x) __builtin_popcountll((x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
inline long long rand(long long x, long long y) { return (rng() % (y+1-x)) + x; } //inclusivesss
string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?b:gcd(b%a,a); }

#define ll long long int
#define ld long double
#define FOR(ii, ss, ee) for(ll ii = (ss); ii <= (ll)(ee); ++ii)
#define DEC(ii, ss, ee) for(ll ii = (ss); ii >= (ll)(ee); --ii)
typedef pair <ll, ll> pi; typedef pair <ll, pi> spi; typedef pair <pi, pi> dpi;

#define LLINF ((long long) 1e18)//1234567890987654321
#define INF 1234567890ll
// #define cerr if(0)cout
#define MAXN (300006)
ll n, m; bool ga;
vector<vector<char>> grid;
vector<vector<int>> sum;
vector<vector<int>> cnt;
vector<vector<bool>> ans;
ll query(ll a,ll b,ll c,ll d) {
	return cnt[c][d]-cnt[a-1][d]-cnt[c][b-1]+cnt[a-1][b-1];
}
bool bstar(ll x) {
	FOR(i,0,n) FOR(j,0,m) sum[i][j]=0;
	FOR(i,x+1,n) {
		if(i + x > n) break;
		FOR(j,x+1,m) {
			if(j+x>m) break;
			if(query(i-x, j-x, i+x, j+x)) continue;
			sum[i-x][j-x]+=1;
			if(i+x+1 <= n) sum[i+x+1][j-x]+=-1;
			if(j+x+1 <= m) sum[i-x][j+x+1]+=-1;
			if(i+x+1 <= n && j+x+1 <= m) sum[i+x+1][j+x+1]+=1;
			if(ga) ans[i][j]=1;
		}
	}
	FOR(i,1,n) FOR(j,1,m) {
		sum[i][j] += sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1];
	}
	FOR(i,1,n) FOR(j,1,m) if((grid[i][j]=='.' && sum[i][j]) || (grid[i][j]=='X' && sum[i][j]==0)) return 0;
	return 1;
}
int main()
{
	FAST
	cin>>n>>m;
	grid.resize(n+1, vector<char>(m+1));
	sum.resize(n+1, vector<int> (m+1));
	cnt.resize(n+1, vector<int> (m+1));
	ans.resize(n+1, vector<bool>(m+1));
	FOR(i,1,n) FOR(j,1,m) cin>>grid[i][j], cnt[i][j]=(grid[i][j]=='.')+cnt[i-1][j]+cnt[i][j-1]-cnt[i-1][j-1];
	// ll st=0, en=1e6 + 3, mid=0;
	// while(en-st>1) {
		// mid=(st+en)>>1;
		// if(bstar(mid)) st=mid;
		// else en=mid;
	// }
	ll st = 0;
	vector<ll> v;
	FOR(i,1,1e6+1) v.pb(i);
	shuffle(all(v), rng);
	for(auto i:v) if(i>st) {
		if(bstar(i)) st=i;
	}
	cout<<st<<'\n';
	ga=1, bstar(st);
	FOR(i,1,n) { FOR(j,1,m) cout<<(ans[i][j]?'X':'.'); cout<<"\n"; }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

using P = pair<int,int>;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,M;
    cin >> N >> M;
    vec<string> S(N);
    for(auto& x:S) cin >> x;
    queue<P> Q;
    vvec<int> dist(N,vec<int>(M,-1));

    auto in = [&](int x,int y){
        return 0<=x && x<N && 0<=y && y<M;
    };
    auto id = [&](int x,int y){
        return x*M+y;
    };
    rep(i,N) rep(j,M) if(S[i][j]=='X'){
        int c = 0;
        for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){
            int nx = i+dx,ny = j+dy;
            if(!in(nx,ny)) continue;
            c += S[nx][ny]=='X';
        }
        if(c!=9){
            dist[i][j] = 0;
            Q.push({i,j});
        }
    }
    while(!Q.empty()){
        auto [x,y] = Q.front(); Q.pop();
        for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){
            int nx = x+dx,ny = y+dy;
            if(!in(nx,ny)) continue;
            if(dist[nx][ny]==-1){
                dist[nx][ny] = dist[x][y]+1;
                Q.push({nx,ny});
            }
        }
    }

    auto check = [&](int x){
        vvec<int> T(N+1,vec<int>(M+1));
        rep(i,N) rep(j,M) if(S[i][j]=='X' && dist[i][j]>=x){
            int a = i-x,b = j-x,c = i+x,d = j+x;
            if(!in(a,b)) return false;
            if(!in(c,d)) return false;
            T[a][b]++;
            T[a][d+1]--;
            T[c+1][b]--;
            T[c+1][d+1]++;
        }
        rep(i,N) rep(j,M) T[i+1][j] += T[i][j];
        rep(i,N) rep(j,M) T[i][j+1] += T[i][j];
        rep(i,N) rep(j,M){
            if(S[i][j]=='.' && T[i][j]>0) return false;
            if(S[i][j]=='X' && T[i][j]==0) return false;
        }
        return true;
    };

    int l = 0,r = min(N,M);
    while(l+1<r){
        int m = (l+r)/2;
        (check(m)? l:r) = m;
    }
    cout << l << "\n";
    rep(i,N) rep(j,M){
        if(S[i][j]=='.') cout << '.';
        else cout << (dist[i][j]>=l? 'X':'.');
        if(j==M-1) cout << "\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

using P = pair<int,int>;

class UnionFind{
private:
    vec<int> p,s;
    int cnt;
public:
    vec<int> v;
    UnionFind(){}
    UnionFind(int N):cnt(N),s(N,1),p(N),v(N){
        iota(p.begin(),p.end(),0);
    }
    int find(int x){
        if(p[x]==x) return x;
        else return p[x] = find(p[x]);
    }
    void unite(int x,int y){
        x = find(x); y = find(y);
        if(x==y) return;
        if(s[x]>s[y]) swap(x,y);
        p[x] = y;
        s[y] += s[x];
        chmax(v[y],v[x]);
        cnt--;
    }
    bool is_same_set(int x,int y) {return find(x)==find(y);}
    int size(int x) {return s[find(x)];}
    int compnents_number(){return cnt;}
    int val(int x){return v[find(x)];}
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,M;
    cin >> N >> M;
    vec<string> S(N);
    for(auto& x:S) cin >> x;
    queue<P> Q;
    vvec<int> dist(N,vec<int>(M,-1));

    auto in = [&](int x,int y){
        return 0<=x && x<N && 0<=y && y<M;
    };
    auto id = [&](int x,int y){
        return x*M+y;
    };
    UnionFind uf(N*M);
    rep(i,N) rep(j,M) if(S[i][j]=='X'){
        int c = 0;
        for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){
            int nx = i+dx,ny = j+dy;
            if(!in(nx,ny)) continue;
            c += S[nx][ny]=='X';
        }
        if(c!=9){
            dist[i][j] = 0;
            Q.push({i,j});
        }
    }
    while(!Q.empty()){
        auto [x,y] = Q.front(); Q.pop();
        for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){
            int nx = x+dx,ny = y+dy;
            if(!in(nx,ny)) continue;
            if(dist[nx][ny]==-1){
                dist[nx][ny] = dist[x][y]+1;
                uf.v[id(nx,ny)] = dist[nx][ny];
                Q.push({nx,ny});
            }
        }
    }
    rep(i,N) rep(j,M) if(S[i][j]=='X'){
        if(i+1<N && S[i+1][j]=='X') uf.unite(id(i,j),id(i+1,j));
        if(j+1<M && S[i][j+1]=='X') uf.unite(id(i,j),id(i,j+1));
    }
    int mi = 1e9;
    rep(i,N) rep(j,M) if(S[i][j]=='X'){
        chmin(mi,uf.val(id(i,j)));
    }
    cout << mi << "\n";
    rep(i,N) rep(j,M){
        if(S[i][j]=='.') cout << '.';
        else cout << (dist[i][j]>=mi? 'X':'.');
        if(j==M-1) cout << "\n";
    }
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define rep(i,n) for(int i=0;i<(n);i++)
#define drep(i,n) for(int i=(n)-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

using P = pair<int,int>;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,M;
    cin >> N >> M;
    vec<string> S(N);
    for(auto& x:S) cin >> x;
    queue<P> Q;
    vvec<int> dist(N,vec<int>(M,-1));

    auto in = [&](int x,int y){
        return 0<=x && x<N && 0<=y && y<M;
    };
    auto id = [&](int x,int y){
        return x*M+y;
    };
    rep(i,N) rep(j,M) if(S[i][j]=='X'){
        int c = 0;
        for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){
            int nx = i+dx,ny = j+dy;
            if(!in(nx,ny)) continue;
            c += S[nx][ny]=='X';
        }
        if(c!=9){
            dist[i][j] = 0;
            Q.push({i,j});
        }
    }
    while(!Q.empty()){
        auto [x,y] = Q.front(); Q.pop();
        for(int dx=-1;dx<=1;dx++) for(int dy=-1;dy<=1;dy++){
            int nx = x+dx,ny = y+dy;
            if(!in(nx,ny)) continue;
            if(dist[nx][ny]==-1){
                dist[nx][ny] = dist[x][y]+1;
                Q.push({nx,ny});
            }
        }
    }

    auto check = [&](int x){
        vvec<int> T(N+1,vec<int>(M+1));
        rep(i,N) rep(j,M) if(S[i][j]=='X' && dist[i][j]>=x){
            int a = i-x,b = j-x,c = i+x,d = j+x;
            if(!in(a,b)) return false;
            if(!in(c,d)) return false;
            T[a][b]++;
            T[a][d+1]--;
            T[c+1][b]--;
            T[c+1][d+1]++;
        }
        rep(i,N) rep(j,M) T[i+1][j] += T[i][j];
        rep(i,N) rep(j,M) T[i][j+1] += T[i][j];
        rep(i,N) rep(j,M){
            if(S[i][j]=='.' && T[i][j]>0) return false;
            if(S[i][j]=='X' && T[i][j]==0) return false;
        }
        return true;
    };

    int l = 0,r = min(N,M);
    while(l+1<r){
        int m = (l+r)/2;
        (check(m)? l:r) = m;
    }
    cerr << l << "\n";
    rep(i,N) rep(j,M){
        if(S[i][j]=='.') cout << '.';
        else cout << (dist[i][j]>=l? 'X':'.');
        if(j==M-1) cout << "\n";
    }
}


#pragma comment(linker, "/stack:200000000")
#define _CRT_SECURE_NO_DEPRECATE
//#pragma comment(linker, "/STACK:167772160000")
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <iomanip>
#include <queue>
#include <deque>
#include <set>
#include <unordered_set>
#include <stack>
#include <sstream>
#include <assert.h>
#include <unordered_map>
#include <bitset>
#include <functional>
#include <climits>
#include <cstring>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
//typedef uint64_t ull;
//typedef std::pair<long double,long double> pdd;
#define fori(N)          for(int i = 0; i<(N); i++)
#define forj(N)         for(int j = 0; j<(N); j++)
#define fork(N)         for(int k = 0; k<(N); k++)
#define forl(N)         for(int l = 0; l<(N); l++)
#define ford(N)         for(int d = 0; d<(N); d++)
#define fori1(N)          for(int i = 1; i<=(N); i++)
#define forj1(N)         for(int j = 1; j<=(N); j++)
#define fork1(N)         for(int k = 1; k<=(N); k++)
#define ford1(N)         for(int d = 1; d<=(N); d++)
#define PI (2*asin(1))
#define mp make_pair

void redirectIO() {
	ios::sync_with_stdio(false); cin.tie(0);
#if defined(_DEBUG) || defined(_RELEASE)
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
}
int n, m;
bool ** grid;
bool ** initialGrid;
int ** distances;

bool hasNeigh(int a, int b, bool ** gr, bool value) {
	fori(3)forj(3) {
		if (gr[a - 1 + i][b - 1 + j] == value)return true;
	}
	return false;
}

bool check(int a, int b, int dist) {
	int needDist = dist + 1;
	int minX = max(a-dist, 1);
	int maxX = min(a+dist, n);
	int minY = max(b - dist, 1);
	int maxY = min(b + dist, m);
	if (minX == a - dist) {
		for (int i = minY; i <= maxY; i++) {
			if (distances[minX][i] == needDist) {
				return true;
			}
		}
	}
	if (maxX == a + dist) {
		for (int i = minY; i <= maxY; i++) {
			if (distances[maxX][i] == needDist) {
				return true;
			}
		}
	}

	if (minY == b - dist) {
		for (int i = minX; i <= maxX; i++) {
			if (distances[i][minY] == needDist) {
				return true;
			}
		}
	}
	if (maxY == b + dist) {
		for (int i = minX; i <= maxX; i++) {
			if (distances[i][maxY] == needDist) {
				return true;
			}
		}
	}
	return false;
}

int main()
{
	redirectIO();
	/*cout << "1000 1000\n";
	fori(1000) {
		forj(1000)cout << "X";
		cout << endl;
	}
	return 0;*/

	cin >> n >> m;

	grid = new bool *[n + 2];
	initialGrid = new bool *[n + 2];
	distances = new int *[n + 2];

	fori(n + 2) {
		grid[i] = new bool[m + 2];
		initialGrid[i] = new bool[m + 2];
		distances[i] = new int[m + 2];
	}
	fori(n + 2)forj(m + 2)grid[i][j] = initialGrid[i][j] = distances[i][j] = 0;

	fori1(n)forj1(m) {
		char c; cin >> c;
		if (c == 'X')grid[i][j] = initialGrid[i][j] = true;
	}

	vector<pii>perimeter;
	fori1(n)forj1(m) {
		if (grid[i][j] && hasNeigh(i, j, grid, false))perimeter.push_back(mp(i, j));
	}
	vector<pii> initialP = perimeter;
	int answer = 1;
	while (!perimeter.empty()) {
		set<pii>nextPerimeter;
		for (pii x : perimeter) {
			grid[x.first][x.second] = false;
		}
		for (pii x : perimeter) {
			bool found = false;
			fori(3)forj(3) {
				int a = x.first - 1 + i;
				int b = x.second - 1 + j;

				if (grid[a][b]) {
					nextPerimeter.insert(mp(a, b));
					found = true;
				}
			}
			/*if (!found) {
				cout << answer << "\n";
				fori1(n) {
					forj1(m) {
						if (grid[i][j])cout << 'X';
						else cout << '.';
					}
					cout << "\n";
				}
				return 0;
			}*/
		}
		for (pii x : perimeter) {
			distances[x.first][x.second] = answer;
		}
		perimeter.clear();
		for (pii x : nextPerimeter) {
			perimeter.push_back(x);
		}
		answer++;
	}
	answer = 1010;
	for (pii x : initialP) {
		while (true) {
			if (check(x.first, x.second, answer))break;
			answer--;
		}
	}
	cout << answer << "\n";
	fori1(n) {
		forj1(m) {
			if (distances[i][j] > answer)cout << 'X';
			else cout << '.';
		}
		cout << "\n";

	}
	return 0;
}


#pragma comment(linker, "/stack:200000000")
#define _CRT_SECURE_NO_DEPRECATE
//#pragma comment(linker, "/STACK:167772160000")
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <iomanip>
#include <queue>
#include <deque>
#include <set>
#include <unordered_set>
#include <stack>
#include <sstream>
#include <assert.h>
#include <unordered_map>
#include <bitset>
#include <functional>
#include <climits>
#include <cstring>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
//typedef uint64_t ull;
//typedef std::pair<long double,long double> pdd;
#define fori(N)          for(int i = 0; i<(N); i++)
#define forj(N)         for(int j = 0; j<(N); j++)
#define fork(N)         for(int k = 0; k<(N); k++)
#define forl(N)         for(int l = 0; l<(N); l++)
#define ford(N)         for(int d = 0; d<(N); d++)
#define fori1(N)          for(int i = 1; i<=(N); i++)
#define forj1(N)         for(int j = 1; j<=(N); j++)
#define fork1(N)         for(int k = 1; k<=(N); k++)
#define ford1(N)         for(int d = 1; d<=(N); d++)
#define PI (2*asin(1))
#define mp make_pair

void redirectIO() {
	ios::sync_with_stdio(false); cin.tie(0);
#if defined(_DEBUG) || defined(_RELEASE)
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
}
int n, m;
bool ** grid;
bool ** nextGrid;
bool ** initialGrid;
int ** distances;

bool hasNeigh(int a, int b, bool ** gr, bool value) {
	fori(3)forj(3) {
		if (gr[a - 1 + i][b - 1 + j] == value)return true;
	}
	return false;
}

bool check(int a, int b, int dist) {
	int needDist = dist + 1;
	int minX = max(a-dist, 1);
	int maxX = min(a+dist, n);
	int minY = max(b - dist, 1);
	int maxY = min(b + dist, m);
	if (minX == a - dist) {
		for (int i = minY; i <= maxY; i++) {
			if (distances[minX][i] == needDist) {
				return true;
			}
		}
	}
	if (maxX == a + dist) {
		for (int i = minY; i <= maxY; i++) {
			if (distances[maxX][i] == needDist) {
				return true;
			}
		}
	}

	if (minY == b - dist) {
		for (int i = minX; i <= maxX; i++) {
			if (distances[i][minY] == needDist) {
				return true;
			}
		}
	}
	if (maxY == b + dist) {
		for (int i = minX; i <= maxX; i++) {
			if (distances[i][maxY] == needDist) {
				return true;
			}
		}
	}
	return false;
}

int main()
{
	redirectIO();
	cin >> n >> m;

	grid = new bool *[n + 2];
	initialGrid = new bool *[n + 2];
	nextGrid = new bool *[n + 2];
	distances = new int *[n + 2];

	fori(n + 2) {
		grid[i] = new bool[m + 2];
		initialGrid[i] = new bool[m + 2];
		nextGrid[i] = new bool[m + 2];
		distances[i] = new int[m + 2];
	}
	fori(n + 2)forj(m + 2)grid[i][j] = nextGrid[i][j] = initialGrid[i][j] = distances[i][j] = 0;

	fori1(n)forj1(m) {
		char c; cin >> c;
		if (c == 'X')grid[i][j] = nextGrid[i][j] = initialGrid[i][j] = true;
	}

	vector<pii>perimeter;
	fori1(n)forj1(m) {
		if (grid[i][j] && hasNeigh(i, j, grid, false))perimeter.push_back(mp(i, j));
	}
	vector<pii> initialP = perimeter;
	int answer = 1;
	while (!perimeter.empty()) {
		vector<pii>nextPerimeter;
		for (pii x : perimeter) {
			nextGrid[x.first][x.second] = false;
		}
		for (pii x : perimeter) {
			bool found = false;
			fori(3)forj(3) {
				int a = x.first - 1 + i;
				int b = x.second - 1 + j;

				if (nextGrid[a][b]) {
					nextPerimeter.push_back(mp(a, b));
					found = true;
				}
			}
			/*if (!found) {
				cout << answer << "\n";
				fori1(n) {
					forj1(m) {
						if (grid[i][j])cout << 'X';
						else cout << '.';
					}
					cout << "\n";
				}
				return 0;
			}*/
		}
		for (pii x : perimeter) {
			grid[x.first][x.second] = false;
			distances[x.first][x.second] = answer;
		}
		perimeter = std::move(nextPerimeter);
		answer++;
	}
	answer = 1010;
	for (pii x : initialP) {
		while (true) {
			if (check(x.first, x.second, answer))break;
			answer--;
		}
	}
	cout << answer << "\n";
	fori1(n) {
		forj1(m) {
			if (distances[i][j] > answer)cout << 'X';
			else cout << '.';
		}
		cout << "\n";

	}
	return 0;
}


#pragma comment(linker, "/stack:200000000")
#define _CRT_SECURE_NO_DEPRECATE
//#pragma comment(linker, "/STACK:167772160000")
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <iomanip>
#include <queue>
#include <deque>
#include <set>
#include <unordered_set>
#include <stack>
#include <sstream>
#include <assert.h>
#include <unordered_map>
#include <bitset>
#include <functional>
#include <climits>
#include <cstring>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
//typedef uint64_t ull;
//typedef std::pair<long double,long double> pdd;
#define fori(N)          for(int i = 0; i<(N); i++)
#define forj(N)         for(int j = 0; j<(N); j++)
#define fork(N)         for(int k = 0; k<(N); k++)
#define forl(N)         for(int l = 0; l<(N); l++)
#define ford(N)         for(int d = 0; d<(N); d++)
#define fori1(N)          for(int i = 1; i<=(N); i++)
#define forj1(N)         for(int j = 1; j<=(N); j++)
#define fork1(N)         for(int k = 1; k<=(N); k++)
#define ford1(N)         for(int d = 1; d<=(N); d++)
#define PI (2*asin(1))
#define mp make_pair

void redirectIO() {
	ios::sync_with_stdio(false); cin.tie(0);
#if defined(_DEBUG) || defined(_RELEASE)
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
}
int n, m;
bool ** grid;
bool ** initialGrid;
int ** distances;

bool hasNeigh(int a, int b, bool ** gr, bool value) {
	fori(3)forj(3) {
		if (gr[a - 1 + i][b - 1 + j] == value)return true;
	}
	return false;
}

bool check(int a, int b, int dist) {
	int needDist = dist + 1;
	int minX = max(a-dist, 1);
	int maxX = min(a+dist, n);
	int minY = max(b - dist, 1);
	int maxY = min(b + dist, m);
	if (minX == a - dist) {
		for (int i = minY; i <= maxY; i++) {
			if (distances[minX][i] == needDist) {
				return true;
			}
		}
	}
	if (maxX == a + dist) {
		for (int i = minY; i <= maxY; i++) {
			if (distances[maxX][i] == needDist) {
				return true;
			}
		}
	}

	if (minY == b - dist) {
		for (int i = minX; i <= maxX; i++) {
			if (distances[i][minY] == needDist) {
				return true;
			}
		}
	}
	if (maxY == b + dist) {
		for (int i = minX; i <= maxX; i++) {
			if (distances[i][maxY] == needDist) {
				return true;
			}
		}
	}
	return false;
}

int main()
{
	redirectIO();
	cin >> n >> m;

	grid = new bool *[n + 2];
	initialGrid = new bool *[n + 2];
	distances = new int *[n + 2];

	fori(n + 2) {
		grid[i] = new bool[m + 2];
		initialGrid[i] = new bool[m + 2];
		distances[i] = new int[m + 2];
	}
	fori(n + 2)forj(m + 2)grid[i][j] = initialGrid[i][j] = distances[i][j] = 0;

	fori1(n)forj1(m) {
		char c; cin >> c;
		if (c == 'X')grid[i][j] = initialGrid[i][j] = true;
	}

	vector<pii>perimeter;
	fori1(n)forj1(m) {
		if (grid[i][j] && hasNeigh(i, j, grid, false))perimeter.push_back(mp(i, j));
	}
	vector<pii> initialP = perimeter;
	int answer = 1;
	while (!perimeter.empty()) {
		vector<pii>nextPerimeter;
		for (pii x : perimeter) {
			grid[x.first][x.second] = false;
		}
		for (pii x : perimeter) {
			bool found = false;
			fori(3)forj(3) {
				int a = x.first - 1 + i;
				int b = x.second - 1 + j;

				if (grid[a][b]) {
					nextPerimeter.push_back(mp(a, b));
					found = true;
				}
			}
			/*if (!found) {
				cout << answer << "\n";
				fori1(n) {
					forj1(m) {
						if (grid[i][j])cout << 'X';
						else cout << '.';
					}
					cout << "\n";
				}
				return 0;
			}*/
		}
		for (pii x : perimeter) {
			distances[x.first][x.second] = answer;
		}
		perimeter = nextPerimeter;
		answer++;
	}
	answer = 1010;
	for (pii x : initialP) {
		while (true) {
			if (check(x.first, x.second, answer))break;
			answer--;
		}
	}
	cout << answer << "\n";
	fori1(n) {
		forj1(m) {
			if (distances[i][j] > answer)cout << 'X';
			else cout << '.';
		}
		cout << "\n";

	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const int BIG = (int)(1e9);

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

vector<vector<int>>* coucou;
inline int getSomme(int l1, int c1, int l2, int c2)
{
    auto &p = (*coucou);
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

vector<vector<int>> pp;

bool fonctionne(int tps, bool afficher)
{
    coucou = &pref;
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	genPref(grille, pp);
	coucou = &pp;

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0, lig-tps), colDeb = max(0, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.assign(nbLig, vector<int>(nbCol));
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);
	pp = pref;

	int lo = 0, ri = (nbLig+1)*(nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 1000000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

inline int getSomme(vector<vector<int>> &p, int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

bool fonctionne(int tps, bool afficher)
{
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(pref, ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	auto pp = pref; genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0, lig-tps), colDeb = max(0, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(pp, ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.resize(nbLig);
	form(i, nbLig) tab[i].resize(nbCol);
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);

	int lo = 0, ri = max(nbLig+1, nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define int long long
#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 1000000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

int getSomme(vector<vector<int>> &p, int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

bool fonctionne(int tps, bool afficher)
{
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(pref, ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	auto pp = pref; genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0LL, lig-tps), colDeb = max(0LL, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(pp, ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.assign(nbLig, vector<int>(nbCol));
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);

	int lo = 0, ri = (nbLig+1)*(nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const int BIG = (int)(1e9);

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

inline __attribute__((always_inline)) int getSomme(vector<vector<int>> &p, int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

vector<vector<int>> pp;

bool fonctionne(int tps, bool afficher)
{
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(pref, ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0, lig-tps), colDeb = max(0, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(pp, ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.assign(nbLig, vector<int>(nbCol));
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);
	pp = pref;

	int lo = 0, ri = (nbLig+1)*(nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const int BIG = (int)(1e9);

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

inline __attribute__((always_inline)) int getSomme(vector<vector<int>> &p, int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

vector<int> pp;

bool fonctionne(int tps, bool afficher)
{
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(pref, ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0, lig-tps), colDeb = max(0, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(pp, ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.assign(nbLig, vector<int>(nbCol));
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);
	pp = pref;

	int lo = 0, ri = (nbLig+1)*(nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 1000000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

vector<vector<int>> grille, pp;
bool fonctionne(int tps, bool afficher)
{
	form2(lig, tps, nbLig-tps) form2(col, tps, nbCol-tps) {
		int l1 = lig-tps, c1 = col-tps;
		int l2 = lig+tps, c2 = col+tps;
		int tot = pref[l2][c2];
		if (l1) tot -= pref[l1-1][c2];
		if (c1) tot -= pref[l2][c1-1];
		if (l1 && c1) tot += pref[l1-1][c1-1];
		if (tot == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int l1 = max(0, lig-tps), c1 = max(0, col-tps);
		int l2 = min(nbLig-1, lig+tps), c2 = min(nbCol-1, col+tps);
		int tot = pp[l2][c2];
		if (l1) tot -= pp[l1-1][c2];
		if (c1) tot -= pp[l2][c1-1];
		if (l1 && c1) tot += pp[l1-1][c1-1];
		if (tot == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.resize(nbLig);
	form(i, nbLig) tab[i].resize(nbCol);
	pref = tab;
	pp = tab;
	grille = tab;
	int lo = 0, ri = max(nbLig+1, nbCol+1);
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);

	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
using namespace std;

#define int long long
#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 1000000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

inline int getSomme(vector<vector<int>> &p, int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

bool fonctionne(int tps, bool afficher)
{
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(pref, ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	auto pp = pref; genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0LL, lig-tps), colDeb = max(0LL, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(pp, ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.resize(nbLig);
	form(i, nbLig) tab[i].resize(nbCol);
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);

	int lo = 0, ri = max(nbLig+1, nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 1000000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

vector<vector<int>> grille, pp;
bool fonctionne(int tps, bool afficher)
{
	form(lig, nbLig) form(col, nbCol) {
		grille[lig][col] = 0;
		int l1 = lig-tps, c1 = col-tps;
		int l2 = lig+tps, c2 = col+tps;
		if (l1 < 0 || c1 < 0 || l2 >= nbLig || c2 >= nbCol) continue;
		int tot = pref[l2][c2];
		if (l1) tot -= pref[l1-1][c2];
		if (c1) tot -= pref[l2][c1-1];
		if (l1 && c1) tot += pref[l1-1][c1-1];
		if (tot == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int l1 = max(0, lig-tps), c1 = max(0, col-tps);
		int l2 = min(nbLig-1, lig+tps), c2 = min(nbCol-1, col+tps);
		int tot = pp[l2][c2];
		if (l1) tot -= pp[l1-1][c2];
		if (c1) tot -= pp[l2][c1-1];
		if (l1 && c1) tot += pp[l1-1][c1-1];
		if (tot == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.resize(nbLig);
	form(i, nbLig) tab[i].resize(nbCol);
	pref = tab;
	pp = tab;
	grille = tab;
	int lo = 0, ri = max(nbLig+1, nbCol+1);
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);

	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const int BIG = (int)(1e9);

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

vector<vector<int>> p;

inline int getSomme(int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

vector<vector<int>> pp;

bool fonctionne(int tps, bool afficher)
{
    p = pref;
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	genPref(grille, pp);
	p = pp;

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0, lig-tps), colDeb = max(0, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.assign(nbLig, vector<int>(nbCol));
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);
	pp = pref;

	int lo = 0, ri = (nbLig+1)*(nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <bits/stdc++.h>
using namespace std;

#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const int BIG = (int)(1e9);

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

int nbLig, nbCol;
vector<vector<int>> tab;
vector<vector<int>> pref;

inline __attribute__((always_inline)) int getSomme(vector<vector<int>> &p, int l1, int c1, int l2, int c2)
{
	int tot = p[l2][c2];
	if (l1) tot -= p[l1-1][c2];
	if (c1) tot -= p[l2][c1-1];
	if (l1 && c1) tot += p[l1-1][c1-1];
	return tot;
}

void genPref(vector<vector<int>> &tt, vector<vector<int>> &pp)
{
	form(lig, nbLig) form(col, nbCol) {
		pp[lig][col] = tt[lig][col];
		if (lig) pp[lig][col] += pp[lig-1][col];
		if (col) pp[lig][col] += pp[lig][col-1];
		if (lig && col) pp[lig][col] -= pp[lig-1][col-1];
	}
}

bool fonctionne(int tps, bool afficher)
{
	auto grille = tab;
	form(lig, nbLig) form(col, nbCol) {
		int ligDeb = lig-tps, colDeb = col-tps;
		int ligFin = lig+tps, colFin = col+tps;
		bool b = true;
		if (ligDeb < 0 || colDeb < 0 || ligFin >= nbLig || colFin >= nbCol) b = false;
		if (b && getSomme(pref, ligDeb, colDeb, ligFin, colFin) == 0) grille[lig][col] = 1; // ARBRE
		else grille[lig][col] = 0;
	}

	auto pp = pref; genPref(grille, pp);

	form(lig, nbLig) form(col, nbCol) if (tab[lig][col] == 0) {
		int ligDeb = max(0, lig-tps), colDeb = max(0, col-tps);
		int ligFin = min(nbLig-1, lig+tps), colFin = min(nbCol-1, col+tps);
		if (getSomme(pp, ligDeb, colDeb, ligFin, colFin) == 0) return false;
	}

	if (afficher) {
		form(lig, nbLig) {
			form(col, nbCol) {
				if (grille[lig][col] == 1) cout << "X";
				else cout << ".";
			}
			cout << "\n";
		}
	}
	return true;
}
void solve()
{
	cin >> nbLig >> nbCol;
	tab.assign(nbLig, vector<int>(nbCol));
	pref = tab;
	form(lig, nbLig) form(col, nbCol) {
		char c; cin >> c;
		if (c == '.') tab[lig][col] = 1;
		else tab[lig][col] = 0;
	}

	genPref(tab, pref);

	int lo = 0, ri = (nbLig+1)*(nbCol+1);
	while (lo < ri) {
		int mid = (lo+ri+1)/2;
		if (fonctionne(mid, false)) lo = mid;
		else ri = mid-1;
	}
	cout << lo << "\n";
	fonctionne(lo, true);
}


#include <iostream>
#include <set>
#include <map>
#include <algorithm>
#include <deque>
#include <vector>

using namespace std;
typedef long long int ll;

bool test(int n, int m, int side, vector<vector<bool>> &mp, vector<vector<ll>> &pref_mp) {
    ll l_area = side * side;
    vector<vector<ll>> pref_mp2(n + 1, vector<ll>(m + 1, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= side && j >= side) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - side][j];
                res -= pref_mp[i][j - side];
                res += pref_mp[i - side][j - side];
                if (res == l_area) {
                    pref_mp2[i][j] = 1;
                }
            }
        }
    }
    for (int i = n; i >= 1; --i) {
        for (int j = m; j >= 1; --j) {
            if (i < n) {
                pref_mp2[i][j] += pref_mp2[i + 1][j];
            }
            if (j < m) {
                pref_mp2[i][j] += pref_mp2[i][j + 1];
            }
            if (i < n && j < m) {
                pref_mp2[i][j] -= pref_mp2[i + 1][j + 1];
            }
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            ll cnt = pref_mp2[i][j];
            int is = i + side, js = j + side;
            if (is <= n) {
                cnt -= pref_mp2[is][j];
            }
            if (js <= m) {
                cnt -= pref_mp2[i][js];
            }
            if (is <= n && js <= m) {
                cnt += pref_mp2[is][js];
            }
            if (mp[i][j] && cnt == 0) {
                return false;
            }
        }
    }
    return true;
}

int main() {
    // ifstream cin("biconv.in");
    // ofstream cout("biconv.out");
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<vector<bool>> mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        string s;
        cin >> s;
        for (int j = 1; j <= m; ++j) {
            if (s[j - 1] == 'X') {
                mp[i][j] = true;
            }
        }
    }
    vector<vector<ll>> pref_mp(n + 1, vector<ll>(m + 1, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            pref_mp[i][j] = mp[i][j];
            pref_mp[i][j] += pref_mp[i - 1][j];
            pref_mp[i][j] += pref_mp[i][j - 1];
            pref_mp[i][j] -= pref_mp[i - 1][j - 1];
        }
    }
    int l = 0, r = max(n, m);
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (test(n, m, mid, mp, pref_mp)) {
            l = mid;
        } else {
            r = mid;
        }
    }
    int ans = (l - 1) / 2;
    cout << ans << "\n";
    ll l_area = l * 1LL * l;
    vector<vector<bool>> final_mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= l && j >= l) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - l][j];
                res -= pref_mp[i][j - l];
                res += pref_mp[i - l][j - l];
                if (res == l_area) {
                    final_mp[i - ans][j - ans] = true;
                    if (l % 2 == 0) {
                        final_mp[i - ans - 1][j - ans - 1] = true;
                        final_mp[i - ans][j - ans - 1] = true;
                        final_mp[i - ans - 1][j - ans] = true;
                    }
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cout << (final_mp[i][j] ? 'X' : '.');
        }
        cout << "\n";
    }
}


#include <iostream>
#include <set>
#include <map>
#include <algorithm>
#include <deque>
#include <vector>

using namespace std;
typedef long long int ll;

bool test(int n, int m, int side, vector<vector<bool>> &mp, vector<vector<int>> &pref_mp) {
    int l_area = side * side;
    vector<vector<int>> pref_mp2(n + 2, vector<int>(m + 2, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= side && j >= side) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - side][j];
                res -= pref_mp[i][j - side];
                res += pref_mp[i - side][j - side];
                if (res == l_area) {
                    pref_mp2[i][j] = 1;
                }
            }
        }
    }
    for (int i = n; i >= 1; --i) {
        for (int j = m; j >= 1; --j) {
            pref_mp2[i][j] += pref_mp2[i + 1][j];
            pref_mp2[i][j] += pref_mp2[i][j + 1];
            pref_mp2[i][j] -= pref_mp2[i + 1][j + 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (mp[i][j]) {
                ll cnt = pref_mp2[i][j];
                int is = min(i + side, n + 1), js = min(j + side, m + 1);
                cnt -= pref_mp2[is][j];
                cnt -= pref_mp2[i][js];
                cnt += pref_mp2[is][js];
                if (cnt == 0) {
                    return false;
                }
            }
        }
    }
    return true;
}

int main() {
    // ifstream cin("biconv.in");
    // ofstream cout("biconv.out");
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<vector<bool>> mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        string s;
        cin >> s;
        for (int j = 1; j <= m; ++j) {
            if (s[j - 1] == 'X') {
                mp[i][j] = true;
            }
        }
    }
    vector<vector<int>> pref_mp(n + 1, vector<int>(m + 1, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            pref_mp[i][j] = mp[i][j];
            pref_mp[i][j] += pref_mp[i - 1][j];
            pref_mp[i][j] += pref_mp[i][j - 1];
            pref_mp[i][j] -= pref_mp[i - 1][j - 1];
        }
    }
    int l = 0, r = min(n, m) + 1;
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (test(n, m, mid, mp, pref_mp)) {
            l = mid;
        } else {
            r = mid;
        }
    }
    int ans = (l - 1) / 2;
    cout << ans << "\n";
    int l_area = l * l;
    vector<vector<bool>> final_mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= l && j >= l) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - l][j];
                res -= pref_mp[i][j - l];
                res += pref_mp[i - l][j - l];
                if (res == l_area) {
                    final_mp[i - ans][j - ans] = true;
                    if (l % 2 == 0) {
                        final_mp[i - ans - 1][j - ans - 1] = true;
                        final_mp[i - ans][j - ans - 1] = true;
                        final_mp[i - ans - 1][j - ans] = true;
                    }
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cout << (final_mp[i][j] ? 'X' : '.');
        }
        cout << "\n";
    }
}


#include <iostream>
#include <set>
#include <map>
#include <algorithm>
#include <deque>
#include <vector>

using namespace std;
typedef long long int ll;

bool test(int n, int m, int side, vector<vector<bool>> &mp, vector<vector<int>> &pref_mp) {
    int l_area = side * side;
    vector<vector<int>> pref_mp2(n + 2, vector<int>(m + 2, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= side && j >= side) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - side][j];
                res -= pref_mp[i][j - side];
                res += pref_mp[i - side][j - side];
                if (res == l_area) {
                    pref_mp2[i][j] = 1;
                }
            }
        }
    }
    for (int i = n; i >= 1; --i) {
        for (int j = m; j >= 1; --j) {
            pref_mp2[i][j] += pref_mp2[i + 1][j];
            pref_mp2[i][j] += pref_mp2[i][j + 1];
            pref_mp2[i][j] -= pref_mp2[i + 1][j + 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (mp[i][j]) {
                ll cnt = pref_mp2[i][j];
                int is = min(i + side, n + 1), js = min(j + side, m + 1);
                cnt -= pref_mp2[is][j];
                cnt -= pref_mp2[i][js];
                cnt += pref_mp2[is][js];
                if (cnt == 0) {
                    return false;
                }
            }
        }
    }
    return true;
}

int main() {
    // ifstream cin("biconv.in");
    // ofstream cout("biconv.out");
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<vector<bool>> mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        string s;
        cin >> s;
        for (int j = 1; j <= m; ++j) {
            if (s[j - 1] == 'X') {
                mp[i][j] = true;
            }
        }
    }
    vector<vector<int>> pref_mp(n + 1, vector<int>(m + 1, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            pref_mp[i][j] = mp[i][j];
            pref_mp[i][j] += pref_mp[i - 1][j];
            pref_mp[i][j] += pref_mp[i][j - 1];
            pref_mp[i][j] -= pref_mp[i - 1][j - 1];
        }
    }
    int l = 0, r = min(n, m);
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (test(n, m, mid, mp, pref_mp)) {
            l = mid;
        } else {
            r = mid;
        }
    }
    int ans = (l - 1) / 2;
    cout << ans << "\n";
    int l_area = l * l;
    vector<vector<bool>> final_mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= l && j >= l) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - l][j];
                res -= pref_mp[i][j - l];
                res += pref_mp[i - l][j - l];
                if (res == l_area) {
                    final_mp[i - ans][j - ans] = true;
                    if (l % 2 == 0) {
                        final_mp[i - ans - 1][j - ans - 1] = true;
                        final_mp[i - ans][j - ans - 1] = true;
                        final_mp[i - ans - 1][j - ans] = true;
                    }
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cout << (final_mp[i][j] ? 'X' : '.');
        }
        cout << "\n";
    }
}


#include <iostream>
#include <set>
#include <map>
#include <algorithm>
#include <deque>
#include <vector>

using namespace std;
typedef long long int ll;

bool test(int n, int m, int side, vector<vector<bool>> &mp, vector<vector<ll>> &pref_mp) {
    ll l_area = side * side;
    vector<vector<ll>> pref_mp2(n + 2, vector<ll>(m + 2, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= side && j >= side) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - side][j];
                res -= pref_mp[i][j - side];
                res += pref_mp[i - side][j - side];
                if (res == l_area) {
                    pref_mp2[i][j] = 1;
                }
            }
        }
    }
    for (int i = n; i >= 1; --i) {
        for (int j = m; j >= 1; --j) {
            pref_mp2[i][j] += pref_mp2[i + 1][j];
            pref_mp2[i][j] += pref_mp2[i][j + 1];
            pref_mp2[i][j] -= pref_mp2[i + 1][j + 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (mp[i][j]) {
                ll cnt = pref_mp2[i][j];
                int is = min(i + side, n + 1), js = min(j + side, m + 1);
                cnt -= pref_mp2[is][j];
                cnt -= pref_mp2[i][js];
                cnt += pref_mp2[is][js];
                if (cnt == 0) {
                    return false;
                }
            }
        }
    }
    return true;
}

int main() {
    // ifstream cin("biconv.in");
    // ofstream cout("biconv.out");
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<vector<bool>> mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        string s;
        cin >> s;
        for (int j = 1; j <= m; ++j) {
            if (s[j - 1] == 'X') {
                mp[i][j] = true;
            }
        }
    }
    vector<vector<ll>> pref_mp(n + 1, vector<ll>(m + 1, 0));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            pref_mp[i][j] = mp[i][j];
            pref_mp[i][j] += pref_mp[i - 1][j];
            pref_mp[i][j] += pref_mp[i][j - 1];
            pref_mp[i][j] -= pref_mp[i - 1][j - 1];
        }
    }
    int l = 0, r = max(n, m);
    while (r - l > 1) {
        int mid = (l + r) / 2;
        if (test(n, m, mid, mp, pref_mp)) {
            l = mid;
        } else {
            r = mid;
        }
    }
    int ans = (l - 1) / 2;
    cout << ans << "\n";
    ll l_area = l * 1LL * l;
    vector<vector<bool>> final_mp(n + 1, vector<bool>(m + 1, false));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i >= l && j >= l) {
                ll res = pref_mp[i][j];
                res -= pref_mp[i - l][j];
                res -= pref_mp[i][j - l];
                res += pref_mp[i - l][j - l];
                if (res == l_area) {
                    final_mp[i - ans][j - ans] = true;
                    if (l % 2 == 0) {
                        final_mp[i - ans - 1][j - ans - 1] = true;
                        final_mp[i - ans][j - ans - 1] = true;
                        final_mp[i - ans - 1][j - ans] = true;
                    }
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cout << (final_mp[i][j] ? 'X' : '.');
        }
        cout << "\n";
    }
}


#include <bits/stdc++.h>

#define int long long

#define pii pair<int, int>

#define x1 x1228
#define y1 y1228

#define left left228
#define right right228

#define pb push_back
#define eb emplace_back

#define mp make_pair

#define ff first
#define ss second

#define matr vector<vector<int> >

#define all(x) x.begin(), x.end()

using namespace std;
typedef long long ll;
typedef long double ld;

const int maxn = 1e6 + 7, mod = 998244353, MAXN = 1e6 + 7;
const double eps = 1e-9;
const ll inf = 1e18;
mt19937 rnd(time(0));
int n, m;
vector<char> a[maxn];
vector<int> pref[maxn];

int get(int xx, int yy, int xx1, int yy1) {
    return pref[xx1 + 1][yy1 + 1] - pref[xx1 + 1][yy] - pref[xx][yy1 + 1] + pref[xx][yy];
}

vector<int> dx = {0, 0, -1, 1, 1, 1, -1, -1};
vector<int> dy = {-1, 1, 0, 0, 1, -1, 1, -1};
int dist[maxn];

bool check(int xx) {
    for (int i = 0; i < maxn; ++i) dist[i] = inf;
    deque<pii> q;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                q.eb(i, j);
                dist[i * m + j] = 0;
            }
        }
    }
    while (q.size()) {
        pii t = q.front();
        q.pop_front();
        for (int i = 0; i < 8; ++i) {
            int x1 = t.ff + dx[i], y1 = t.ss + dy[i];
            if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && dist[x1 * m + y1] == inf && dist[t.ff * m + t.ss] + 1 <= xx) {
                dist[x1 * m + y1] = dist[t.ff * m + t.ss] + 1;
                q.eb(x1, y1);
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] == 'X' && dist[i * m + j] == inf) return false;
        }
    }
    return true;
}

vector<char> ans[maxn];
void ask(int xx) {
    for (int i = 0; i < n; ++i) {
        ans[i].resize(m, '.');
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                ans[i][j] = 'X';
            }
        }
    }
    cout << xx << '\n';
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << ans[i][j];
        }
        cout << '\n';
    }
}

void binn() {
    int l = 0;
    int m;
    int r = 2007;
    while (l + 1 < r) {
        m = (l + r) / 2;
        if (check(m)) {
            l = m;
        } else {
            r = m;
        }
    }
    ask(l);
}
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        a[i].resize(m + 1);
        pref[i].resize(m + 1);
        for (int j = 0; j < m; ++j) cin >> a[i][j];
    }
    pref[n].resize(m + 1);
    a[n].resize(m + 1);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            pref[i + 1][j + 1] = pref[i + 1][j] + pref[i][j + 1] - pref[i][j] + (a[i][j] == 'X');
        }
    }
    binn();
}

signed main() {
#ifdef LOCAL
    freopen("TASK.in", "r", stdin);
    freopen("TASK.out", "w", stdout);
#else

#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    int t = 1;
    for (int i = 0; i < t; ++i) {
        solve();
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

#define pii pair<int, int>

#define x1 x1228
#define y1 y1228

#define left left228
#define right right228

#define pb push_back
#define eb emplace_back

#define mp make_pair

#define ff first
#define ss second

#define matr vector<vector<int> >

#define all(x) x.begin(), x.end()

using namespace std;
typedef long long ll;
typedef long double ld;

const int maxn = 3e6 + 7, mod = 998244353, MAXN = 1e6 + 7;
const double eps = 1e-9;
const ll inf = 1e18;
mt19937 rnd(time(0));
int n, m;
vector<char> a[maxn];
vector<int> pref[maxn];

int get(int xx, int yy, int xx1, int yy1) {
    return pref[xx1 + 1][yy1 + 1] - pref[xx1 + 1][yy] - pref[xx][yy1 + 1] + pref[xx][yy];
}

vector<int> dx = {0, 0, -1, 1, 1, 1, -1, -1};
vector<int> dy = {-1, 1, 0, 0, 1, -1, 1, -1};
int dist[maxn];

bool check(int xx) {
    for (int i = 0; i < maxn; ++i) dist[i] = inf;
    deque<pii> q;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                q.eb(i, j);
                dist[i * n + j] = 0;
            }
        }
    }
    while (q.size()) {
        pii t = q.front();
        q.pop_front();
        for (int i = 0; i < 8; ++i) {
            int x1 = t.ff + dx[i], y1 = t.ss + dy[i];
            if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && dist[x1 * n + y1] == inf && dist[t.ff * n + t.ss] + 1 <= xx) {
                dist[x1 * n + y1] = dist[t.ff * n + t.ss] + 1;
                q.eb(x1, y1);
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] == 'X' && dist[i * n + j] == inf) return false;
        }
    }
    return true;
}

vector<char> ans[maxn];
void ask(int xx) {
    for (int i = 0; i < n; ++i) {
        ans[i].resize(m, '.');
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                ans[i][j] = 'X';
            }
        }
    }
    cout << xx << '\n';
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << ans[i][j];
        }
        cout << '\n';
    }
}

void binn() {
    int l = 0;
    int m;
    int r = 2007;
    while (l + 1 < r) {
        m = (l + r) / 2;
        if (check(m)) {
            l = m;
        } else {
            r = m;
        }
    }
    ask(l);
}
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        a[i].resize(m + 1);
        pref[i].resize(m + 1);
        for (int j = 0; j < m; ++j) cin >> a[i][j];
    }
    pref[n].resize(m + 1);
    a[n].resize(m + 1);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            pref[i + 1][j + 1] = pref[i + 1][j] + pref[i][j + 1] - pref[i][j] + (a[i][j] == 'X');
        }
    }
    binn();
}

signed main() {
#ifdef LOCAL
    freopen("TASK.in", "r", stdin);
    freopen("TASK.out", "w", stdout);
#else

#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    int t = 1;
    for (int i = 0; i < t; ++i) {
        solve();
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

#define pii pair<int, int>

#define x1 x1228
#define y1 y1228

#define left left228
#define right right228

#define pb push_back
#define eb emplace_back

#define mp make_pair

#define ff first
#define ss second

#define matr vector<vector<int> >

#define all(x) x.begin(), x.end()

using namespace std;
typedef long long ll;
typedef long double ld;

const int maxn = 1e6 + 7, mod = 998244353, MAXN = 1e6 + 7;
const double eps = 1e-9;
const ll inf = 1e18;
mt19937 rnd(time(0));
int n, m;
vector<char> a[maxn];
vector<int> pref[maxn];

int get(int xx, int yy, int xx1, int yy1) {
    return pref[xx1 + 1][yy1 + 1] - pref[xx1 + 1][yy] - pref[xx][yy1 + 1] + pref[xx][yy];
}

vector<int> dx = {0, 0, -1, 1, 1, 1, -1, -1};
vector<int> dy = {-1, 1, 0, 0, 1, -1, 1, -1};
int dist[maxn];

bool check(int xx) {
    for (int i = 0; i < maxn; ++i) dist[i] = inf;
    deque<pii> q;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                q.eb(i, j);
                dist[i * n + j] = 0;
            }
        }
    }
    while (q.size()) {
        pii t = q.front();
        q.pop_front();
        for (int i = 0; i < 8; ++i) {
            int x1 = t.ff + dx[i], y1 = t.ss + dy[i];
            if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && dist[x1 * n + y1] == inf && dist[t.ff * n + t.ss] + 1 <= xx) {
                dist[x1 * n + y1] = dist[t.ff * n + t.ss] + 1;
                q.eb(x1, y1);
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] == 'X' && dist[i * n + j] == inf) return false;
        }
    }
    return true;
}

vector<char> ans[maxn];
void ask(int xx) {
    for (int i = 0; i < n; ++i) {
        ans[i].resize(m, '.');
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                ans[i][j] = 'X';
            }
        }
    }
    cout << xx << '\n';
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << ans[i][j];
        }
        cout << '\n';
    }
}

void binn() {
    int l = 0;
    int m;
    int r = 2007;
    while (l + 1 < r) {
        m = (l + r) / 2;
        if (check(m)) {
            l = m;
        } else {
            r = m;
        }
    }
    ask(l);
}
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        a[i].resize(m + 1);
        pref[i].resize(m + 1);
        for (int j = 0; j < m; ++j) cin >> a[i][j];
    }
    pref[n].resize(m + 1);
    a[n].resize(m + 1);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            pref[i + 1][j + 1] = pref[i + 1][j] + pref[i][j + 1] - pref[i][j] + (a[i][j] == 'X');
        }
    }
    binn();
}

signed main() {
#ifdef LOCAL
    freopen("TASK.in", "r", stdin);
    freopen("TASK.out", "w", stdout);
#else

#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    int t = 1;
    for (int i = 0; i < t; ++i) {
        solve();
    }
    return 0;
}


#include <bits/stdc++.h>

#define int long long

#define pii pair<int, int>

#define x1 x1228
#define y1 y1228

#define left left228
#define right right228

#define pb push_back
#define eb emplace_back

#define mp make_pair

#define ff first
#define ss second

#define matr vector<vector<int> >

#define all(x) x.begin(), x.end()

using namespace std;
typedef long long ll;
typedef long double ld;

const int maxn = 2e6 + 7, mod = 998244353, MAXN = 1e6 + 7;
const double eps = 1e-9;
const ll inf = 1e18;
mt19937 rnd(time(0));
int n, m;
vector<char> a[maxn];
vector<int> pref[maxn];

int get(int xx, int yy, int xx1, int yy1) {
    return pref[xx1 + 1][yy1 + 1] - pref[xx1 + 1][yy] - pref[xx][yy1 + 1] + pref[xx][yy];
}

vector<int> dx = {0, 0, -1, 1, 1, 1, -1, -1};
vector<int> dy = {-1, 1, 0, 0, 1, -1, 1, -1};
int dist[maxn];

bool check(int xx) {
    for (int i = 0; i < maxn; ++i) dist[i] = inf;
    deque<pii> q;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                q.eb(i, j);
                dist[i * n + j] = 0;
            }
        }
    }
    while (q.size()) {
        pii t = q.front();
        q.pop_front();
        for (int i = 0; i < 8; ++i) {
            int x1 = t.ff + dx[i], y1 = t.ss + dy[i];
            if (x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && dist[x1 * n + y1] == inf && dist[t.ff * n + t.ss] + 1 <= xx) {
                dist[x1 * n + y1] = dist[t.ff * n + t.ss] + 1;
                q.eb(x1, y1);
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (a[i][j] == 'X' && dist[i * n + j] == inf) return false;
        }
    }
    return true;
}

vector<char> ans[maxn];
void ask(int xx) {
    for (int i = 0; i < n; ++i) {
        ans[i].resize(m, '.');
        for (int j = 0; j < m; ++j) {
            if (a[i][j] != 'X') continue;
            int lx = i - xx;
            int ly = j - xx;
            int rx = i + xx;
            int ry = j + xx;
            if (!(lx >= 0 && lx < n && rx >= 0 && rx < n && ly >= 0 && ly < m && ry >= 0 && ry < m)) continue;
            if (get(lx, ly, rx, ry) == (xx * 2 + 1) * (xx * 2 + 1)) {
                ans[i][j] = 'X';
            }
        }
    }
    cout << xx << '\n';
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << ans[i][j];
        }
        cout << '\n';
    }
}

void binn() {
    int l = 0;
    int m;
    int r = 2007;
    while (l + 1 < r) {
        m = (l + r) / 2;
        if (check(m)) {
            l = m;
        } else {
            r = m;
        }
    }
    ask(l);
}
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        a[i].resize(m + 1);
        pref[i].resize(m + 1);
        for (int j = 0; j < m; ++j) cin >> a[i][j];
    }
    pref[n].resize(m + 1);
    a[n].resize(m + 1);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            pref[i + 1][j + 1] = pref[i + 1][j] + pref[i][j + 1] - pref[i][j] + (a[i][j] == 'X');
        }
    }
    binn();
}

signed main() {
#ifdef LOCAL
    freopen("TASK.in", "r", stdin);
    freopen("TASK.out", "w", stdout);
#else

#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    int t = 1;
    for (int i = 0; i < t; ++i) {
        solve();
    }
    return 0;
}


    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    char str[2000000];
    vector<vector<char> > s;
    vector<vector<char> > d;
    vector<vector<int> > dist;
    vector<vector<int> > dist2;
    vector<int> rd;
    vector<char> r;
    vector<pair<int,int> > q;
    char c;
    void bfs() {
        q.clear();
        dist.clear();
        for(int i=0;i<n;i++) {
            rd.clear();
            for(int j=0;j<m;j++) {
                if(s[i][j]=='.') {
                    rd.push_back(0);
                    q.push_back({i,j});
                }
                else rd.push_back(1e9);
            }
            dist.push_back(rd);
        }
        int ind=0;
        while(ind<q.size()) {
            int x=q[ind].first;
            int y=q[ind].second;
            if(x>0 && dist[x-1][y]>dist[x][y]+1) {
                dist[x-1][y]=dist[x][y]+1;
                q.push_back({x-1,y});
            }
            if(x<n-1 && dist[x+1][y]>dist[x][y]+1) {
                dist[x+1][y]=dist[x][y]+1;
                q.push_back({x+1,y});
            }
            if(y>0 && dist[x][y-1]>dist[x][y]+1) {
                dist[x][y-1]=dist[x][y]+1;
                q.push_back({x,y-1});
            }
            if(y<m-1 && dist[x][y+1]>dist[x][y]+1) {
                dist[x][y+1]=dist[x][y]+1;
                q.push_back({x,y+1});
            }
            if(x>0 && y>0 && dist[x-1][y-1]>dist[x][y]+1) {
                dist[x-1][y-1]=dist[x][y]+1;
                q.push_back({x-1,y-1});
            }
            if(x<n-1 && y<m-1 && dist[x+1][y+1]>dist[x][y]+1) {
                dist[x+1][y+1]=dist[x][y]+1;
                q.push_back({x+1,y+1});
            }
            if(y>0 && x<n-1 && dist[x+1][y-1]>dist[x][y]+1) {
                dist[x+1][y-1]=dist[x][y]+1;
                q.push_back({x+1,y-1});
            }
            if(y<m-1 && x>0 && dist[x-1][y+1]>dist[x][y]+1) {
                dist[x-1][y+1]=dist[x][y]+1;
                q.push_back({x-1,y+1});
            }
            ind++;
        }
    }
    void find_trees(int t) {
        d.clear();
        for(int i=0;i<n;i++) {
            r.clear();
            for(int j=0;j<m;j++) {
                if(s[i][j]=='.') r.push_back('.');
                else {
                    if(dist[i][j]>t) r.push_back('X');
                    else r.push_back('.');
                }
            }
            d.push_back(r);
        }
    }
    bool check_fire(int t) {
        q.clear();
        dist2.clear();
        for(int i=0;i<n;i++) {
            rd.clear();
            for(int j=0;j<m;j++) {
                if(d[i][j]=='X') {
                    rd.push_back(0);
                    q.push_back({i,j});
                }
                else rd.push_back(1e9);
            }
            dist2.push_back(rd);
        }
        int ind=0;
        if(q.size()==0) return false;
        while(ind<q.size()) {
            int x=q[ind].first;
            int y=q[ind].second;
            if(x>0 && dist2[x-1][y]>dist2[x][y]+1) {
                dist2[x-1][y]=dist2[x][y]+1;
                if(s[x-1][y]=='.' && dist2[x-1][y]<=t) return false;
                if(s[x-1][y]=='X' && dist2[x-1][y]>t) return false;
                q.push_back({x-1,y});
            }
            if(x<n-1 && dist2[x+1][y]>dist2[x][y]+1) {
                dist2[x+1][y]=dist2[x][y]+1;
                if(s[x+1][y]=='.' && dist2[x+1][y]<=t) return false;
                if(s[x+1][y]=='X' && dist2[x+1][y]>t) return false;
                q.push_back({x+1,y});
            }
            if(y>0 && dist2[x][y-1]>dist2[x][y]+1) {
                dist2[x][y-1]=dist2[x][y]+1;
                if(s[x][y-1]=='.' && dist2[x][y-1]<=t) return false;
                if(s[x][y-1]=='X' && dist2[x][y-1]>t) return false;
                q.push_back({x,y-1});
            }
            if(y<m-1 && dist2[x][y+1]>dist2[x][y]+1) {
                dist2[x][y+1]=dist2[x][y]+1;
                if(s[x][y+1]=='.' && dist2[x][y+1]<=t) return false;
                if(s[x][y+1]=='X' && dist2[x][y+1]>t) return false;
                q.push_back({x,y+1});
            }
            if(x>0 && y>0 && dist2[x-1][y-1]>dist2[x][y]+1) {
                dist2[x-1][y-1]=dist2[x][y]+1;
                if(s[x-1][y-1]=='.' && dist2[x-1][y-1]<=t) return false;
                if(s[x-1][y-1]=='X' && dist2[x-1][y-1]>t) return false;
                q.push_back({x-1,y-1});
            }
            if(x<n-1 && y<m-1 && dist2[x+1][y+1]>dist2[x][y]+1) {
                dist2[x+1][y+1]=dist2[x][y]+1;
                if(s[x+1][y+1]=='.' && dist2[x+1][y+1]<=t) return false;
                if(s[x+1][y+1]=='X' && dist2[x+1][y+1]>t) return false;
                q.push_back({x+1,y+1});
            }
            if(y>0 && x<n-1 && dist2[x+1][y-1]>dist2[x][y]+1) {
                dist2[x+1][y-1]=dist2[x][y]+1;
                if(s[x+1][y-1]=='.' && dist2[x+1][y-1]<=t) return false;
                if(s[x+1][y-1]=='X' && dist2[x+1][y-1]>t) return false;
                q.push_back({x+1,y-1});
            }
            if(y<m-1 && x>0 && dist2[x-1][y+1]>dist2[x][y]+1) {
                dist2[x-1][y+1]=dist2[x][y]+1;
                if(s[x-1][y+1]=='.' && dist2[x-1][y+1]<=t) return false;
                if(s[x-1][y+1]=='X' && dist2[x-1][y+1]>t) return false;
                q.push_back({x-1,y+1});
            }
            ind++;
        }
        return true;
    }
    bool pos(int t) {
        find_trees(t);
        return check_fire(t);
    }
    int main() {
        scanf("%d %d",&n,&m);
        r.clear();
        for(int i=0;i<m+2;i++) r.push_back('.');
        s.push_back(r);
        for(int i=0;i<n;i++) {
            r.clear();
            r.push_back('.');
            scanf("%s",str);
            for(int j=0;j<m;j++) {
                r.push_back(str[j]);
            }
            r.push_back('.');
            s.push_back(r);
        }
        r.clear();
        for(int i=0;i<m+2;i++) r.push_back('.');
        s.push_back(r);
        n+=2;
        m+=2;
        int l=0;
        int r=(min(n,m)+1)/2;
        bfs();
        while(l<r) {
            int mid=(l+r+1)>>1;
            if(pos(mid)) l=mid;
            else r=mid-1;
        }
        printf("%d\n",l);
        find_trees(l);
        for(int i=1;i<n-1;i++) {
            for(int j=1;j<m-1;j++) printf("%c",d[i][j]);
            printf("\n");
        }
        return 0;
    }