#include <iostream>
#include <vector>
#include <array>

using namespace std;

bool isValid(int x, int y, int n, int m);

int countMines(const vector<string>& matrix, int x, int y, int n, int m);

int main() {
    int n, m;
    cin >> n >> m;

    vector<string> matrix(n);
    for (int i = 0; i < n; ++i) {
        cin >> matrix[i];
    }

    vector<vector<char>> minesweeper(n, vector<char>(m, ' '));

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (matrix[i][j] == '*') {
                minesweeper[i][j] = '*';
            } else {
                minesweeper[i][j] = '0' + countMines(matrix, i, j, n,
                                                     m); // 将数字转换为字符表示
            }
        }
    }

    // 输出扫雷矩阵
    for (const auto& row : minesweeper) {
        for (char c : row) {
            cout << c;
        }
        cout << endl;
    }

    return 0;
}

// 检查坐标是否在矩阵范围内内
bool isValid(int x, int y, int n, int m) {
    return x >= 0 && x < n && y >= 0 && y < m;
}

// 计算给定位置周围的雷数
int countMines(const vector<string>& matrix, int x, int y, int n, int m) {
    int count = 0;
    // 八个方向的偏移量
    array<int, 8> dx = {-1, -1, -1, 0, 0, 1, 1, 1};
    array<int, 8> dy = {-1, 0, 1, -1, 1, -1, 0, 1};

    for (int i = 0; i < 8; ++i) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (isValid(nx, ny, n, m) && matrix[nx][ny] == '*') {
            ++count;
        }
    }
    return count;
}