#include <bits/stdc++.h>
using namespace std;
const int dir[][2] = {{-1, 0}, {0, 1},  {1, 0},  {0, -1},
                      {1, 1},  {1, -1}, {-1, 1}, {-1, -1}};
char grid[100][100];
int match[100][100];
int placed[100][100];
int oneans[100][100];
int used[10];
int dom[100][100];
int order[100][100];
void place(int r, int c, int d) {
  for (int x = 0; x < (2); ++x)
    for (int y = 0; y < (2); ++y) placed[r + x][c + y] = d;
}
bool CanPlace(int r, int c, int delta) {
  int t;
  bool res = true;
  for (int x = 0; x < (2); ++x)
    for (int y = 0; y < (2); ++y)
      if (-1 != (t = match[r + x][c + y])) {
        assert(-1 != placed[x + r + dir[t][0]][y + c + dir[t][1]]);
        int a = placed[r + x][c + y];
        int b = placed[r + x + dir[t][0]][y + c + dir[t][1]];
        if (dom[a][b]) res = false;
        dom[a][b] += delta;
        dom[b][a] += delta;
      }
  return res;
}
int gFirst = true;
int DFS(int r, int c, int n, int m) {
  if (c > m) c = 1, r++;
  if (r > n) {
    if (gFirst) memcpy(oneans, placed, sizeof(placed));
    gFirst = false;
    return 1;
  }
  if (grid[r][c] == '.' || placed[r][c] != -1) return DFS(r, c + 1, n, m);
  int res = 0;
  int single = 0;
  int single_cnt = 0;
  for (int i = 0; i < (7); ++i) {
    int t = 0;
    bool can = false;
    bool first = false;
    if (used[i] == 2) continue;
    if (used[i] == 0) {
      single++;
      can = single == 1;
      first = true;
    } else if (used[i] == 1) {
      can = true;
    } else {
      assert(0);
    }
    if (can) {
      place(r, c, i);
      if (CanPlace(r, c, 1)) {
        used[i]++;
        t = DFS(r, c + 1, n, m);
        used[i]--;
        if (!first)
          res += t;
        else
          single_cnt = t;
      }
      CanPlace(r, c, -1);
      place(r, c, -1);
    }
  }
  res += single_cnt * single;
  return res;
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < (n); ++i) cin >> (grid[i + 1] + 1);
  memset(match, 0xff, sizeof(match));
  int top = 1;
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (m); ++j)
      if (grid[i + 1][j + 1] != '.' && order[i + 1][j + 1] == 0) {
        for (int x = 0; x < (2); ++x)
          for (int y = 0; y < (2); ++y) {
            assert(0 == order[i + 1 + x][j + 1 + y]);
            order[i + 1 + x][j + 1 + y] = top++;
          }
      }
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (m); ++j)
      if (grid[i + 1][j + 1] != '.')
        for (int d = 0; d < (4); ++d)
          if (order[i + 1][j + 1] >
                  order[i + 1 + dir[d][0]][j + 1 + dir[d][1]] &&
              grid[i + 1][j + 1] ==
                  grid[i + 1 + dir[d][0]][j + 1 + dir[d][1]]) {
            match[i + 1][j + 1] = d;
          }
  memset(placed, 0xff, sizeof(placed));
  cout << DFS(1, 1, n, m) << endl;
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (m); ++j) {
      char ch = oneans[i + 1][j + 1] == -1 ? '.' : oneans[i + 1][j + 1] + '0';
      cout << ch;
      if (j + 1 == m) cout << endl;
    }
  return 0;
}
