#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
inline ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <typename T, size_t N>
inline ostream &operator<<(ostream &os, const array<T, N> &a) {
  os << "[";
  int cnt = 0;
  for (auto &val : a) {
    if (cnt++) os << ", ";
    os << val;
  }
  os << "]";
  return os;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "]";
}
template <typename T>
inline ostream &operator<<(ostream &os, const set<T> &v) {
  os << "{";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "}";
}
template <typename T>
inline ostream &operator<<(ostream &os, const unordered_set<T> &v) {
  os << "{";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "}";
}
template <typename T>
inline ostream &operator<<(ostream &os, const multiset<T> &v) {
  os << "{";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "}";
}
template <typename T1, typename T2>
inline ostream &operator<<(ostream &os, const map<T1, T2> &v) {
  os << "[";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "]";
}
template <typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}
using ll = long long;
using ull = unsigned long long;
using vi = vector<int>;
using vll = vector<long long>;
using vvi = vector<vector<int>>;
using vs = vector<string>;
using vb = vector<bool>;
using vd = vector<double>;
using vvb = vector<vector<bool>>;
using vvc = vector<vector<char>>;
using vc = vector<char>;
using si = set<int>;
using mpii = map<int, int>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const char nl = '\n';
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template <class T>
inline bool umin(T &a, const T b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
inline bool umax(T &a, const T b) {
  return a < b ? a = b, 1 : 0;
}
int n, m;
void solve() {
  vvc a(n, vc(m));
  for (int i = 0; i < (n); i++)
    for (int j = 0; j < (m); j++) cin >> a[i][j];
  int nodes = n * m;
  vvi g(nodes, vi());
  for (int i = 1; i < n - 1; i++) {
    for (int j = 1; j < m - 1; j++) {
      if (a[i][j] == 'X') {
        vi neis;
        for (int k = 0; k < (4); k++) {
          int x = i + dx[k];
          int y = j + dy[k];
          if (a[x][y] == '.') {
            neis.emplace_back(x * m + y);
          }
        }
        int cnt = ((int)(neis).size());
        if (cnt & 1) {
          cout << "NO" << nl;
          return;
        }
        if (cnt == 2) {
          g[neis[0]].emplace_back(neis[1]);
          g[neis[1]].emplace_back(neis[0]);
        } else if (cnt == 4) {
          for (int k = 0; k < (cnt); k++) {
            g[neis[k]].emplace_back(neis[(k + 1) % cnt]);
            g[neis[(k + 1) % cnt]].emplace_back(neis[k]);
          }
        }
      }
    }
  }
  function<bool(int, int, char)> dfs = [&](int u, int fa, char c) -> bool {
    a[u / m][u % m] = c;
    char nc = (c == '1' ? '4' : '1');
    for (int v : g[u]) {
      if (v == fa) continue;
      if (a[v / m][v % m] == c) return false;
      if (a[v / m][v % m] == '.') {
        if (!dfs(v, u, nc)) return false;
      }
    }
    return true;
  };
  for (int i = 0; i < (n); i++)
    for (int j = 0; j < (m); j++) {
      if (a[i][j] == '.') {
        if (!dfs(i * m + j, -1, '1')) {
          cout << "NO" << nl;
          return;
        }
      }
    }
  cout << "YES" << nl;
  for (int i = 0; i < (n); i++)
    for (int j = 0; j < (m); j++) {
      if (a[i][j] == 'X') {
        int cnt = 0;
        for (int k = 0; k < (4); k++) {
          int x = i + dx[k];
          int y = j + dy[k];
          if (a[x][y] != 'X') cnt++;
        }
        cout << 5 * cnt / 2;
      } else {
        cout << a[i][j];
      }
      cout << " \n"[j == m - 1];
    }
}
void solve(int _cas) { solve(); }
int main() {
  srand(time(NULL));
  ios_base::sync_with_stdio(false);
  cin.tie(NULL), cout.tie(NULL), cout.precision(12);
  while (cin >> n >> m) solve(1);
}

### Prompt

Please create a solution in CPP to the following problem:

Alice has an empty grid with n rows and m columns. Some of the cells are marked, and no marked cells are adjacent to the edge of the grid. (Two squares are adjacent if they share a side.) 

Alice wants to fill each cell with a number such that the following statements are true: 

  * every unmarked cell contains either the number 1 or 4; 
  * every marked cell contains the sum of the numbers in all unmarked cells adjacent to it (if a marked cell is not adjacent to any unmarked cell, this sum is 0); 
  * every marked cell contains a multiple of 5. 

Alice couldn't figure it out, so she asks Bob to help her. Help Bob find any such grid, or state that no such grid exists.

Input

The first line of input contains two integers n and m (1 ≤ n, m ≤ 500) — the number of rows and the number of columns in the grid, respectively.

Then n lines follow, each containing m characters. Each of these characters is either '.' or 'X' — an unmarked and a marked cell, respectively. No marked cells are adjacent to the edge of the grid.

Output

Output "'NO" if no suitable grid exists. Otherwise, output "'YES"'. Then output n lines of m space-separated integers — the integers in the grid.

Examples

Input


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


Output


YES
4 1 4 4 1
4 5 5 5 1
4 5 1 5 4
1 5 5 5 4
1 4 4 1 4


Input


5 5
.....
.XXX.
.XXX.
.XXX.
.....


Output


NO


Input


3 2
..
..
..


Output


YES
4 1
4 1
1 4


Input


9 9
.........
.XXXXX.X.
.X...X...
.X.XXXXX.
.X.X.X.X.
.X.XXX.X.
.X.....X.
.XXXXXXX.
.........


Output


YES
4 4 4 1 4 1 4 1 4
1 5 5 5 5 5 4 10 1
4 5 1 4 1 5 4 4 4
4 5 1 5 5 0 5 5 1
4 5 1 5 4 5 1 5 4
4 5 1 5 5 5 4 5 1
1 5 4 4 1 1 4 5 1
4 5 5 5 5 5 5 5 4
1 1 1 1 4 4 1 1 4

Note

It can be shown that no such grid exists for the second test.

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
inline ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
template <typename T, size_t N>
inline ostream &operator<<(ostream &os, const array<T, N> &a) {
  os << "[";
  int cnt = 0;
  for (auto &val : a) {
    if (cnt++) os << ", ";
    os << val;
  }
  os << "]";
  return os;
}
template <typename T>
inline ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "]";
}
template <typename T>
inline ostream &operator<<(ostream &os, const set<T> &v) {
  os << "{";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "}";
}
template <typename T>
inline ostream &operator<<(ostream &os, const unordered_set<T> &v) {
  os << "{";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "}";
}
template <typename T>
inline ostream &operator<<(ostream &os, const multiset<T> &v) {
  os << "{";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "}";
}
template <typename T1, typename T2>
inline ostream &operator<<(ostream &os, const map<T1, T2> &v) {
  os << "[";
  int cnt = 0;
  for (auto &val : v) {
    if (cnt++) os << ", ";
    os << val;
  }
  return os << "]";
}
template <typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}
using ll = long long;
using ull = unsigned long long;
using vi = vector<int>;
using vll = vector<long long>;
using vvi = vector<vector<int>>;
using vs = vector<string>;
using vb = vector<bool>;
using vd = vector<double>;
using vvb = vector<vector<bool>>;
using vvc = vector<vector<char>>;
using vc = vector<char>;
using si = set<int>;
using mpii = map<int, int>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const char nl = '\n';
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template <class T>
inline bool umin(T &a, const T b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
inline bool umax(T &a, const T b) {
  return a < b ? a = b, 1 : 0;
}
int n, m;
void solve() {
  vvc a(n, vc(m));
  for (int i = 0; i < (n); i++)
    for (int j = 0; j < (m); j++) cin >> a[i][j];
  int nodes = n * m;
  vvi g(nodes, vi());
  for (int i = 1; i < n - 1; i++) {
    for (int j = 1; j < m - 1; j++) {
      if (a[i][j] == 'X') {
        vi neis;
        for (int k = 0; k < (4); k++) {
          int x = i + dx[k];
          int y = j + dy[k];
          if (a[x][y] == '.') {
            neis.emplace_back(x * m + y);
          }
        }
        int cnt = ((int)(neis).size());
        if (cnt & 1) {
          cout << "NO" << nl;
          return;
        }
        if (cnt == 2) {
          g[neis[0]].emplace_back(neis[1]);
          g[neis[1]].emplace_back(neis[0]);
        } else if (cnt == 4) {
          for (int k = 0; k < (cnt); k++) {
            g[neis[k]].emplace_back(neis[(k + 1) % cnt]);
            g[neis[(k + 1) % cnt]].emplace_back(neis[k]);
          }
        }
      }
    }
  }
  function<bool(int, int, char)> dfs = [&](int u, int fa, char c) -> bool {
    a[u / m][u % m] = c;
    char nc = (c == '1' ? '4' : '1');
    for (int v : g[u]) {
      if (v == fa) continue;
      if (a[v / m][v % m] == c) return false;
      if (a[v / m][v % m] == '.') {
        if (!dfs(v, u, nc)) return false;
      }
    }
    return true;
  };
  for (int i = 0; i < (n); i++)
    for (int j = 0; j < (m); j++) {
      if (a[i][j] == '.') {
        if (!dfs(i * m + j, -1, '1')) {
          cout << "NO" << nl;
          return;
        }
      }
    }
  cout << "YES" << nl;
  for (int i = 0; i < (n); i++)
    for (int j = 0; j < (m); j++) {
      if (a[i][j] == 'X') {
        int cnt = 0;
        for (int k = 0; k < (4); k++) {
          int x = i + dx[k];
          int y = j + dy[k];
          if (a[x][y] != 'X') cnt++;
        }
        cout << 5 * cnt / 2;
      } else {
        cout << a[i][j];
      }
      cout << " \n"[j == m - 1];
    }
}
void solve(int _cas) { solve(); }
int main() {
  srand(time(NULL));
  ios_base::sync_with_stdio(false);
  cin.tie(NULL), cout.tie(NULL), cout.precision(12);
  while (cin >> n >> m) solve(1);
}

```