// Arup Guha
// 3/2/2024
// Sample Program to illustrate a BFS on a grid to find shortest distances 
// from one grid square.

import java.util.*;

public class griddist {

	final public static int[] DX = {-1,0,0,1};
	final public static int[] DY = {0,-1,1,0};
	
	public static int r;
	public static int c;
	public static char[][] grid;
	public static int[][] dist;
	
	public static void main(String[] args) {
	
		// Format has #rows and #cols on the first line.
		Scanner stdin = new Scanner(System.in);
		r = stdin.nextInt();
		c = stdin.nextInt();
		
		// Then the grid: _ is a passable square, # is blocked, S is start location (exactly 1 of these)
		// Read in the grid of characters.
		grid = new char[r][];
		for (int i=0; i<r; i++)
			grid[i] = stdin.next().toCharArray();
			
		// Finding my start location.
		int sx = -1, sy = -1;
		for (int i=0; i<r; i++) {
			for (int j=0; j<c; j++) {
				if (grid[i][j] == 'S') {
					sx = i;
					sy = j;
				}
			}
		}
		
		// Run BFS.
		bfs(sx, sy);
		
		// Print out distance to each square. Blocked squares print as #
		for (int i=0; i<r; i++) {
			for (int j=0; j<c; j++) {
				if (grid[i][j] == '#')
					System.out.print("#\t");
				else
					System.out.print(dist[i][j]+"\t");
			}
			System.out.println();
		}
	}
	
	// Runs BFS from (sx, sy);
	public static void bfs(int sx, int sy) {
	
		dist = new int[r][c];
		for (int i=0; i<r; i++)
			Arrays.fill(dist[i], -1);
		dist[sx][sy] = 0;
		
		// Set up my queue.
		ArrayDeque<Integer> q = new ArrayDeque<Integer>();
		q.offer(sx*c + sy);
		
		// Run BFS.
		while (q.size() > 0) {
		
			// Get next place.
			int cur = q.poll();
			
			// Extract location.
			int x = cur/c;
			int y = cur%c;
			
			// Try going in each direction.
			for (int i=0; i<DX.length; i++) {
			
				int nx = x + DX[i];
				int ny = y + DY[i];
				
				// Can't go off the grid.
				if (!inbounds(nx, ny)) continue;
				
				// We've been there before.
				if (dist[nx][ny] != -1) continue;
				
				// Illegal square.
				if (grid[nx][ny] == '#') continue;
				
				// Update distance add to queue.
				dist[nx][ny] = dist[x][y] + 1;
				q.offer(nx*c + ny);
			}
		}
	}
	
	public static boolean inbounds(int x, int y) {
		return x>=0 && x<r && y>=0 && y<c;
	}
}