#include <stdio.h>
#include <vector>
#include <algorithm>
#include <set>

int init_broj_praznih = 0;
int n, m;
char mat[10][11];
char nmat[10][11];
struct polje
{
	int y; int x; bool zauzeto;
};
struct pozicija
{
	int br_topova;
	std::vector<polje> polja;
	std::vector<std::pair<int,int>> povezana_polja;//prvo iterator polja pa pozicije
};
std::set<std::pair<int, int>> krajnje_koord;
std::vector<pozicija> moguce_poz;
std::vector<pozicija> krajnje_poz;

int saberi_po_x(std::pair<int,int> p1)
{
	int sum = 0;
	int y = p1.second;
	for (int i = p1.first+1; i < m; i++)
	{
		if (mat[y][i] == '#' || (mat[y][i] <= '4' && mat[y][i] >= '0'))
			break;
		else
		{
			sum++;
			nmat[y][i] = 'X';
		}
	}
	for (int i = p1.first-1; i >= 0; i--)
	{
		if (mat[y][i] == '#' || (mat[y][i] <= '4' && mat[y][i] >= '0'))
			break;
		else
		{
			sum++;
			nmat[y][i] = 'X';
		}
	}
	return sum;
}
int saberi_po_y(std::pair<int,int> p1)
{
	int sum = 0;
	int x = p1.first;
	for (int i = p1.second; i < n; i++)
	{
		if (mat[i][x] == '#' || (mat[i][x] <= '4' && mat[i][x] >= '0'))
			break;
		else
		{
			sum++;
			nmat[i][x] = 'X';
		}
	}
	for (int i = p1.second-1; i >= 0; i--)
	{
		if (mat[i][x] == '#' || (mat[i][x] <= '4' && mat[i][x] >= '0'))
			break;
		else
		{
			sum++;
			nmat[i][x] = 'X';
		}
	}
	return sum;
}

void print_mat()
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= m; j++)
		{
			if (mat[i][j] == 'x')
				printf(".");
			else
			printf("%c", mat[i][j]);
		}
	}
}

bool pokrivaju_sva_polja()
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 11; j++)
		{
			nmat[i][j] = mat[i][j];
		}
	}
	int count = 0;
	for (int i = 0; i < krajnje_poz.size(); i++)
	{
		for (int j = 0; j < krajnje_poz[i].polja.size(); j++)
		{
			if (krajnje_poz[i].polja[j].zauzeto)
			{
				krajnje_koord.insert(std::make_pair(krajnje_poz[i].polja[j].x, krajnje_poz[i].polja[j].y));
			}
		}
	}
	for each (std::pair<int,int> var in krajnje_koord)
	{
		saberi_po_x(var);
		saberi_po_y(var);
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (nmat[i][j] == 'X')
			{
				count++;
			}
		}
	}
	if (count < init_broj_praznih)
	{
		return false;
	}
}


bool dal_se_dva_tuku(polje p1,polje p2)
{
	if (p1.zauzeto && p2.zauzeto)
	{
		if ((p1.x == p2.x) || (p1.y == p2.y))
		{
			if ((p1.x == p2.x) && (p1.y == p2.y))
			{
				return false;
			}
			if (p1.y == p2.y)
			{
				int dX = 0;
				if (p2.x > p1.x)
					dX = 1;
				else
					dX = -1;
				for (int i = p1.x; i != p2.x; i+=dX)
				{
					if (mat[p1.y][i] == '#' || (mat[p1.y][i] <= '4' && mat[p1.y][i] >= '0'))
					{
						return false;
					}
				}
			}
			else
			{
				int dY = 0;
				if (p2.y > p1.y)
					dY = 1;
				else
					dY = -1;
				for (int i = p1.y; i != p2.y; i += dY)
				{
					if (mat[i][p1.x] == '#' || (mat[i][p1.x] <= '4' && mat[i][p1.x] >= '0'))
					{
						return false;
					}
				}
			}
			return true;
		}
		else
			return false;
	}
	else
		return false;
}

void postavi_polje(pozicija* poz,int it,bool punjenje,std::vector<pozicija> *sve_poz)
{
	for (int i = 0; i < poz->povezana_polja.size(); i++)
	{
		if ((poz->polja[it].x == sve_poz->at(poz->povezana_polja[i].second).polja[poz->povezana_polja[i].first].x) && (poz->polja[it].y == sve_poz->at(poz->povezana_polja[i].second).polja[poz->povezana_polja[i].first].y))
		{
			polje* nptr_polje = &sve_poz->at(poz->povezana_polja[i].second).polja[poz->povezana_polja[i].first];
			pozicija* nptr_poz = &sve_poz->at(poz->povezana_polja[i].second);
			if (punjenje == true)
			{
				*nptr_polje = { nptr_polje->y,nptr_polje->x,punjenje };
				int broj_top = nptr_poz->br_topova;
				*nptr_poz = { broj_top - 1,nptr_poz->polja,nptr_poz->povezana_polja };
			}
			else if (nptr_polje->zauzeto)
			{
				*nptr_polje = { nptr_polje->y,nptr_polje->x,punjenje };
				*nptr_poz = { nptr_poz->br_topova + 1,nptr_poz->polja,nptr_poz->povezana_polja };
			}
		}
	}
	if (punjenje == true)
		*poz = { poz->br_topova-1,poz->polja,poz->povezana_polja };
	else if(poz->polja[it].zauzeto)
		*poz = {poz->br_topova+1,poz->polja,poz->povezana_polja};
	polje* npolje = &poz->polja[it];
	*npolje = {npolje->y,npolje->x, punjenje };
}

void napuni(pozicija* poz,bool punjenje,std::vector<pozicija> *sve_poz)
{

	for (int i = 0; i < poz->polja.size(); i++)
	{
		postavi_polje(poz,i, punjenje,sve_poz);
	}


}
bool dal_se_biju(std::vector<pozicija> sve_poz)
{
	for (int i = 0; i < sve_poz.size(); i++)
	{
		for (int j = 0; j < sve_poz.size(); j++) //Mozda se nesto zajebe ovde oko i+1
		{
			pozicija t0 = sve_poz[i];
			pozicija t1 = sve_poz[j];
			if (t0.br_topova < 0 || t1.br_topova < 0)
			{
				return true;
			}
			for (int k = 0; k < t0.polja.size(); k++)
			{
				for (int l = 0; l < t1.polja.size(); l++)
				{
					polje p0 = t0.polja[k];
					polje p1 = t1.polja[l];
					if (dal_se_dva_tuku(p0, p1))
						return true;
				}
			}
		}
	}
	
	return false;
}
bool sve_cisto(std::pair<int,int> p1,std::pair<int,int> p2)
{
	if (p1.first == p2.first)
	{
		int dY = 0;
		if (p1.second < p2.second)
			dY = 1;
		else
			dY = -1;
		for (int i = p1.second; i != p2.second ; i+=dY)
		{
			if (nmat[i][p1.first] == '#' || (nmat[i][p1.first] <= '4' && nmat[i][p1.first] >= '0')) 
				return false;
		}
		return true;
	}
	else
	{
		int dX = 0;
		if (p1.first < p2.first)
			dX = 1;
		else
			dX = -1;
		for (int i = p1.second; i != p2.second; i += dX)
		{
			if (nmat[p1.second][i] == '#' || (nmat[p1.second][i] <= '4' && nmat[p1.second][i] >= '0'))
				return false;
		}
		return true;
	}
}

std::vector<std::pair<int, int>> nadji_prazna(char matrica[10][11])
{
	std::vector<std::pair<int, int>> prazna;
	for (int i = n-1; i >= 0; i--)
	{
		for (int j = m-2; j >= 0; j--)
		{
			if (matrica[i][j] == '.')
			{
				prazna.push_back(std::make_pair(j, i));
			}
		}
	}
	return prazna;
}
bool polja_GO()
{
	if (!pokrivaju_sva_polja())
	{
		std::vector<std::pair<int, int>> prazna_polja = nadji_prazna(nmat);
		for (int i = 0; i < prazna_polja.size(); i++)
		{
			std::pair<int, int> polje = prazna_polja[i];
			if ((nmat[polje.second][polje.first + 1] > '4' || nmat[polje.second][polje.first + 1] < '0') &&
				(nmat[polje.second][polje.first - 1] > '4' || nmat[polje.second][polje.first - 1] < '0') &&
				(nmat[polje.second + 1][polje.first] > '4' || nmat[polje.second + 1][polje.first] < '0') &&
				(nmat[polje.second - 1][polje.first] > '4' || nmat[polje.second - 1][polje.first] < '0'))
			{
				mat[polje.second][polje.first] = 'C';
				for (int j = 0; j < prazna_polja.size(); j++)
				{
					std::pair<int, int> pp = prazna_polja[j];
					if ((pp.first == polje.first || pp.second == polje.second) && sve_cisto(pp, polje))
					{
						nmat[pp.second][pp.first] = 'X';
						prazna_polja.erase(prazna_polja.begin() + j);
						j--;
					}
				}
			}

		}
		if (prazna_polja.size() > 0)
			return false;
	}
	return true;
}

bool metnitopa(std::vector<pozicija> moguce_pozicije,int it)
{
	pozicija* poz = &moguce_pozicije[it];
	if (poz->br_topova > poz->polja.size())
		return false;
	
	if (poz->br_topova == 4)
	{
		napuni(poz, true, &moguce_pozicije);
		if (dal_se_biju(moguce_pozicije))
			return false;
		else
		{
			if (it == moguce_pozicije.size() - 1 && polja_GO())
			{

				krajnje_poz.push_back(*poz);
				return true;
			}
			bool mt = metnitopa(moguce_pozicije, it + 1);
			if (mt)
			{
				krajnje_poz.push_back(*poz);
				return true;
			}
			else 
			{
				return false;
			}
		}
		napuni(poz, false, &moguce_pozicije);
	}
	else if (poz->br_topova == 3)
	{
		for (int i = 0; i < poz->polja.size(); i++)
		{
			napuni(poz, true, &moguce_pozicije);
			postavi_polje(poz, i, false, &moguce_pozicije);
			if (!dal_se_biju(moguce_pozicije))
			{
				krajnje_poz.push_back(*poz);
				if (it == moguce_pozicije.size() - 1 && polja_GO())
				{
					return true;
				}
				bool mt = metnitopa(moguce_pozicije, it + 1);
				if (mt)
				{
					return true;
				}
				else if (i >= poz->polja.size() - 1)
				{
					return false;
				}
				else
				{
					krajnje_poz.erase(krajnje_poz.begin()+it);
				}
			}
			napuni(poz, false, &moguce_pozicije);
		}
	}
	else if (poz->br_topova == 2)
	{
		for (int i = 0; i < poz->polja.size(); i++)
		{
			for (int j = i+1; j < poz->polja.size(); j++)
			{
				napuni(poz, false, &moguce_pozicije);
				postavi_polje(poz, i, true, &moguce_pozicije);
				postavi_polje(poz, j, true, &moguce_pozicije);
				if (!dal_se_biju(moguce_pozicije))
				{
					krajnje_poz.push_back(*poz);
					if (it == moguce_pozicije.size() - 1 && polja_GO())
					{
						return true;
					}
					bool mt = metnitopa(moguce_pozicije, it + 1);
					if (mt)
					{

						return true;
					}
					else if (i >= poz->polja.size() - 1)
					{
						return false;
					}
					else
					{
						krajnje_poz.erase(krajnje_poz.begin() + it);
					}
				}
				napuni(poz, false, &moguce_pozicije);
			}
		}
	}
	else if(poz->br_topova == 1)
	{
		for (int i = 0; i < poz->polja.size(); i++)
		{
			napuni(poz, false, &moguce_pozicije);
			postavi_polje(poz, i, true, &moguce_pozicije);
			if (!dal_se_biju(moguce_pozicije))
			{
				krajnje_poz.push_back(*poz);
				if (it == moguce_pozicije.size()-1 && polja_GO())
				{
					return true;
				}
				bool mt = metnitopa(moguce_pozicije, it + 1);
				if (mt)
				{
					return true;
				}
				else if (i >= poz->polja.size()-1)
				{
					return false;
				}
				else
				{
					krajnje_poz.erase(krajnje_poz.begin() + it);
				}

			}
			napuni(poz, false,&moguce_pozicije);
		}
	}
	else
	{
		if (!dal_se_biju(moguce_pozicije))
		{
			krajnje_poz.push_back(*poz);
			bool mt = metnitopa(moguce_pozicije, it + 1);
			if (mt)
			{
				return true;
			}
			else
			{
				krajnje_poz.erase(krajnje_poz.begin() + it);
				return false;
			}
		}
	}
	return false;
}



int main()
{

	scanf("%d %d\n", &n, &m);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= m; j++)
		{
			scanf("%c", &mat[i][j]);
			if (mat[i][j] == '.')
				init_broj_praznih++;
			
		}
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (mat[i][j] == '0')
			{
				if (mat[i+1][j] == '.')
					mat[i + 1][j] = 'x';
				if (mat[i - 1][j] == '.')
					mat[i - 1][j] = 'x';
				if (mat[i][j+1] == '.')
					mat[i][j+1] = 'x';
				if (mat[i][j-1] == '.')
					mat[i][j-1] = 'x';
			}
		}
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (mat[i][j] > '0' && mat[i][j] <= '4')
			{
				pozicija ptemp;
				ptemp.br_topova = mat[i][j] - 48;
				if (mat[i + 1][j] == '.')
					ptemp.polja.push_back({i+1,j,false });
				if (mat[i - 1][j] == '.')
					ptemp.polja.push_back({ i - 1,j,false });
				if (mat[i][j + 1] == '.')
					ptemp.polja.push_back({ i,j + 1,false });
				if (mat[i][j - 1] == '.')
					ptemp.polja.push_back({ i,j - 1,false });

				moguce_poz.push_back(ptemp);
			}

			
		}
	}

	for (int i = 0; i < moguce_poz.size(); i++)
	{
		for (int j = i+1; j < moguce_poz.size(); j++)
		{
			pozicija* t0 = &moguce_poz[i];
			pozicija* t1 = &moguce_poz[j];
			for (int k = 0; k < t0->polja.size(); k++)
			{
				for (int l = k; l < t1->polja.size(); l++)
				{
					polje* p0 = &t0->polja[k];
					polje* p1 = &t1->polja[l];
					if ((p0->x == p1->x) && (p0->y == p1->y))
					{
						std::vector<std::pair<int, int>> temp_polja = t0->povezana_polja;
						temp_polja.push_back(std::make_pair(l,j));
						*t0 = {t0->br_topova,t0->polja,temp_polja};

						temp_polja = t1->povezana_polja;
						temp_polja.push_back(std::make_pair(k,i));
						*t1 = { t1->br_topova,t1->polja,temp_polja };
					}
				}
			}
		}
	}
	if (metnitopa(moguce_poz, 0))
	{
		for each (std::pair<int, int> var in krajnje_koord)
		{
			mat[var.second][var.first] = 'C';
		}
		print_mat();
	}
	else
	{
		printf("-1");
	}
	return 0;
}