#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
#define el '\n'
int dp[2][8192];
short prv[12][40][8192];
char choice[12][40][8192];
void run_case(int tc) {
int R, C;
cin >> R >> C;
string dummy;
getline(cin, dummy);
vector<string> g(R);
for(int i = 0; i < R; ++i) {
getline(cin, g[i]);
while((int)g[i].size() < C) {
g[i].push_back(' ');
}
}
int N = R / 2;
int M = C / 2;
for(auto & i : dp)
for(int & m : i)
m = 1e9;
dp[0][0] = 0;
for (int c = 0; c < M; ++c) { // column by column
for (int r = 0; r < N; ++r) { // dp[c][r][mask] is min cost if we have last mask boundary state
// we must pass by 'mask' to go from processed rooms to unprocessed rooms
// bit=1 : edge used
int idx = c * N + r;
int cur = idx % 2;
int nxt = (idx + 1) % 2;
for(int m = 0; m < (1 << (N + 1)); ++m) {
dp[nxt][m] = 1e9;
}
for (int mask = 0; mask < (1 << (N + 1)); ++mask) {
if (dp[cur][mask] >= 1e9) continue;
int up = (mask >> r) & 1; // got into (r, c) from above
int le = (mask >> (r + 1)) & 1; // got into (r, c) from left
for (int down = 0; down <= 1; ++down) { // exit (r, c) from below
if (down && (r == N - 1 || g[2 * r + 2][2 * c + 1] != ' ')) continue;
for (int ri = 0; ri <= 1; ++ri) { // exit (r, c) from right
if (ri && (c == M - 1 || g[2 * r + 1][2 * c + 2] != ' ')) continue; // must be available
int deg = up + le + down + ri;
bool is_X = (g[2 * r + 1][2 * c + 1] == 'X');
if (is_X && deg != 1) continue;
if (!is_X && deg != 0 && deg != 2) continue;
int new_mask = mask;
new_mask &= ~(1 << r); // remove edge in from above
new_mask &= ~(1 << (r + 1)); // remove edge in from left
new_mask |= (ri << r); // edge right from (r, c)
new_mask |= (down << (r + 1)); // edge down from (r, c), will be discarded if last row
int nr = r + 1;
int nc = c;
int nmsk = new_mask;
if (nr == N) {
nr = 0;
nc = c + 1;
nmsk <<= 1; // bit0 = 0 cuz no going down into (nr, nc), and bit1 is going right, but bitmax not needed now cuz no down from last row
}
if (nc == M && nmsk != 0) continue; // state not needed
int cost = dp[cur][mask] + down + ri; // down and right edges out of (r, c)
if (cost < dp[nxt][nmsk]) {
dp[nxt][nmsk] = cost;
// edges out of the cell we just processed
choice[nr][nc][nmsk] = (char)((down << 1) | ri);
prv[nr][nc][nmsk] = (short)mask;
}
}
}
}
}
}
cout << dp[(M * N) % 2][0] * 2 << "\n";
int cr = 0, cc = M, cmsk = 0;
while (cr != 0 || cc != 0) {
int r, c; // last processed (prv in loop, not in pipe)
if (cr == 0) {
r = N - 1;
c = cc - 1;
} else {
r = cr - 1;
c = cc;
}
int pmsk = prv[cr][cc][cmsk]; // came from dp[r][c][pmask]
int ch = choice[cr][cc][cmsk]; // choice made by (r, c) to reach (rc, cc)
// how we came in (cr, cc) from (r, c)
int down = (ch >> 1) & 1;
int ri = ch & 1;
// where edges of (r, c) went
if (down) g[2 * r + 2][2 * c + 1] = '.';
if (ri) g[2 * r + 1][2 * c + 2] = '.';
// how we go into of (r, c)
int up = (pmsk >> r) & 1;
int lef = (pmsk >> (r + 1)) & 1;
// if edge out or in, then we must have passed in
if ((up || lef || down || ri) && g[2 * r + 1][2 * c + 1] == ' ') {
g[2 * r + 1][2 * c + 1] = '.';
}
cr = r;
cc = c;
cmsk = pmsk;
}
for(int i = 0; i < R; ++i) {
while((int)g[i].size() > C && g[i].back() == ' ') {
g[i].pop_back();
}
cout << g[i] << el;
}
}
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int _t = 1;
// cin >> _t;
for (int i = 1; i <= _t; i++) {
run_case(i);
}
}