← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

type Point struct {
	r, c int
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, m int
	if _, err := fmt.Fscan(reader, &n, &m); err != nil {
		return
	}

	grid := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &grid[i])
	}

	adj := make([][]Point, n*m)
	getId := func(r, c int) int {
		return r*m + c
	}

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] == 'X' {
				var unmarked []Point
				if i > 0 && grid[i-1][j] == '.' {
					unmarked = append(unmarked, Point{i - 1, j})
				}
				if i < n-1 && grid[i+1][j] == '.' {
					unmarked = append(unmarked, Point{i + 1, j})
				}
				if j > 0 && grid[i][j-1] == '.' {
					unmarked = append(unmarked, Point{i, j - 1})
				}
				if j < m-1 && grid[i][j+1] == '.' {
					unmarked = append(unmarked, Point{i, j + 1})
				}

				if len(unmarked)%2 != 0 {
					fmt.Fprintln(writer, "NO")
					return
				}

				if len(unmarked) == 2 {
					u, v := unmarked[0], unmarked[1]
					uid := getId(u.r, u.c)
					vid := getId(v.r, v.c)
					adj[uid] = append(adj[uid], v)
					adj[vid] = append(adj[vid], u)
				} else if len(unmarked) == 4 {
					top := Point{i - 1, j}
					bottom := Point{i + 1, j}
					left := Point{i, j - 1}
					right := Point{i, j + 1}

					tid := getId(top.r, top.c)
					bid := getId(bottom.r, bottom.c)
					lid := getId(left.r, left.c)
					rid := getId(right.r, right.c)

					adj[tid] = append(adj[tid], bottom)
					adj[bid] = append(adj[bid], top)
					adj[lid] = append(adj[lid], right)
					adj[rid] = append(adj[rid], left)
				}
			}
		}
	}

	color := make([][]int, n)
	for i := 0; i < n; i++ {
		color[i] = make([]int, m)
		for j := 0; j < m; j++ {
			color[i][j] = -1
		}
	}

	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] == '.' && color[i][j] == -1 {
				queue := []Point{{i, j}}
				color[i][j] = 0

				for len(queue) > 0 {
					curr := queue[0]
					queue = queue[1:]

					currId := getId(curr.r, curr.c)
					for _, next := range adj[currId] {
						if color[next.r][next.c] == -1 {
							color[next.r][next.c] = 1 - color[curr.r][curr.c]
							queue = append(queue, next)
						} else if color[next.r][next.c] == color[curr.r][curr.c] {
							fmt.Fprintln(writer, "NO")
							return
						}
					}
				}
			}
		}
	}

	mapColor := func(c int) int {
		if c == 0 {
			return 1
		}
		return 4
	}

	fmt.Fprintln(writer, "YES")
	for i := 0; i < n; i++ {
		for j := 0; j < m; j++ {
			if grid[i][j] == '.' {
				if j > 0 {
					fmt.Fprint(writer, " ")
				}
				fmt.Fprint(writer, mapColor(color[i][j]))
			} else {
				sum := 0
				if i > 0 && grid[i-1][j] == '.' {
					sum += mapColor(color[i-1][j])
				}
				if i < n-1 && grid[i+1][j] == '.' {
					sum += mapColor(color[i+1][j])
				}
				if j > 0 && grid[i][j-1] == '.' {
					sum += mapColor(color[i][j-1])
				}
				if j < m-1 && grid[i][j+1] == '.' {
					sum += mapColor(color[i][j+1])
				}
				if j > 0 {
					fmt.Fprint(writer, " ")
				}
				fmt.Fprint(writer, sum)
			}
		}
		fmt.Fprintln(writer)
	}
}
```