The Berland Forest can be represented as an infinite cell plane. Every cell contains a tree. That is, contained before the recent events.

A destructive fire raged through the Forest, and several trees were damaged by it. Precisely speaking, you have a n × m rectangle map which represents the damaged part of the Forest. The damaged trees were marked as "X" while the remaining ones were marked as ".". You are sure that all burnt trees are shown on the map. All the trees outside the map are undamaged.

The firemen quickly extinguished the fire, and now they are investigating the cause of it. The main version is that there was an arson: at some moment of time (let's consider it as 0) some trees were set on fire. At the beginning of minute 0, only the trees that were set on fire initially were burning. At the end of each minute, the fire spread from every burning tree to each of 8 neighboring trees. At the beginning of minute T, the fire was extinguished.

The firemen want to find the arsonists as quickly as possible. The problem is, they know neither the value of T (how long the fire has been raging) nor the coordinates of the trees that were initially set on fire. They want you to find the maximum value of T (to know how far could the arsonists escape) and a possible set of trees that could be initially set on fire.

Note that you'd like to maximize value T but the set of trees can be arbitrary.

Input

The first line contains two integer n and m (1 ≤ n, m ≤ 10^6, 1 ≤ n ⋅ m ≤ 10^6) — the sizes of the map.

Next n lines contain the map. The i-th line corresponds to the i-th row of the map and contains m-character string. The j-th character of the i-th string is "X" if the corresponding tree is burnt and "." otherwise.

It's guaranteed that the map contains at least one "X".

Output

In the first line print the single integer T — the maximum time the Forest was on fire. In the next n lines print the certificate: the map (n × m rectangle) where the trees that were set on fire are marked as "X" and all other trees are marked as ".".

Examples

Input


3 6
XXXXXX
XXXXXX
XXXXXX


Output


1
......
.X.XX.
......


Input


10 10
.XXXXXX...
.XXXXXX...
.XXXXXX...
.XXXXXX...
.XXXXXXXX.
...XXXXXX.
...XXXXXX.
...XXXXXX.
...XXXXXX.
..........


Output


2
..........
..........
...XX.....
..........
..........
..........
.....XX...
..........
..........
..........


Input


4 5
X....
..XXX
..XXX
..XXX


Output


0
X....
..XXX
..XXX
..XXX
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.stream.Collectors;

/**
 * https://codeforces.com/contest/1261/problem/C
 */
public class TaskC {
    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 m = in.nextInt();
        char[][] forest = new char[n][];
        for(int i=0;i<n;i++){
            forest [i] =  in.next().toCharArray();
        }
        Solution sol = new Solution(forest);
        sol.bfs();
        sol.checkSolution(out);
        out.close();
        in.close();
    }
    public static class Solution {
        private final char [][] forest;
        private final Map<Integer,List<int[]>> pA = new HashMap<>();
        private final int[][] mem;

        public Solution(char [][] forest){
            this.forest=forest;
            mem = new int[forest.length][forest[0].length];
        }

        public  void bfs() {

            for(int i=0;i<mem.length;i++){
                for(int j=0;j<mem[i].length;j++){
                    if(forest[i][j]=='.') {
                        mem[i][j] = -1;
                    }
                }
            }

            Queue<int[]> toVisit = new LinkedList<>();
            for (int i = 0; i < forest.length; i++) {
                for (int j = 0; j < forest[i].length; j++) {
                    if (forest[i][j]=='X' && border(i, j)) {
                        toVisit.add(new int[]{i, j});
                        mem[i][j]=1;
                        addToMap(1,new int[]{i,j});
                    }
                }
            }

            while(!toVisit.isEmpty()){
                int [] point = toVisit.poll();
                List<int[]> notVisited = notVisited(point[0],point[1],mem);
                for(int[]p:notVisited){
                    mem[p[0]][p[1]]=mem[point[0]][point[1]]+1;
                    toVisit.add(p);
                    addToMap(mem[p[0]][p[1]], p);
                }
            }

        }

        public void checkSolution(PrintWriter out){
            int[] keys = pA.keySet().stream().sorted().mapToInt(i->i).toArray();

            int h = 0;
            int l = 0;
            h = keys.length - 1;
            int m = (l + h + 1) / 2;
            while (l != h) {
                int key = keys[m];
                if (runFireBFS(key)) {
                    l = m;
                } else {
                    h = m - 1;
                }
                m = (l + h + 1) / 2;
            }
            printAnsw(keys[h], out);
            return;
        }

        public void printAnsw(int key, PrintWriter out){
            char[][] iF = new char[forest.length][forest[0].length];
            for(int x=0;x<iF.length;x++){
                for(int y=0;y<iF[x].length;y++){
                    iF[x][y]='.';
                    if(mem[x][y]>=key){
                        iF[x][y]='X';
                    }
                }
            }
            out.printf("%d%n",key-1);
            for(int x=0;x<iF.length;x++){
                out.println(String.valueOf(iF[x]));
            }
        }

        public boolean runFireBFS(int key){
            Queue<int[]> q = new LinkedList<>();
            //init
            int step = 1;
            int [][] m = new int[forest.length][forest[0].length];
           for(int i=0;i<mem.length;i++){
               for(int j=0;j<mem[i].length;j++) {
                   if(mem[i][j]>=key) {
                       int x = i;
                       int y = j;
                       q.add(new int[]{step, x, y});
                       m[i][j] = 1;
                   }
               }
           }

           while(!q.isEmpty()&&step<=key){
              int [] fire = q.poll();
              step=fire[0];
              m[fire[1]][fire[2]]=step;
              List<int[]> spred = spredFire(fire[1],fire[2],m);
              for(int[] nF:spred){
                 int x = nF[0];
                 int y = nF[1];
                 int nS=step+1;
                 if(nS<=key) {
                     if (forest[x][y] == '.') {
                         return false;
                     }
                     m[x][y]=nS;
                     q.add(new int[]{nS, x, y});
                 }
              }
           }

           for(int i=0;i<forest.length;i++){
               for(int j=0;j<forest[i].length;j++){
                   if(m[i][j]==0 &&forest[i][j]=='X'){
                      return false;
                   }
                   if(m[i][j]!=0&&forest[i][j]=='.'){
                       return false;
                   }
               }
           }
           return true;
        }

        private List<int[]> spredFire(int x, int y, int[][] mem) {
            List<int[]> result = new ArrayList<>();
            for(int i=x-1;i<=x+1;i++){
                if(i<0){continue;}
                if(i>=mem.length){continue;}
                for(int j=y-1;j<=y+1;j++){
                    if(j<0){continue;}
                    if(j>=mem[i].length){continue;}
                    if(mem[i][j]!=0){
                        continue;
                    }
                    result.add(new int[]{i,j});
                }
            }
            return result;
        }

        public void addToMap(int key, int[] point) {
            List<int[]> points = pA.get(key);
            if(points==null){
                points = new ArrayList<>();
                pA.put(key,points);
            }
            points.add(point);
        }

        private List<int[]> notVisited(final int x, final int y, int [][] mem){
            List<int[]> result = new LinkedList<>();
            for(int i=x-1;i<=x+1;i++){
                if(i<0){continue;}
                if(i>=mem.length){
                    continue;
                }
                for(int j=y-1;j<=y+1;j++){
                    if(j<0){continue;}
                    if(j>=mem[i].length){continue;}
                    if(mem[i][j]==0){
                        result.add(new int[]{i,j});
                    }
                }
            }
            return result;
        }

        private boolean border(final int x, final int y){
            for(int i=x-1;i<=x+1;i++){
                if(i<0) {return true;}
                if(i>=forest.length){return true;}
                for(int j=y-1;j<=y+1;j++){
                    if(j<0){return true;}
                    if(j>=forest[i].length){return true;}
                    if(forest[i][j]=='.'){
                        return true;
                    }
                }
            }
            return false;
        }

    }
    private static void printMatrix(int [][] forest){
        for(int i=0;i<forest.length;i++){
            for(int j=0;j<forest[i].length;j++){
                System.out.printf("%3d",forest[i][j]);
            }
            System.out.printf("%n");
        }
    }



    private static void printMatrix(char [][] forest){
        for(int i=0;i<forest.length;i++){
            for(int j=0;j<forest[i].length;j++){
                System.out.printf("%c",forest[i][j]);
            }
            System.out.printf("%n");
        }
    }

    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());
        }

    }

}
