import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;

/**
 * http://codeforces.com/contest/752/problem/D
 */

public class TaskD {
    private static int PRIME = 1_000_000_007;

    public static void main(String[] arg) {
        final FastScanner in = new FastScanner(System.in);
        final PrintWriter out = new PrintWriter(System.out);
        final int n = in.nextInt();
        final int k = in.nextInt();
        Map<Integer, Queue<Integer>> eqHashes = new HashMap<>();
        Map<Integer, Queue<Integer>> fMap = new HashMap<>();
        Map<Integer, Queue<Integer>> bMap = new HashMap<>();
        int[][] hashes = new int[n][2];
        for (int i = 0; i < n; i++) {
            String str = in.next();
            int value = in.nextInt();
            char[] chars = str.toCharArray();
            int hash = hash(chars);
            int bhash = bakHash(chars);
            if (hash == bhash) {
                addValue(hash, value, eqHashes);
            } else {
                addValue(hash, value, fMap);
                addValue(bhash, value, bMap);
            }
            hashes[i][0] = hash;
            hashes[i][1] = bhash;
        }

        long result = 0;
        int max = 0;
        for (int i = 0; i < n; i++) {
            if (hashes[i][0] == hashes[i][1]) {
                int[] res = pool2Values(hashes[i][0],eqHashes);
                if(res==null){
                    continue;
                }
                if(res[0]+res[1]>0){
                    result=res[0]+res[1]+result;
                    if(res[1]<0){
                        max = Math.max(-res[1],max);
                    }
                }
                else{
                    addValue(hashes[i][0],res[1],eqHashes);
                    addValue(hashes[i][0],res[0],eqHashes);
                }
                continue;
            }
            //get string itself
            Integer fVal = poolVal(hashes[i][0],fMap);
            Integer bVal = poolVal(hashes[i][1],bMap);
            //find componion
            Integer cfVal = peekVal(hashes[i][1],fMap);
            int sum1=0;
            if(fVal!=null && cfVal!=null){
                sum1=cfVal+fVal;
            }
            if(sum1>0){
                result+=sum1;
                poolVal(hashes[i][1],fMap);
                poolVal(hashes[i][0],bMap);
            }
        }
        for(Queue<Integer> q:eqHashes.values()){
            if(q.size()>0){
                max = Math.max(max, q.peek());
            }
        }
        result+=max;
        out.printf("%d%n", Math.max(result, 0));
        out.close();
        in.close();
    }

    private static Integer peekVal(int key, Map<Integer, Queue<Integer>> map){
        Queue<Integer> values = map.get(key);
        if(values==null || values.isEmpty()){
            return null;
        }
        return values.peek();
    }

    private static int[] pool2Values(int key, Map<Integer, Queue<Integer>> map){
        Queue<Integer> values = map.get(key);
        if(values==null || values.size()<2){
            return null;
        }
        int []res = new int[2];
        res[0]=values.poll();
        res[1]=values.poll();
        return  res;
    }

    private  static Integer poolVal(int key, Map<Integer, Queue<Integer>> map){
        Queue<Integer> values = map.get(key);
        return values.poll();
    }

    private static void addValue(int key, int value, Map<Integer, Queue<Integer>> map) {
        Queue<Integer> values = map.get(key);
        if (values == null) {
            values = new PriorityQueue<>(1, Collections.reverseOrder());
            map.put(key, values);
        }
        values.add(value);
    }

    public void test() {

        String s1 = "aaaaaaaaaaaaaaaab";
        String s2 = "baaaaaaaaaaaaaaaa";
        System.out.printf("%d %d %n", hash(s1.toCharArray()), bakHash(s2.toCharArray()));
    }

    private static int hash(char[] cs) {
        long h = 0;
        for (int i = 0; i < cs.length; i++) {
            h = 97L * h % PRIME;
            h = h + cs[i];
        }
        return (int) (h % PRIME);
    }

    private static int bakHash(char[] cs) {
        long h = 0;
        for (int i = cs.length - 1; i >= 0; i--) {
            h = 97L * h % PRIME;
            h = h + cs[i];
        }
        return (int) (h % PRIME);
    }

    private static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream stream) {
            try {
                br = new BufferedReader(new InputStreamReader(stream));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        int[] readIntArr(int n) {
            int[] result = new int[n];
            for (int i = 0; i < n; i++) {
                result[i] = Integer.parseInt(next());
            }
            return result;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        long nextLong() {
            return Long.parseLong(next());
        }

    }

}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.StringTokenizer;

public class c implements Runnable {

	final int oo = 987654321;

	int n, m;
	char[][] grid;
	int[] dr = {0, 1, 0, -1, -1, -1, 1, 1};
	int[] dc = {1, 0, -1, 0, -1, 1, -1, 1};

	public void solve(FS in, PrintWriter out) {
		n = in.nextInt();
		m = in.nextInt();
		grid = new char[n][];
		for(int i = 0; i < n; ++i) {
			grid[i] = in.next().toCharArray();
		}
		int[][] dist = new int[n][m];
		{
			ArrayDeque<int[]> q = new ArrayDeque<>();
			for(int i = 0; i < n; ++i) Arrays.fill(dist[i], oo);
			for(int i = 0; i < n; ++i) {
				for(int j = 0; j < m; ++j) {
					if(grid[i][j] != 'X') continue;
					boolean isBorder = false;
					for(int k = 0; k < dr.length; ++k) {
						int r = i + dr[k], c = j + dc[k];
						if(r < 0 || r >= n || c < 0 || c >= m || grid[r][c] == '.') {
							isBorder = true;
							break;
						}
					}
					if(isBorder) {
						q.add(new int[] {i, j});
						dist[i][j] = 0;
					}
				}
			}
			while(!q.isEmpty()) {
				int[] curCell = q.poll();
				int i = curCell[0], j = curCell[1];
				for(int k = 0; k < dr.length; ++k) {
					int r = i + dr[k], c = j + dc[k];
					if(r < 0 || r >= n || c < 0 || c >= m || grid[r][c] == '.') continue;
					int ndist = dist[i][j] + 1;
					if(dist[r][c] <= ndist) continue;
					dist[r][c] = ndist;
					q.add(new int[] {r, c});
				}
			}
		}

		int lo = 0, hi = n * m;
		int[][] minDist = new int[n][m];
		while(lo <= hi) {
			int mid = lo + hi >> 1;
			ArrayDeque<int[]> q = new ArrayDeque<>();
			for(int[] cur : minDist) Arrays.fill(cur, oo);
			for(int i = 0; i < n; ++i) {
				for(int j = 0; j < m; ++j) {
					if(grid[i][j] == 'X' && dist[i][j] >= mid) {
						q.add(new int[] {i, j});
						minDist[i][j] = 0;
					}
				}
			}
			boolean good = true;
			while(!q.isEmpty()) {
				int[] curCell = q.poll();
				int i = curCell[0], j = curCell[1];
				for(int k = 0; k < dr.length; ++k) {
					int r = i + dr[k], c = j + dc[k];
					int ndist = minDist[i][j] + 1;
					if(ndist > mid) continue;
					if(r < 0 || r >= n || c < 0 || c >= m || grid[r][c] == '.') {
						good = false;
						continue;
					}
					if(minDist[r][c] <= ndist) continue;
					minDist[r][c] = ndist;
					q.add(new int[] {r, c});
				}
			}
			for(int i = 0; good && i < n; ++i) {
				for(int j = 0; good && j < m; ++j) {
					if(grid[i][j] != 'X') continue;
					if(minDist[i][j] > mid) {
						good = false;
					}
				}
			}
			if(good) lo = mid + 1;
			else hi = mid - 1;
		}
		out.println(hi);
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < m; ++j) {
				if(grid[i][j] == 'X' && dist[i][j] >= hi) {
					out.print('X');
				} else {
					out.print('.');
				}
			}
			out.println();
		}
	}

	public void run() {
		System.err.println("go!");
		FS in = new FS();
		PrintWriter out = new PrintWriter(System.out);
		solve(in, out);
		out.close();
	}

	public static void main(String[] args) {
		new Thread(null, new c(), "lmao", 1L<<28).start();
	}
	static class FS {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");
		String next() {
			while(!st.hasMoreElements()) {
				try { st = new StringTokenizer(br.readLine()); }
				catch(Exception e) {}
			}
			return st.nextToken();
		}
		int nextInt() {
			return Integer.parseInt(next());
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.io.BufferedReader;
// import java.io.FileInputStream;
// import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Random;
import java.util.StringTokenizer;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.round;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;
import static java.util.Collections.reverseOrder;
import static java.util.Collections.sort;
import static java.util.Comparator.comparingInt;

public class Solution {
    FastScanner in;
    PrintWriter out;

    private void solve() throws IOException {
        int N = in.nextInt(), M = in.nextInt();
        boolean[][] map = new boolean[N + 2][M + 2];
        for (int i = 0; i < N; i++) {
            char[] s = in.next().toCharArray();
            for (int j = 0; j < M; j++) {
                map[i + 1][j + 1] = s[j] == 'X';
            }
        }

        int[][] sum = new int[N + 1][M + 1];
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                sum[i][j] = (map[i][j] ? 1 : 0) + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
            }
        }

        int l = 1, r = min(N, M) + 1;
        int[][] cur = new int[N + 2][M + 2];

        while (l + 1 < r) {
            int m = (l + r) / 2;
            for (int i = 1; i <= N - m + 1; i++) {
                for (int j = 1; j <= M - m + 1; j++) {
                    if (map[i][j] && sum[i + m - 1][j + m - 1] - sum[i - 1][j + m - 1] - sum[i + m - 1][j - 1] + sum[i - 1][j - 1] == m * m) {
                        cur[i][j]++;
                        cur[i + m][j]--;
                        cur[i][j + m]--;
                        cur[i + m][j + m]++;
                    }
                }
            }

            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= M; j++) {
                    cur[i][j] += cur[i - 1][j] + cur[i][j - 1] - cur[i - 1][j - 1];
                }
            }

            boolean ok = true;
            main:
            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= M; j++) {
                    if (map[i][j] && cur[i][j] == 0) {
                        ok = false;
                        break main;
                    }
                }
            }

            if (ok)
                l = m;
            else
                r = m;

            for (int i = 0; i < cur.length; i++) {
                fill(cur[i], 0);
            }
        }

        if (l % 2 == 0)
            l--;
        out.println(l / 2);
        boolean[][] ans = new boolean[N][M];
        for (int i = 0; i <= N - l; i++) {
            for (int j = 0; j <= M - l; j++) {
                if (map[i + 1][j + 1] && sum[i + l][j + l] - sum[i][j + l] - sum[i + l][j] + sum[i][j] == l * l) {
                    ans[i + l / 2][j + l / 2] = true;
                }
            }
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++)
                out.print(ans[i][j] ? 'X' : '.');
            out.println();
        }
    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

        FastScanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

        boolean hasNextLine() throws IOException {
            return br.ready();
        }
    }

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream(".in"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream(".out"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Solution().run();
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int height;
        int width;
        char[][] s;
        char[][] t;
        int[][] dist;
        int[] qr;
        int[] qc;
        int[][] sum;

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            height = in.nextInt();
            width = in.nextInt();
            s = new char[height][];
            for (int r = 0; r < height; r++) {
                s[r] = in.next().toCharArray();
            }

            init();

            int left = 0;
            int right = height + width + 1;
            while (right - left > 1) {
                int middle = (left + right) / 2;
                if (can(middle)) {
                    left = middle;
                } else {
                    right = middle;
                }
            }
            can(left);

            out.println(left);
            for (int r = 0; r < height; r++) {
                out.println(new String(t[r]));
            }
        }

        private void init() {
            qr = new int[height * width];
            qc = new int[height * width];

            t = new char[height][width];
            dist = new int[height][width];

            sum = new int[height + 1][width + 1];
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    sum[r + 1][c + 1] = sum[r + 1][c] + sum[r][c + 1] - sum[r][c] + (s[r][c] == 'X' ? 1 : 0);
                }
            }
        }

        private int getSum(int r1, int c1, int r2, int c2) {
            return sum[r2 + 1][c2 + 1] - sum[r2 + 1][c1] - sum[r1][c2 + 1] + sum[r1][c1];
        }

        private boolean can(int radius) {
            int qt = 0;
            int qh = 0;
            int area = (2 * radius + 1) * (2 * radius + 1);
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    t[r][c] = '.';
                    dist[r][c] = -1;
                    int r1 = r - radius;
                    int r2 = r + radius;
                    int c1 = c - radius;
                    int c2 = c + radius;
                    if (r1 >= 0 && r2 < height && c1 >= 0 && c2 < width && getSum(r1, c1, r2, c2) == area) {
                        t[r][c] = 'X';
                        qr[qh] = r;
                        qc[qh] = c;
                        ++qh;
                        dist[r][c] = 0;
                    }
                }
            }

            while (qt < qh) {
                int r = qr[qt];
                int c = qc[qt];
                ++qt;
                if (dist[r][c] == radius) {
                    continue;
                }
                for (int dr = -1; dr <= 1; dr++) {
                    for (int dc = -1; dc <= 1; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                            continue;
                        }
                        if (dist[nr][nc] < 0) {
                            dist[nr][nc] = 1 + dist[r][c];
                            qr[qh] = nr;
                            qc[qh] = nc;
                            ++qh;
                        }
                    }
                }
            }

            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    char ch = dist[r][c] < 0 ? '.' : 'X';
                    if (ch != s[r][c]) {
                        return false;
                    }
                }
            }
            return true;
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int height;
        int width;
        char[][] s;
        char[][] t;
        int[][] deg;
        int[][] compId;
        int numComps;
        int[] qr;
        int[] qc;
        int[][] compR;
        int[][] compC;

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            height = in.nextInt();
            width = in.nextInt();
            s = new char[height][];
            for (int r = 0; r < height; r++) {
                s[r] = in.next().toCharArray();
            }

            findComponents();

            deg = new int[height][width];
            t = new char[height][width];
            reset();

            int[] compTime = new int[numComps];
            int minTime = Integer.MAX_VALUE;
            for (int i = 0; i < numComps; i++) {
                compTime[i] = burnComponent(i, Integer.MAX_VALUE);
                minTime = Math.min(minTime, compTime[i]);
            }

            reset();
            for (int i = 0; i < numComps; i++) {
                burnComponent(i, minTime);
            }

            out.println(minTime);
            for (int r = 0; r < height; r++) {
                out.println(new String(t[r]));
            }
        }

        private void findComponents() {
            compId = new int[height][width];
            for (int[] arr : compId) {
                Arrays.fill(arr, -1);
            }
            qr = new int[height * width];
            qc = new int[height * width];
            compR = new int[height * width][];
            compC = new int[height * width][];
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    if (s[r][c] == 'X' && compId[r][c] < 0) {
                        bfsComp(r, c);
                    }
                }
            }
            compR = Arrays.copyOf(compR, numComps);
            compC = Arrays.copyOf(compC, numComps);
        }

        private void reset() {
            for (int r = 0; r < height; r++) {
                System.arraycopy(s[r], 0, t[r], 0, width);
            }

            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    deg[r][c] = 0;
                    if (s[r][c] != 'X') {
                        continue;
                    }
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = r + dr;
                            int nc = c + dc;
                            if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                                continue;
                            }
                            if (s[nr][nc] == 'X') {
                                ++deg[r][c];
                            }
                        }
                    }
                }
            }
        }

        private int burnComponent(int compId, int timeLimit) {
            int[] rs = compR[compId];
            int[] cs = compC[compId];
            int qt = 0;
            int qh = 0;
            for (int i = 0; i < rs.length; i++) {
                int r = rs[i];
                int c = cs[i];
                if (deg[r][c] < 8) {
                    qr[qh] = r;
                    qc[qh] = c;
                    ++qh;
                }
            }

            for (int time = 0; time < timeLimit; time++) {
                if (qh == rs.length) {
                    // This was the last layer.
                    return time;
                }

                int nqh = qh;
                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = r + dr;
                            int nc = c + dc;
                            if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                                continue;
                            }
                            if (s[nr][nc] != 'X') {
                                continue;
                            }
                            if (deg[nr][nc] == 8) {
                                qr[nqh] = nr;
                                qc[nqh] = nc;
                                ++nqh;
                            }
                            --deg[nr][nc];
                        }
                    }
                }
                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    t[r][c] = '.';
                }
                qt = qh;
                qh = nqh;
            }
            return timeLimit;
        }

        private void bfsComp(int sr, int sc) {
            compId[sr][sc] = numComps;
            qr[0] = sr;
            qc[0] = sc;
            int qt = 0;
            int qh = 1;
            while (qt < qh) {
                int r = qr[qt];
                int c = qc[qt];
                ++qt;
                for (int dr = -1; dr <= 1; dr++) {
                    for (int dc = -1; dc <= 1; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                            continue;
                        }
                        if (s[nr][nc] == 'X' && compId[nr][nc] < 0) {
                            compId[nr][nc] = numComps;
                            qr[qh] = nr;
                            qc[qh] = nc;
                            ++qh;
                        }
                    }
                }
            }

            compR[numComps] = Arrays.copyOfRange(qr, 0, qh);
            compC[numComps] = Arrays.copyOfRange(qc, 0, qh);
            ++numComps;
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int height;
        int width;
        char[][] s;
        char[][] t;
        int[][] deg;
        int[] qr;
        int[] qc;
        int numTrees;

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            height = in.nextInt();
            width = in.nextInt();
            s = new char[height][];
            for (int r = 0; r < height; r++) {
                s[r] = in.next().toCharArray();
            }

            init();

            int minTime = burn();

            out.println(minTime);
            for (int r = 0; r < height; r++) {
                out.println(new String(t[r]));
            }

            if (false) {
                for (int i = 0; i < minTime; i++) {
                    addOne();
                    out.println();
                    for (int r = 0; r < height; r++) {
                        out.println(new String(t[r]));
                    }
                }
            }
        }

        private void init() {
            qr = new int[height * width];
            qc = new int[height * width];

            deg = new int[height][width];
            t = new char[height][width];

            for (int r = 0; r < height; r++) {
                System.arraycopy(s[r], 0, t[r], 0, width);
            }

            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    deg[r][c] = 0;
                    if (s[r][c] != 'X') {
                        continue;
                    }
                    ++numTrees;
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = r + dr;
                            int nc = c + dc;
                            if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                                continue;
                            }
                            if (s[nr][nc] == 'X') {
                                ++deg[r][c];
                            }
                        }
                    }
                }
            }
        }

        private int burn() {
            int qt = 0;
            int qh = 0;

            boolean[][] burning = new boolean[height][width];
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    if (s[r][c] == 'X' && deg[r][c] < 9) {
                        qr[qh] = r;
                        qc[qh] = c;
                        ++qh;
                        burning[r][c] = true;
                    }
                }
            }

            if (qh == numTrees) {
                return 0;
            }

            boolean[][] hitAny = new boolean[height][width];
            for (int time = 1; ; time++) {
                int nqh = qh;
                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = r + dr;
                            int nc = c + dc;
                            if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                                continue;
                            }
                            if (s[nr][nc] != 'X') {
                                continue;
                            }
                            if (!burning[nr][nc]) {
                                hitAny[r][c] = true;
                            }
                            if (deg[nr][nc] == 9) {
                                qr[nqh] = nr;
                                qc[nqh] = nc;
                                ++nqh;
                            }
                            --deg[nr][nc];
                        }
                    }
                }
                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    if (!hitAny[r][c]) {
                        return time - 1;
                    }
                }

                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    t[r][c] = '.';
                    burning[r][c] = true;
                }
                if (nqh == numTrees) {
                    return time;
                }
                qt = qh;
                qh = nqh;
            }
        }

        private void addOne() {
            int qh = 0;
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    if (t[r][c] == 'X') {
                        qr[qh] = r;
                        qc[qh] = c;
                        ++qh;
                    }
                }
            }

            for (int qi = 0; qi < qh; qi++) {
                int r = qr[qi];
                int c = qc[qi];
                for (int dr = -1; dr <= 1; dr++) {
                    for (int dc = -1; dc <= 1; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                            continue;
                        }
                        t[nr][nc] = 'X';
                    }
                }
            }
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        int height;
        int width;
        char[][] s;
        char[][] t;
        int[][] deg;
        int[][] compId;
        int numComps;
        int[] qr;
        int[] qc;
        int[][] compR;
        int[][] compC;

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            height = in.nextInt();
            width = in.nextInt();
            s = new char[height][];
            for (int r = 0; r < height; r++) {
                s[r] = in.next().toCharArray();
            }

            findComponents();

            deg = new int[height][width];
            t = new char[height][width];
            reset();

            int[] compTime = new int[numComps];
            int minTime = Integer.MAX_VALUE;
            for (int i = 0; i < numComps; i++) {
                compTime[i] = burnComponent(i, Integer.MAX_VALUE);
                minTime = Math.min(minTime, compTime[i]);
            }

            reset();
            for (int i = 0; i < numComps; i++) {
                burnComponent(i, minTime);
            }

            out.println(minTime);
            for (int r = 0; r < height; r++) {
                out.println(new String(t[r]));
            }

            if (false) {
                for (int i = 0; i < minTime; i++) {
                    addOne();
                    out.println();
                    for (int r = 0; r < height; r++) {
                        out.println(new String(t[r]));
                    }
                }
            }
        }

        private void addOne() {
            int qh = 0;
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    if (t[r][c] == 'X') {
                        qr[qh] = r;
                        qc[qh] = c;
                        ++qh;
                    }
                }
            }

            for (int qi = 0; qi < qh; qi++) {
                int r = qr[qi];
                int c = qc[qi];
                for (int dr = -1; dr <= 1; dr++) {
                    for (int dc = -1; dc <= 1; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                            continue;
                        }
                        t[nr][nc] = 'X';
                    }
                }
            }
        }

        private void findComponents() {
            compId = new int[height][width];
            for (int[] arr : compId) {
                Arrays.fill(arr, -1);
            }
            qr = new int[height * width];
            qc = new int[height * width];
            compR = new int[height * width][];
            compC = new int[height * width][];
            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    if (s[r][c] == 'X' && compId[r][c] < 0) {
                        bfsComp(r, c);
                    }
                }
            }
            compR = Arrays.copyOf(compR, numComps);
            compC = Arrays.copyOf(compC, numComps);
        }

        private void reset() {
            for (int r = 0; r < height; r++) {
                System.arraycopy(s[r], 0, t[r], 0, width);
            }

            for (int r = 0; r < height; r++) {
                for (int c = 0; c < width; c++) {
                    deg[r][c] = 0;
                    if (s[r][c] != 'X') {
                        continue;
                    }
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = r + dr;
                            int nc = c + dc;
                            if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                                continue;
                            }
                            if (s[nr][nc] == 'X') {
                                ++deg[r][c];
                            }
                        }
                    }
                }
            }
        }

        private int burnComponent(int compId, int timeLimit) {
            int[] rs = compR[compId];
            int[] cs = compC[compId];
            int qt = 0;
            int qh = 0;

            for (int i = 0; i < rs.length; i++) {
                int r = rs[i];
                int c = cs[i];
                if (deg[r][c] < 9) {
                    qr[qh] = r;
                    qc[qh] = c;
                    ++qh;
                }
            }

            for (int time = 0; time < timeLimit; time++) {
                if (qh == rs.length) {
                    // This was the last layer.
                    return time;
                }

                int nqh = qh;
                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = r + dr;
                            int nc = c + dc;
                            if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                                continue;
                            }
                            if (s[nr][nc] != 'X') {
                                continue;
                            }
                            if (deg[nr][nc] == 9) {
                                qr[nqh] = nr;
                                qc[nqh] = nc;
                                ++nqh;
                            }
                            --deg[nr][nc];
                        }
                    }
                }
                for (int qi = qt; qi < qh; qi++) {
                    int r = qr[qi];
                    int c = qc[qi];
                    t[r][c] = '.';
                }
                qt = qh;
                qh = nqh;
            }
            return timeLimit;
        }

        private void bfsComp(int sr, int sc) {
            compId[sr][sc] = numComps;
            qr[0] = sr;
            qc[0] = sc;
            int qt = 0;
            int qh = 1;
            while (qt < qh) {
                int r = qr[qt];
                int c = qc[qt];
                ++qt;
                for (int dr = -1; dr <= 1; dr++) {
                    for (int dc = -1; dc <= 1; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (nr < 0 || nr >= height || nc < 0 || nc >= width) {
                            continue;
                        }
                        if (s[nr][nc] == 'X' && compId[nr][nc] < 0) {
                            compId[nr][nc] = numComps;
                            qr[qh] = nr;
                            qc[qh] = nc;
                            ++qh;
                        }
                    }
                }
            }

            compR[numComps] = Arrays.copyOfRange(qr, 0, qh);
            compC[numComps] = Arrays.copyOfRange(qc, 0, qh);
            ++numComps;
        }

    }

    static class FastScanner {
        private BufferedReader in;
        private StringTokenizer st;

        public FastScanner(InputStream stream) {
            in = new BufferedReader(new InputStreamReader(stream));
        }

        public String next() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    String rl = in.readLine();
                    if (rl == null) {
                        return null;
                    }
                    st = new StringTokenizer(rl);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


//package round602;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class C {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		char[][] map = nm(n,m);
		int[][] cum = new int[n+1][m+1];
		for(int i = 0;i < n;i++){
			for(int j = 0;j < m;j++){
				cum[i+1][j+1] = cum[i][j+1] + cum[i+1][j] - cum[i][j] + (map[i][j] == 'X' ? 1 : 0);
			}
		}

		int low = 0, high = Math.min(n,m)+1;
		while(high - low > 1){
			int h = high+low>>1;
			if(ok(h, map, cum)){
				low = h;
			}else{
				high = h;
			}
		}
		out.println(low);
		restore(low, map, cum);
	}

	boolean ok(int h, char[][] map, int[][] cum)
	{
		int n = map.length, m = map[0].length;
		int[][] stamp = new int[n+2][m+2];
		int o = 2*h+1;
		for(int i = 0;i+o <= n;i++){
			for(int j = 0;j+o <= m;j++){
				if(cum[i+o][j+o] -
						cum[i+o][j] -
						cum[i][j+o] +
						cum[i][j] == (o)*(o)){
					stamp[i+1][j+1]++;
					stamp[i+o+1][j+1]--;
					stamp[i+1][j+o+1]--;
					stamp[i+o+1][j+o+1]++;
				}
			}
		}
		boolean ret = true;
		for(int i = 0;i < n;i++){
			for(int j = 0;j < m;j++){
				stamp[i+1][j+1] +=
						stamp[i][j+1] + stamp[i+1][j]
								- stamp[i][j];
				if((stamp[i+1][j+1] > 0) != (map[i][j] == 'X')){
//					return false;
					ret = false;
				}
			}
		}
		return ret;
	}

	void restore(int h, char[][] map, int[][] cum)
	{
		int n = map.length, m = map[0].length;
		int o = 2*h+1;
		char[][] ret = new char[n][m];
		for(int i = 0;i < n;i++)Arrays.fill(ret[i], '.');
		for(int i = 0;i+o <= n;i++){
			for(int j = 0;j+o <= m;j++){
				if(cum[i+o][j+o] -
						cum[i+o][j] -
						cum[i][j+o] +
						cum[i][j] == (o)*(o)){
					ret[i+h][j+h] = 'X';
				}
			}
		}
		for(int i = 0;i < n;i++){
			out.println(new String(ret[i]));
		}
	}

	void run() throws Exception
	{
//		int n = 1000000, m = 1;
//		Random gen = new Random();
//		StringBuilder sb = new StringBuilder();
//		sb.append(n + " ");
//		sb.append(m + " ");
//		for (int i = 0; i < n; i++) {
//			for(int j = 0;j < m;j++){
//				sb.append("X");
//			}
//			sb.append("\n");
//		}
//		INPUT = sb.toString();

		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new C().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;

public class Main {

    String fileName = "";

    boolean Check(int x1, int y1, int x2, int y2, int[][] arr) {
        int sz = (x2 - x1 + 1) * (y2 - y1 + 1);
        int sum = arr[x2][y2]
                - (x1 > 0 ? arr[x1 - 1][y2] : 0)
                - (y1 > 0 ? arr[x2][y1 - 1] : 0)
                + (x1 > 0 && y1 > 0 ? arr[x1 - 1][y1 - 1] : 0);
        return sz == sum;
    }

    class Pair implements Comparable<Pair> {
        int a, b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public int compareTo(Pair o) {
            if (a != o.a) {
                return Integer.compare(a, o.a);
            }
            return Integer.compare(b, o.b);
        }
    }

    void Solve() throws IOException {
        int n = readInt(), m = readInt();
        char[][] a = new char[n][m];
        for (int i = 0; i < n; i++) {
            a[i] = readString().toCharArray();
        }
        int[][] arr = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] = a[i][j] == 'X' ? 1 : 0;
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 1; j < m; j++) {
                arr[i][j] += arr[i][j - 1];
            }
        }
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] += arr[i - 1][j];
            }
        }

        int[][] max = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int left = 0;
                int right = Math.min(Math.min(i, j), Math.min(n - 1 - i, m - 1 - j));
                int mid;
                while (left <= right) {
                    mid = (left + right) / 2;
                    if (Check(i - mid, j - mid, i + mid, j + mid, arr)) {
                        max[i + mid][j + mid] = Math.max(mid, max[i + mid][j + mid]);
                        left = mid + 1;
                    } else {
                        right = mid - 1;
                    }
                }
            }
        }

        /*
               0 0 0
               0 0 0
               0 0 1
               max = 1
               [i][j - 2 * max] .. [i][j]

               1 1 1
               1 1 1
               1 1 1

         */

        int[][] ans = new int[n][m];

        for (int i = n - 1; i >= 0; i--) {
            PriorityQueue<Pair> set = new PriorityQueue<>();
            for (int j = m - 1; j >= 0; j--) {
                if (a[i][j] == 'X') {
                    set.add(new Pair(-max[i][j], - j + 2 * max[i][j]));

                    while (!set.isEmpty() && -set.peek().b > j) {
                        set.poll();
                    }
                    ans[i][j] = -set.peek().a;
                }
            }
        }
        for (int j = m - 1; j >= 0; j--) {
            PriorityQueue<Pair> set = new PriorityQueue<>();
            for (int i = n - 1; i >= 0; i--) {
                if (a[i][j] == 'X') {
                    set.add(new Pair(-ans[i][j], - i + 2 * ans[i][j]));

                    while (!set.isEmpty() && -set.peek().b > i) {
                        set.poll();
                    }
                    ans[i][j] = -set.peek().a;
                }
            }
        }
        int answer = Math.min(n, m);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                answer = Math.min(answer, a[i][j] == 'X' ? ans[i][j] : answer);
            }
        }
        out.println(answer);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (a[i][j] == '.') {
                    continue;
                } else {
                    int right = Math.min(Math.min(i, j), Math.min(n - 1 - i, m - 1 - j));
                    if (right < answer || !Check(i - answer, j - answer, i + answer, j + answer, arr)) {
                        a[i][j] = '.';
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            String str = new String(a[i]);
            out.println(str);
        }
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }

    void run() throws IOException {
        Solve();
        out.close();
    }

    BufferedReader in;
    PrintWriter out;

    StringTokenizer tok;
    String delimiter = " ";

    Main() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new PrintWriter(fileName + ".out");
            }
        }
        tok = new StringTokenizer("");
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            String nextLine = in.readLine();
            if (null == nextLine) {
                return null;
            }

            tok = new StringTokenizer(nextLine);
        }
        return tok.nextToken(delimiter);
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    int[] readIntArray(int n) throws IOException {
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = readInt();
        }
        return a;
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    void sortIntArray(int[] a) {
        Integer[] arr = new Integer[a.length];
        for (int i = 0; i < a.length; i++) {
            arr[i] = a[i];
        }

        Arrays.sort(arr);
        for (int i = 0; i < a.length; i++) {
            a[i] = arr[i];
        }
    }
}


import java.io.*;
import java.util.*;

public class Main {

    String fileName = "";

    boolean Check(int x1, int y1, int x2, int y2, int[][] arr) {
        int sz = (x2 - x1 + 1) * (y2 - y1 + 1);
        int sum = arr[x2][y2]
                - (x1 > 0 ? arr[x1 - 1][y2] : 0)
                - (y1 > 0 ? arr[x2][y1 - 1] : 0)
                + (x1 > 0 && y1 > 0 ? arr[x1 - 1][y1 - 1] : 0);
        return sz == sum;
    }

    class Pair implements Comparable<Pair> {
        int a, b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public int compareTo(Pair o) {
            if (a != o.a) {
                return Integer.compare(a, o.a);
            }
            return Integer.compare(b, o.b);
        }
    }

    void Solve() throws IOException {
        int n = readInt(), m = readInt();
        char[][] a = new char[n][m];
        for (int i = 0; i < n; i++) {
            a[i] = readString().toCharArray();
        }
        int[][] arr = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] = a[i][j] == 'X' ? 1 : 0;
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 1; j < m; j++) {
                arr[i][j] += arr[i][j - 1];
            }
        }
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] += arr[i - 1][j];
            }
        }

        int[][] max = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int left = 0;
                int right = Math.min(Math.min(i, j), Math.min(n - 1 - i, m - 1 - j));
                int mid;
                while (left <= right) {
                    mid = (left + right) / 2;
                    if (Check(i - mid, j - mid, i + mid, j + mid, arr)) {
                        max[i + mid][j + mid] = Math.max(mid, max[i + mid][j + mid]);
                        left = mid + 1;
                    } else {
                        right = mid - 1;
                    }
                }
            }
        }

        /*
               0 0 0
               0 0 0
               0 0 1
               max = 1
               [i][j - 2 * max] .. [i][j]

               1 1 1
               1 1 1
               1 1 1

         */

        int[][] ans = new int[n][m];

        for (int i = n - 1; i >= 0; i--) {
            TreeSet<Pair> set = new TreeSet<>();
            for (int j = m - 1; j >= 0; j--) {
                if (a[i][j] == 'X') {
                    set.add(new Pair(max[i][j], j - 2 * max[i][j]));

                    while (!set.isEmpty() && set.last().b > j) {
                        set.pollLast();
                    }
                    ans[i][j] = set.last().a;
                }
            }
        }
        for (int j = m - 1; j >= 0; j--) {
            TreeSet<Pair> set = new TreeSet<>();
            for (int i = n - 1; i >= 0; i--) {
                if (a[i][j] == 'X') {
                    set.add(new Pair(ans[i][j], i - 2 * ans[i][j]));

                    while (!set.isEmpty() && set.last().b > i) {
                        set.pollLast();
                    }
                    ans[i][j] = set.last().a;
                }
            }
        }
        int answer = Math.min(n, m);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                answer = Math.min(answer, a[i][j] == 'X' ? ans[i][j] : answer);
            }
        }
        out.println(answer);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (a[i][j] == '.') {
                    continue;
                } else {
                    int right = Math.min(Math.min(i, j), Math.min(n - 1 - i, m - 1 - j));
                    if (right < answer || !Check(i - answer, j - answer, i + answer, j + answer, arr)) {
                        a[i][j] = '.';
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            String str = new String(a[i]);
            out.println(str);
        }
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }

    void run() throws IOException {
        Solve();
        out.close();
    }

    BufferedReader in;
    PrintWriter out;

    StringTokenizer tok;
    String delimiter = " ";

    Main() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new PrintWriter(fileName + ".out");
            }
        }
        tok = new StringTokenizer("");
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            String nextLine = in.readLine();
            if (null == nextLine) {
                return null;
            }

            tok = new StringTokenizer(nextLine);
        }
        return tok.nextToken(delimiter);
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    int[] readIntArray(int n) throws IOException {
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = readInt();
        }
        return a;
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    void sortIntArray(int[] a) {
        Integer[] arr = new Integer[a.length];
        for (int i = 0; i < a.length; i++) {
            arr[i] = a[i];
        }

        Arrays.sort(arr);
        for (int i = 0; i < a.length; i++) {
            a[i] = arr[i];
        }
    }
}


import java.io.*;
import java.util.*;

public class Main {

    String fileName = "";

    boolean Check(int x1, int y1, int x2, int y2, int[][] arr) {
        int sz = (x2 - x1 + 1) * (y2 - y1 + 1);
        int sum = arr[x2][y2]
                - (x1 > 0 ? arr[x1 - 1][y2] : 0)
                - (y1 > 0 ? arr[x2][y1 - 1] : 0)
                + (x1 > 0 && y1 > 0 ? arr[x1 - 1][y1 - 1] : 0);
        return sz == sum;
    }

    class Pair implements Comparable<Pair> {
        int a, b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public int compareTo(Pair o) {
            if (a != o.a) {
                return Integer.compare(a, o.a);
            }
            return Integer.compare(b, o.b);
        }
    }

    void Solve() throws IOException {
        int n = readInt(), m = readInt();
        char[][] a = new char[n][m];
        for (int i = 0; i < n; i++) {
            a[i] = readString().toCharArray();
        }
        int[][] arr = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] = a[i][j] == 'X' ? 1 : 0;
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 1; j < m; j++) {
                arr[i][j] += arr[i][j - 1];
            }
        }
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] += arr[i - 1][j];
            }
        }

        int[][] max = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int left = 0;
                int right = Math.min(Math.min(i, j), Math.min(n - 1 - i, m - 1 - j));
                int mid;
                while (left <= right) {
                    mid = (left + right) / 2;
                    if (Check(i - mid, j - mid, i + mid, j + mid, arr)) {
                        max[i + mid][j + mid] = Math.max(mid, max[i + mid][j + mid]);
                        left = mid + 1;
                    } else {
                        right = mid - 1;
                    }
                }
            }
        }

        /*
               0 0 0
               0 0 0
               0 0 1
               max = 1
               [i][j - 2 * max] .. [i][j]

               1 1 1
               1 1 1
               1 1 1

         */

        int[][] ans = new int[n][m];

        for (int i = n - 1; i >= 0; i--) {
            TreeSet<Pair> set = new TreeSet<>();
            for (int j = m - 1; j >= 0; j--) {
                if (a[i][j] == 'X') {
                    set.add(new Pair(max[i][j], j - 2 * max[i][j]));

                    while (!set.isEmpty() && set.last().b > j) {
                        set.pollLast();
                    }
                    ans[i][j] = set.last().a;
                }
            }
        }
        for (int j = m - 1; j >= 0; j--) {
            TreeSet<Pair> set = new TreeSet<>();
            for (int i = n - 1; i >= 0; i--) {
                if (a[i][j] == 'X') {
                    set.add(new Pair(ans[i][j], i - 2 * ans[i][j]));

                    while (!set.isEmpty() && set.last().b > i) {
                        set.pollLast();
                    }
                    ans[i][j] = set.last().a;
                }
            }
        }
        int answer = Math.min(n, m);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                answer = Math.min(answer, a[i][j] == 'X' ? ans[i][j] : answer);
            }
        }
        out.println(answer);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (a[i][j] == '.') {
                    out.print(a[i][j]);
                } else {
                    int right = Math.min(Math.min(i, j), Math.min(n - 1 - i, m - 1 - j));
                    if (right < answer || !Check(i - answer, j - answer, i + answer, j + answer, arr)) {
                        out.print('.');
                    } else {
                        out.print('X');
                    }
                }
            }
            out.print('\n');
        }
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }

    void run() throws IOException {
        Solve();
        out.close();
    }

    BufferedReader in;
    PrintWriter out;

    StringTokenizer tok;
    String delimiter = " ";

    Main() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            if (fileName.isEmpty()) {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            } else {
                in = new BufferedReader(new FileReader(fileName + ".in"));
                out = new PrintWriter(fileName + ".out");
            }
        }
        tok = new StringTokenizer("");
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            String nextLine = in.readLine();
            if (null == nextLine) {
                return null;
            }

            tok = new StringTokenizer(nextLine);
        }
        return tok.nextToken(delimiter);
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    int[] readIntArray(int n) throws IOException {
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = readInt();
        }
        return a;
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    void sortIntArray(int[] a) {
        Integer[] arr = new Integer[a.length];
        for (int i = 0; i < a.length; i++) {
            arr[i] = a[i];
        }

        Arrays.sort(arr);
        for (int i = 0; i < a.length; i++) {
            a[i] = arr[i];
        }
    }
}


#include <bits/stdc++.h>

using namespace std;

vector <vector <int> > v;
vector <vector <int> > sum;
vector <vector <int> > sol;
vector <vector <int> > aux;

int n, m;

bool ok(int x, int y, int k)
{
	return (1 <= x - k && x + k <= n && 1 <= y - k && y + k <= m);
}

int get_sum(int x1, int y1, int x2, int y2)
{
	return (sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1]);
}

bool check(int mid)
{
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
		{
			aux[i][j] = 0;
			sol[i][j] = 0;
		}

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			if(ok(i, j, mid))
			{
				if(get_sum(i - mid, j - mid, i + mid, j + mid) == (2 * mid + 1) * (2 * mid + 1))
				{
					sol[i][j] = 1;

					aux[i - mid][j - mid]++;
					aux[i + mid][j + mid]++;
					aux[i - mid][j + mid + 1]--;
					aux[i + mid + 1][j - mid]--;
				}
			}

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			aux[i][j] += aux[i - 1][j] + aux[i][j - 1] - sum[i - 1][j - 1];

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			if(v[i][j] == 1 && aux[i][j] == 0)
				return false;

	return true;
}

main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	cin >> n >> m;

	v.resize(n + 2, vector <int> (m + 2, 0));
	sum.resize(n + 2, vector <int> (m + 2, 0));
	sol.resize(n + 2, vector <int> (m + 2, 0));
	aux.resize(n + 2, vector <int> (m + 2, 0));

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
		{
			char c;
			cin >> c;

			if(c == '.')
				v[i][j] = 0;
			else
				v[i][j] = 1;

			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + v[i][j];
		}

	int l = 0;
	int r = min(n, m);

	int res = 0;

	while(l <= r)
	{
		int mid = (l + r) / 2;

		if(check(mid) == true)
		{
			l = mid + 1;
			res = mid;
		}
		else
		{
			r = mid - 1;
		}
	}

	check(res);

	cout << res << '\n';

	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{
			if(sol[i][j] == 1)
			{
				cout << 'X';
			}
			else
			{
				cout << '.';
			}
		}

		cout << '\n';
	}
}


#include <bits/stdc++.h>

using namespace std;

vector <vector <int> > v;
vector <vector <int> > sum;
vector <vector <int> > sol;
vector <vector <int> > aux;

int n, m;

bool ok(int x, int y, int k)
{
	return (1 <= x - k && x + k <= n && 1 <= y - k && y + k <= m);
}

int get_sum(int x1, int y1, int x2, int y2)
{
	return (sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1]);
}

bool check(int mid)
{
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
		{
			aux[i][j] = 0;
			sol[i][j] = 0;
		}

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			if(ok(i, j, mid))
			{
				if(get_sum(i - mid, j - mid, i + mid, j + mid) == (2 * mid + 1) * (2 * mid + 1))
				{
					sol[i][j] = 1;

					aux[i - mid][j - mid]++;
					aux[i + mid + 1][j + mid + 1]++;
					aux[i - mid][j + mid + 1]--;
					aux[i + mid + 1][j - mid]--;
				}
			}

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			aux[i][j] += aux[i - 1][j] + aux[i][j - 1] - aux[i - 1][j - 1];

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			if(v[i][j] == 1 && aux[i][j] == 0)
				return false;

	return true;
}

main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	cin >> n >> m;

	v.resize(n + 2, vector <int> (m + 2, 0));
	sum.resize(n + 2, vector <int> (m + 2, 0));
	sol.resize(n + 2, vector <int> (m + 2, 0));
	aux.resize(n + 2, vector <int> (m + 2, 0));

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
		{
			char c;
			cin >> c;

			if(c == '.')
				v[i][j] = 0;
			else
				v[i][j] = 1;

			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + v[i][j];
		}

	int l = 0;
	int r = min(n, m);

	int res = 0;

	while(l <= r)
	{
		int mid = (l + r) / 2;

		if(check(mid) == true)
		{
			l = mid + 1;
			res = mid;
		}
		else
		{
			r = mid - 1;
		}
	}

	check(res);

	cout << res << '\n';

	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{
			if(sol[i][j] == 1)
			{
				cout << 'X';
			}
			else
			{
				cout << '.';
			}
		}

		cout << '\n';
	}
}


#define _USE_MATH_DEFINES
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <complex>
#include <numeric>
#include <string.h>
#include <random>
#include <cmath>
#define rep(i,n) for (int i = 0; i < (int)n; i++)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pi;
typedef pair<pi, pi> pp;
typedef pair<ll, ll> pl;
double PI = 3.141592653589793238462643383279;
const double EPS = 1e-9;
const ll MOD = 1000000007;
//const ll MOD = 998244353
const int inf = 1 << 30;
const ll linf = 1LL << 60;

ll n, m;
vector<string> x;
vector<vector<int>> sum;
vector<vector<int>> ans;
vector<vector<int>> b;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    x.resize(n);
    rep(i,n) cin >> x[i];
    sum.resize(n+2);
    rep(i,n+2) sum[i].resize(m+2);
    b.resize(n+2);
    rep(i,n+2) b[i].resize(m+2);
    ans.resize(n+2);
    rep(i,n+2) ans[i].resize(m+2);
    rep(i,n+2) rep(j,m+2) sum[i][j] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            sum[i][j] = (x[i-1][j-1] == 'X');
            sum[i][j] += sum[i][j-1];
        }
    }
    for (int j = 1; j <= m; j++) {
        for (int i = 1; i <= n; i++) {
            sum[i][j] += sum[i-1][j];
        }
    }
    /*
    rep(i,n+2) {
        rep(j,n+2) {
            cerr << sum[i][j] << " ";
        }
        cerr << endl;
    }
    */
    int st = 1, en = 1001;
    while (en-st > 1) {
        int mid = (st+en)/2;
        rep(i,n+2) rep(j,m+2) b[i][j] = 0;
        for (int i = mid; i <= n; i++) {
            for (int j = mid; j <= m; j++) {
                int cnt = sum[i][j]-sum[i-mid][j]-sum[i][j-mid]+sum[i-mid][j-mid];
                if (cnt == mid*mid) {
                    b[i-mid+1][j-mid+1]++;
                    b[i-mid+1][j+1]--;
                    b[i+1][j-mid+1]--;
                    b[i+1][j+1]++;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                b[i][j] += b[i][j-1];
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                b[i][j] += b[i-1][j];
            }
        }
        bool ok = true;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (x[i-1][j-1] == 'X' && b[i][j] == 0) {
                    ok = false;
                }
            }
        }
        if (ok) st = mid;
        else en = mid;
    }
    if (st%2 == 0) st--;
    cout << st/2 << endl;
    rep(i,n+2) rep(j,m+2) ans[i][j] = 0;
    for (int i = st; i <= n; i++) {
        for (int j = st; j <= m; j++) {
            int cnt = sum[i][j]-sum[i-st][j]-sum[i][j-st]+sum[i-st][j-st];
            if (cnt == st*st) {
                ans[i-st/2][j-st/2] = 1;
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (ans[i][j]) cout << "X";
            else cout << ".";
        }
        cout << endl;
    }
}


#define _USE_MATH_DEFINES
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <complex>
#include <numeric>
#include <string.h>
#include <random>
#include <cmath>
#define rep(i,n) for (int i = 0; i < (int)n; i++)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pi;
typedef pair<pi, pi> pp;
typedef pair<ll, ll> pl;
double PI = 3.141592653589793238462643383279;
const double EPS = 1e-9;
const ll MOD = 1000000007;
//const ll MOD = 998244353
const int inf = 1 << 30;
const ll linf = 1LL << 60;

int n, m;
vector<string> x;
vector<vector<int>> sum;
vector<vector<int>> ans;
vector<vector<int>> b;
char buf[1000001];

int main() {
    scanf("%d%d", &n, &m);
    x.resize(n);
    rep(i,n) {
        scanf(" %s", buf);
        x[i] = buf;
    }
    sum.resize(n+2);
    rep(i,n+2) sum[i].resize(m+2);
    b.resize(n+2);
    rep(i,n+2) b[i].resize(m+2);
    ans.resize(n+2);
    rep(i,n+2) ans[i].resize(m+2);
    rep(i,n+2) rep(j,m+2) sum[i][j] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            sum[i][j] = (x[i-1][j-1] == 'X');
            sum[i][j] += sum[i][j-1];
        }
    }
    for (int j = 1; j <= m; j++) {
        for (int i = 1; i <= n; i++) {
            sum[i][j] += sum[i-1][j];
        }
    }
    int st = 1, en = 1001;
    while (en-st > 1) {
        int mid = (st+en)/2;
        rep(i,n+2) rep(j,m+2) b[i][j] = 0;
        for (int i = mid; i <= n; i++) {
            for (int j = mid; j <= m; j++) {
                int cnt = sum[i][j]-sum[i-mid][j]-sum[i][j-mid]+sum[i-mid][j-mid];
                if (cnt == mid*mid) {
                    b[i-mid+1][j-mid+1]++;
                    b[i-mid+1][j+1]--;
                    b[i+1][j-mid+1]--;
                    b[i+1][j+1]++;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                b[i][j] += b[i][j-1];
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                b[i][j] += b[i-1][j];
            }
        }
        bool ok = true;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (x[i-1][j-1] == 'X' && b[i][j] == 0) {
                    ok = false;
                }
            }
        }
        if (ok) st = mid;
        else en = mid;
    }
    if (st%2 == 0) st--;
    cout << st/2 << endl;
    rep(i,n+2) rep(j,m+2) ans[i][j] = 0;
    for (int i = st; i <= n; i++) {
        for (int j = st; j <= m; j++) {
            int cnt = sum[i][j]-sum[i-st][j]-sum[i][j-st]+sum[i-st][j-st];
            if (cnt == st*st) {
                ans[i-st/2][j-st/2] = 1;
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (ans[i][j]) printf("X");
            else printf(".");
        }
        puts("");
    }
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native,avx2")

#include <bits/stdc++.h>

#define ld long double
#define sf scanf
#define pf printf
#define pb push_back
#define PI ( acos(-1.0) )
#define IN freopen("input.txt","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(int i=a ; i<=b ; i++)
#define FORD(i,a,b) for(int i=a ; i>=b ; i--)
#define INF 1000000000
#define ll long long int
#define eps (1e-8)
#define sq(x) ( (x)*(x) )
#define all(x) x.begin(),x.end()
#define flog2(n) 64 - __builtin_clzll(n) - 1
#define popcnt(n) __builtin_popcountll(n)

using namespace std;

typedef pair < int, int > II;
typedef pair < ll, ll > pll;

int n, m;
vector<vector<char>> c, res, newMap;
vector<vector<int>> s, sum;

inline int max(int x, int y) {
    if (x < y) return y;
    return x;
}

inline int min(int x, int y) {
    if (x < y) return x;
    return y;
}

bool solve(int k) {
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            s[i][j] = sum[i][j] = 0;
            if (c[i][j] == '.') {
                int x1 = max(1, i - k);
                int y1 = max(1, j - k);
                int x2 = min(n, i + k);
                int y2 = min(m, j + k);
                s[x2 + 1][y2 + 1]++;
                s[x2 + 1][y1]--;
                s[x1][y2 + 1]--;
                s[x1][y1]++;
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            res[i][j] = '.';
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + s[i][j];
        }
    }
    FOR (i, k + 1, n - k) {
        FOR (j, k + 1, m - k) {
            if (!sum[i][j]) {
                res[i][j] = 'X';
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            s[i][j] = sum[i][j] = 0;
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            if (res[i][j] == 'X') {
                int x1 = max(1, i - k);
                int y1 = max(1, j - k);
                int x2 = min(n, i + k);
                int y2 = min(m, j + k);
                s[x2 + 1][y2 + 1]++;
                s[x2 + 1][y1]--;
                s[x1][y2 + 1]--;
                s[x1][y1]++;
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + s[i][j];
            if (sum[i][j]) {
                newMap[i][j] = 'X';
            }
            else {
                newMap[i][j] = '.';
            }
            if (newMap[i][j] != c[i][j]) return 0;
        }
    }

    return 1;
}

int main()
{//IN; //OUT;
    ios::sync_with_stdio(0);
    cin.tie(NULL);

    cin >> n >> m;
    c.resize(n + 1);
    res.resize(n + 1);
    newMap.resize(n + 1);
    s.resize(n + 2);
    sum.resize(n + 2);
    FOR (i, 0, n) {
        res[i].resize(m + 1);
        c[i].resize(m + 1);
        newMap[i].resize(m + 1);
    }
    FOR (i, 0, n + 1) {
        s[i].resize(m + 2);
        sum[i].resize(m + 2);
    }
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            cin >> c[i][j];
        }
    }
    int lower = 0, upper = max(m, n);
    while (lower < upper) {
        int mid = (lower + upper + 1) / 2;
        if (solve(mid)) {
            lower = mid;
        }
        else {
            upper = mid - 1;
        }
    }

    cout << lower << endl;
    solve(lower);
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            cout << res[i][j];
        }
        cout << "\n";
    }

    return 0;
}


#include <bits/stdc++.h>

#define ld long double
#define sf scanf
#define pf printf
#define pb push_back
#define PI ( acos(-1.0) )
#define IN freopen("input.txt","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(int i=a ; i<=b ; i++)
#define FORD(i,a,b) for(int i=a ; i>=b ; i--)
#define INF 1000000000
#define ll long long int
#define eps (1e-8)
#define sq(x) ( (x)*(x) )
#define all(x) x.begin(),x.end()
#define flog2(n) 64 - __builtin_clzll(n) - 1
#define popcnt(n) __builtin_popcountll(n)

using namespace std;

typedef pair < int, int > II;
typedef pair < ll, ll > pll;

int n, m;
vector<vector<char>> c, res, newMap;

bool isValid(int i, int j) {
    return (1 <= i && i <= n && 1 <= j && j <= m);
}

bool solve(int k) {
    vector<vector<ll>> s(n + 2), sum(n + 2);
    FOR (i, 0, n + 1) s[i].resize(m + 2), sum[i].resize(m + 2);

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            if (c[i][j] == '.') {
                int x1 = max(1, i - k);
                int y1 = max(1, j - k);
                int x2 = min(n, i + k);
                int y2 = min(m, j + k);
                s[x2 + 1][y2 + 1]++;
                s[x2 + 1][y1]--;
                s[x1][y2 + 1]--;
                s[x1][y1]++;
            }
        }
    }
    vector<II> pos;
    FOR (i, 1, n) FOR (j, 1, m) res[i][j] = '.';
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + s[i][j];
        }
    }
    FOR (i, k + 1, n - k) {
        FOR (j, k + 1, m - k) {
            if (!sum[i][j]) {
                pos.pb({i, j});
                res[i][j] = 'X';
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            s[i][j] = sum[i][j] = 0;
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            if (res[i][j] == 'X') {
                int x1 = max(1, i - k);
                int y1 = max(1, j - k);
                int x2 = min(n, i + k);
                int y2 = min(m, j + k);
                s[x2 + 1][y2 + 1]++;
                s[x2 + 1][y1]--;
                s[x1][y2 + 1]--;
                s[x1][y1]++;
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + s[i][j];
            if (sum[i][j]) {
                newMap[i][j] = 'X';
            }
            else {
                newMap[i][j] = '.';
            }
            if (newMap[i][j] != c[i][j]) return 0;
        }
    }

    return 1;
}

int main()
{//IN; //OUT;
    ios::sync_with_stdio(0);
    cin.tie(NULL);

    cin >> n >> m;
    c.resize(n + 1);
    res.resize(n + 1);
    newMap.resize(n + 1);
    FOR (i, 0, n) {
        res[i].resize(m + 1);
        c[i].resize(m + 1);
        newMap[i].resize(m + 1);
    }
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            cin >> c[i][j];
        }
    }
    int lower = 0, upper = max(m, n);
    while (lower < upper) {
        int mid = (lower + upper + 1) / 2;
        if (solve(mid)) {
            lower = mid;
        }
        else {
            upper = mid - 1;
        }
    }

    cout << lower << endl;
    solve(lower);
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            cout << res[i][j];
        }
        cout << "\n";
    }

    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native,avx2")

#include <bits/stdc++.h>

#define ld long double
#define sf scanf
#define pf printf
#define pb push_back
#define PI ( acos(-1.0) )
#define IN freopen("input.txt","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(int i=a ; i<=b ; i++)
#define FORD(i,a,b) for(int i=a ; i>=b ; i--)
#define INF 1000000000
#define ll long long int
#define eps (1e-8)
#define sq(x) ( (x)*(x) )
#define all(x) x.begin(),x.end()
#define flog2(n) 64 - __builtin_clzll(n) - 1
#define popcnt(n) __builtin_popcountll(n)

using namespace std;

typedef pair < int, int > II;
typedef pair < ll, ll > pll;

int n, m;
vector<vector<char>> c, res, newMap;
vector<vector<int>> s, sum;

inline int max(int x, int y) {
    if (x < y) return y;
    return x;
}

inline int min(int x, int y) {
    if (x < y) return x;
    return y;
}

bool solve(int k) {
    FOR (i, 1, n) FOR (j, 1, m) s[i][j] = sum[i][j] = 0;
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            if (c[i][j] == '.') {
                int x1 = max(1, i - k);
                int y1 = max(1, j - k);
                int x2 = min(n, i + k);
                int y2 = min(m, j + k);
                s[x2 + 1][y2 + 1]++;
                s[x2 + 1][y1]--;
                s[x1][y2 + 1]--;
                s[x1][y1]++;
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            res[i][j] = '.';
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + s[i][j];
        }
    }
    FOR (i, k + 1, n - k) {
        FOR (j, k + 1, m - k) {
            if (!sum[i][j]) {
                res[i][j] = 'X';
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            s[i][j] = sum[i][j] = 0;
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            if (res[i][j] == 'X') {
                int x1 = max(1, i - k);
                int y1 = max(1, j - k);
                int x2 = min(n, i + k);
                int y2 = min(m, j + k);
                s[x2 + 1][y2 + 1]++;
                s[x2 + 1][y1]--;
                s[x1][y2 + 1]--;
                s[x1][y1]++;
            }
        }
    }

    FOR (i, 1, n) {
        FOR (j, 1, m) {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + s[i][j];
            if (sum[i][j]) {
                newMap[i][j] = 'X';
            }
            else {
                newMap[i][j] = '.';
            }
            if (newMap[i][j] != c[i][j]) return 0;
        }
    }

    return 1;
}

int main()
{//IN; //OUT;
    ios::sync_with_stdio(0);
    cin.tie(NULL);

    cin >> n >> m;
    c.resize(n + 1);
    res.resize(n + 1);
    newMap.resize(n + 1);
    s.resize(n + 2);
    sum.resize(n + 2);
    FOR (i, 0, n) {
        res[i].resize(m + 1);
        c[i].resize(m + 1);
        newMap[i].resize(m + 1);
    }
    FOR (i, 0, n + 1) {
        s[i].resize(m + 2);
        sum[i].resize(m + 2);
    }
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            cin >> c[i][j];
        }
    }
    int lower = 0, upper = max(m, n);
    while (lower < upper) {
        int mid = (lower + upper + 1) / 2;
        if (solve(mid)) {
            lower = mid;
        }
        else {
            upper = mid - 1;
        }
    }

    cout << lower << endl;
    solve(lower);
    FOR (i, 1, n) {
        FOR (j, 1, m) {
            cout << res[i][j];
        }
        cout << "\n";
    }

    return 0;
}


#include <bits/stdc++.h>
#define fs first
#define sc second
#define mx 100005
#define mod 1000000007
#define pii pair<int, int>
#define ll long long
#define mkp make_pair
#define all(a) a.begin(),a.end()
using namespace std;

int fx[] = {-1,+1,-1,+1,+1,-1,+0,-0};
int fy[] = {-1,+1,+1,-1,+0,-0,+1,-1};
char **grid;
int **dist;
int n, m;
vector<vector<int> > dp[8];
int rec(int x, int y, int dir){
	if(x>=n || y>=m || x<0 || y<0 || grid[x][y]=='.') return -1;
	int &ret = dp[dir][x][y];
	if(ret != -1) return ret;
	int a = x+fx[dir];
	int b = y+fy[dir];
	ret = 1+rec(a,b,dir);
	return ret;
}

int main()
{
	scanf("%d %d", &n, &m);
	for(int i = 0; i<8; i++) dp[i] = vector<vector<int> > (n, vector<int>(m, -1));
	grid = (char **) malloc(n * sizeof(char *));
	dist = (int **) malloc(n * sizeof(int *));
	for(int i = 0; i<n; i++){
		grid[i] = (char *) malloc((m+1)*sizeof (char));
		dist[i] = (int *) malloc((m+1)*sizeof (int));
		scanf("%s", grid[i]);
		for(int j = 0; j<m; j++) dist[i][j] = -1;
	}

	queue<pair<int, int> > q;
	int mini = INT_MAX;
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			int c = 0;
			if(grid[i][j]=='.') continue;
			for(int k = 0; k<8; k++){
				int x = i + fx[k];
				int y = j + fy[k];
				if(x < 0 || y < 0 || x >= n || y >=m || grid[x][y]!='X') c++;
			}
			if(c){
				q.push({i, j});
				dist[i][j] = 0;
				// if(c >= 3) mini = 0;
			}
		}
	}
	while(!q.empty()){
		auto top = q.front();
		int i = top.first;
		int j = top.second;
		q.pop();
		for(int k = 0; k<8; k++){
			int x = i + fx[k];
			int y = j + fy[k];
			if(x < 0 || y < 0 || x >= n || y >=m || grid[x][y]!='X') continue;
			if(dist[x][y]==-1){
				dist[x][y] = dist[i][j] + 1;
				q.push({x, y});
			}
		}
	}
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			if(grid[i][j]=='.') continue;
			// cout << i << " " << j << " -- \n";
			for(int k = 4; k<8; k+=2){
				int a = rec(i, j, k), b = rec(i, j, k+1);
				if(a > b) swap(a, b);
				if(a == b || a+1==b) mini = min(mini, min(a, b));
			}
		}
	}
	// cout << rec(0, 2, 3) << endl;
	cout << mini << endl;
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			if(dist[i][j] >= mini) printf("X");
			else printf(".");
		}
		printf("\n");
	}

	delete grid;
	delete dist;
	return 0;
}


#include <bits/stdc++.h>
#define fs first
#define sc second
#define mx 100005
#define mod 1000000007
#define pii pair<int, int>
#define ll long long
#define mkp make_pair
#define all(a) a.begin(),a.end()
using namespace std;

int fx[] = {-1,+1,-1,+1,+1,-1,+0,-0};
int fy[] = {-1,+1,+1,-1,+0,-0,+1,-1};
char **grid;
int **dist;
int n, m;
vector<vector<int> > dp[8];
int rec(int x, int y, int dir){
	if(x>=n || y>=m || x<0 || y<0 || grid[x][y]=='.') return -1;
	int &ret = dp[dir][x][y];
	if(ret != -1) return ret;
	int a = x+fx[dir];
	int b = y+fy[dir];
	ret = 1+rec(a,b,dir);
	return ret;
}

int main()
{
	scanf("%d %d", &n, &m);
	for(int i = 0; i<8; i++) dp[i] = vector<vector<int> > (n, vector<int>(m, -1));
	grid = (char **) malloc(n * sizeof(char *));
	dist = (int **) malloc(n * sizeof(int *));
	for(int i = 0; i<n; i++){
		grid[i] = (char *) malloc((m+1)*sizeof (char));
		dist[i] = (int *) malloc((m+1)*sizeof (int));
		scanf("%s", grid[i]);
		for(int j = 0; j<m; j++) dist[i][j] = -1;
	}

	queue<pair<int, int> > q;
	int mini = INT_MAX;
	vector<pair<int, pair<int, int> > > vt;
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			int c = 0;
			if(grid[i][j]=='.') continue;
			for(int k = 0; k<8; k++){
				int x = i + fx[k];
				int y = j + fy[k];
				if(x < 0 || y < 0 || x >= n || y >=m || grid[x][y]!='X') c++;
			}
			if(c){
				q.push({i, j});
				dist[i][j] = 0;
				// if(c >= 3) mini = 0;
			}
		}
	}
	while(!q.empty()){
		auto top = q.front();
		int i = top.first;
		int j = top.second;
		q.pop();
		for(int k = 0; k<8; k++){
			int x = i + fx[k];
			int y = j + fy[k];
			if(x < 0 || y < 0 || x >= n || y >=m || grid[x][y]!='X') continue;
			if(dist[x][y]==-1){
				dist[x][y] = dist[i][j] + 1;
				q.push({x, y});
			}
		}
	}

	for(int i = 0; i<n; i++)
		for(int j = 0; j<m; j++)
			if(dist[i][j]!=-1) vt.push_back({dist[i][j], {i, j}});

	sort(vt.rbegin(), vt.rend());
	int l = 0, r = vt[0].first;
	while(l <= r){
		int mid = (l + r)/2;
		vector< int > dist2[n];
		for(int i = 0; i<n; i++)
			dist2[i] = vector<int>(m, -1);
		for(int i = 0; i<vt.size(); i++){
			if(vt[i].first >= mid) {
				q.push({vt[i].second.first, vt[i].second.second});
				dist2[vt[i].second.first][vt[i].second.second] = 0;
			}
		}
		while(!q.empty()){
			auto top = q.front();
			int i = top.first;
			int j = top.second;
			q.pop();
			for(int k = 0; k<8; k++){
				int x = i + fx[k];
				int y = j + fy[k];
				if(x < 0 || y < 0 || x >= n || y >=m) continue;
				if(dist2[x][y]==-1){
					dist2[x][y] = dist2[i][j] + 1;
					q.push({x, y});
				}
			}
		}
		int f = 0;
		for(int i = 0; i<n; i++){
			for(int j = 0; j<m; j++){
				char ch = '.';
				if(dist2[i][j]!=-1 && dist2[i][j]<=mid) ch = 'X';
				if(grid[i][j] != ch) f = 1;
			}
		}
		if(f==0) l = mid+1;
		else r = mid-1;
	}
	l--;
	cout << l << endl;

	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			if(dist[i][j] >= l) printf("X");
			else printf(".");
		}
		printf("\n");
	}

	delete grid;
	delete dist;
	return 0;
}


#include <bits/stdc++.h>
#define fs first
#define sc second
#define mx 100005
#define mod 1000000007
#define pii pair<int, int>
#define ll long long
#define mkp make_pair
#define all(a) a.begin(),a.end()
using namespace std;

int fx[] = {-1,+1,-1,+1,+1,-1,+0,-0};
int fy[] = {-1,+1,+1,-1,+0,-0,+1,-1};
char **grid;
int **dist;
int n, m;
vector<vector<int> > dp[8];
int rec(int x, int y, int dir){
	if(x>=n || y>=m || x<0 || y<0 || grid[x][y]=='.') return -1;
	int &ret = dp[dir][x][y];
	if(ret != -1) return ret;
	int a = x+fx[dir];
	int b = y+fy[dir];
	ret = 1+rec(a,b,dir);
	return ret;
}

int main()
{
	scanf("%d %d", &n, &m);
	for(int i = 0; i<8; i++) dp[i] = vector<vector<int> > (n, vector<int>(m, -1));
	grid = (char **) malloc(n * sizeof(char *));
	dist = (int **) malloc(n * sizeof(int *));
	for(int i = 0; i<n; i++){
		grid[i] = (char *) malloc((m+1)*sizeof (char));
		dist[i] = (int *) malloc((m+1)*sizeof (int));
		scanf("%s", grid[i]);
		for(int j = 0; j<m; j++) dist[i][j] = -1;
	}

	queue<pair<int, int> > q;
	int mini = INT_MAX;
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			int c = 0;
			if(grid[i][j]=='.') continue;
			for(int k = 0; k<8; k++){
				int x = i + fx[k];
				int y = j + fy[k];
				if(x < 0 || y < 0 || x >= n || y >=m || grid[x][y]!='X') c++;
			}
			if(c){
				q.push({i, j});
				dist[i][j] = 0;
				// if(c >= 3) mini = 0;
			}
		}
	}
	while(!q.empty()){
		auto top = q.front();
		int i = top.first;
		int j = top.second;
		q.pop();
		for(int k = 0; k<8; k++){
			int x = i + fx[k];
			int y = j + fy[k];
			if(x < 0 || y < 0 || x >= n || y >=m || grid[x][y]!='X') continue;
			if(dist[x][y]==-1){
				dist[x][y] = dist[i][j] + 1;
				q.push({x, y});
			}
		}
	}
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			if(grid[i][j]=='.') continue;
			// cout << i << " " << j << " -- \n";
			for(int k = 4; k<8; k+=2){
				mini = min(mini, max(rec(i, j, k), rec(i, j, k+1)));
			}
		}
	}
	// cout << rec(0, 2, 3) << endl;
	cout << mini << endl;
	for(int i = 0; i<n; i++){
		for(int j = 0; j<m; j++){
			if(dist[i][j] >= mini) printf("X");
			else printf(".");
		}
		printf("\n");
	}

	delete grid;
	delete dist;
	return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define mod 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
int n,m;

bool ok(int i,int j){
    if(i<0||i>=n)return false;
    if(j<0||j>=m)return false;
    return true;
}
class UnionFind {
private:
    int sz;
    vector<int> par, size_;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
        if(size_[x] < size_[y]) swap(x,y);
        par[y] = x;
        size_[x] += size_[y];
    }
    int size(int x){
        x = find(x);
        return size_[x];
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    vector<string>s(n);
    vector<vector<int> >d(n,vector<int>(m));
    rep(i,n)cin >> s[i];
    vector<vector<bool>> flag(n,vector<bool>(m));
    queue<pair<pair<int,int>,int> > q;
    UnionFind uf(n*m);
    rep(i,n){
        q.push(MP(MP(i,-1),0));
        q.push(MP(MP(i,m),0));
    }
    rep(j,m){
        q.push(MP(MP(-1,j),0));
        q.push(MP(MP(n,j),0));
    }
    rep(i,n){
        rep(j,m){
            if(s[i][j]=='.'){
                flag[i][j] = true;
                q.push(MP(MP(i,j),0));
            }
        }
    }
    while(!q.empty()){
        auto x = q.front();
        q.pop();
        int i = x.first.first;
        int j = x.first.second;
        int t = x.second;
        if(ok(i,j))d[i][j] = t;
        for(int di=-1;di<=1;di++){
            for(int dj=-1;dj<=1;dj++){
                if(ok(i+di,j+dj)){
                    if(ok(i,j)&&(di==0||dj==0)&&s[i][j]=='X'&&s[i+di][j+dj]=='X'){
                        uf.unite(i*m+j,(i+di)*m+j+dj);
                    }
                    if(!flag[i+di][j+dj]){
                        flag[i+di][j+dj] = true;
                        q.push(MP(MP(i+di,j+dj),t+1));
                    }
                }
            }
        }
    }
    vector<int> res(n*m,-1);
    rep(i,n){
        rep(j,m){
            if(s[i][j]=='X'){
                int K = uf.find(i*m+j);
                res[K] = max(d[i][j],res[K]);
            }
        }
    }
    int p = inf;
    rep(i,n*m){
        if(res[i]!=-1){
            p = min(res[i],p);
        }
    }
    cout << p-1 << endl;
    rep(i,n){
        rep(j,m){
            if(s[i][j]=='X'&&d[i][j]>=p){
                cout << 'X';
            }else{
                cout << '.';
            }
        }
        cout << "\n";
    }
    return 0;
}