Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, or is a wall. You can go from one cell to another only if both cells are empty and have a common side.

Pavel drew a grid maze with all empty cells forming a connected area. That is, you can go from any empty cell to any other one. Pavel doesn't like it when his maze has too little walls. He wants to turn exactly k empty cells into walls so that all the remaining cells still formed a connected area. Help him.


-----Input-----

The first line contains three integers n, m, k (1 ≤ n, m ≤ 500, 0 ≤ k < s), where n and m are the maze's height and width, correspondingly, k is the number of walls Pavel wants to add and letter s represents the number of empty cells in the original maze.

Each of the next n lines contains m characters. They describe the original maze. If a character on a line equals ".", then the corresponding cell is empty and if the character equals "#", then the cell is a wall.


-----Output-----

Print n lines containing m characters each: the new maze that fits Pavel's requirements. Mark the empty cells that you transformed into walls as "X", the other cells must be left without changes (that is, "." and "#").

It is guaranteed that a solution exists. If there are multiple solutions you can output any of them.


-----Examples-----
Input
3 4 2
#..#
..#.
#...

Output
#.X#
X.#.
#...

Input
5 4 5
#...
#.#.
.#..
...#
.#.#

Output
#XXX
#X#.
X#..
...#
.#.#

Difficulty: MEDIUM_HARD
Tags: Graph traversal

Starter code:

Solutions:
from sys import stdin
from collections import deque

def __starting_point():
	(R, C, K) = list(map(int, stdin.readline().rstrip().split()))
	maze = []
	start = None
	for r in range(0, R):
		line = stdin.readline()
		if start is None:
			for c in range(0, C):
				if line[c] == '.':
					start = (r, c)
					break
		maze.append(list(line))
	order = deque()
	stack = deque()
	stack.append(start)

	def add_to_stack(row, col):
		if 0 <= row < R and 0 <= col < C and (maze[row][col] == '.'):
			stack.append((row, col))
			maze[row][col] = ','
	while len(stack) > 0:
		(r, c) = stack.pop()
		order.append((r, c))
		add_to_stack(r - 1, c)
		add_to_stack(r + 1, c)
		add_to_stack(r, c - 1)
		add_to_stack(r, c + 1)
	for k in range(0, K):
		(r, c) = order.pop()
		maze[r][c] = 'X'
	for r in range(0, R):
		line = ''
		for c in range(0, C):
			ch = maze[r][c]
			if ch == ',':
				line += '.'
			else:
				line += ch
		print(line)
__starting_point()


(n, m, k) = list(map(int, input().split()))
arr = []
c = 0
for i in range(n):
	x = input().replace('.', 'X')
	c += x.count('#')
	arr.append(list(map(str, x)))
k = n * m - k - c
(i, p) = (0, [])
while k:
	if 'X' in arr[i]:
		j = arr[i].index('X')
		(arr[i][j], p) = ('.', [(i, j)])
		k -= 1
		break
	i += 1
while k:
	(x, y) = p.pop()
	for (i, j) in ((x, y - 1), (x, y + 1), (x - 1, y), (x + 1, y)):
		if i < 0 or j < 0:
			continue
		if i < n and j < m and (arr[i][j] == 'X'):
			arr[i][j] = '.'
			p.append((i, j))
			k -= 1
			if k == 0:
				break
for i in arr:
	for j in i:
		print(j, end='')
	print()


import os, sys
from io import BytesIO, IOBase

def main():
	(n, m, k) = map(int, input().split())
	arr = [list(input().strip()) for _ in range(n)]
	st = []
	visi = [[1 for _ in range(m + 1)] for _ in range(n + 1)]
	for i in range(n):
		for j in range(m):
			if arr[i][j] == '.':
				st = [(i, j)]
				visi[i][j] = 0
	visi[st[0][0]][st[0][1]] = 1
	dx = [1, -1, 0, 0]
	dy = [0, 0, 1, -1]
	ans = [i[:] for i in arr]
	while len(st):
		if not k:
			break
		fl = 0
		(x, y) = st[-1]
		for i in range(4):
			if not visi[x + dx[i]][y + dy[i]]:
				fl = 1
				st.append((x + dx[i], y + dy[i]))
				visi[x + dx[i]][y + dy[i]] = 1
				break
		if not fl:
			k -= 1
			ans[x][y] = 'X'
			st.pop()
	for i in ans:
		print(*i, sep='')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


import itertools

def main(inp):
	(n, m, k) = split_inp_int(inp)
	grid = {}
	for i in range(n):
		row = inp()
		for j in range(m):
			grid[i, j] = row[j]
	water = {(i, j) for (i, j) in itertools.product(range(n), range(m)) if grid[i, j] == '.'}

	def is_connected(grid):
		water_left = {e for e in water}
		first_water = water_left.pop()
		connected = {first_water}
		queue = {first_water}
		while queue:
			(vx, vy) = queue.pop()
			if len(connected) < len(water) - k:
				connected.add((vx, vy))
			else:
				break
			for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
				consider = (vx + dx, vy + dy)
				if consider in water_left:
					queue.add(consider)
					water_left.remove(consider)
		return connected
	connected = is_connected(grid)
	for i in range(n):
		for j in range(m):
			if grid[i, j] == '.' and (i, j) not in connected:
				grid[i, j] = 'X'
	[print(''.join([grid[i, j] for j in range(m)])) for i in range(n)]

def split_inp_int(inp):
	return list(map(int, inp().split()))

def use_fast_io():
	import sys

	class InputStorage:

		def __init__(self, lines):
			lines.reverse()
			self.lines = lines

		def input_func(self):
			if self.lines:
				return self.lines.pop()
			else:
				return ''
	input_storage_obj = InputStorage(sys.stdin.readlines())
	return input_storage_obj.input_func
from collections import Counter, defaultdict
from functools import reduce
import operator
import math

def product(arr_):
	return reduce(operator.mul, arr_, 1)
main(use_fast_io())


(a, b, c) = map(int, input().split(' '))
array = [[i for i in input()] for j in range(a)]
p = []
x = 0
for i in range(a):
	for j in range(b):
		if array[i][j] == '.':
			p.append((i, j))
			x += 1
visited = [[False] * b for i in range(a)]

def ok(i, j):
	if 0 <= i <= a - 1 and 0 <= j <= b - 1:
		if array[i][j] != '#':
			return True
	return False
sa = 0
while sa < x - c:
	(i, j) = p.pop()
	if visited[i][j]:
		continue
	if ok(i, j - 1):
		if not visited[i][j - 1]:
			p.append((i, j - 1))
	if ok(i, j + 1):
		if not visited[i][j + 1]:
			p.append((i, j + 1))
	if ok(i + 1, j):
		if not visited[i + 1][j]:
			p.append((i + 1, j))
	if ok(i - 1, j):
		if not visited[i - 1][j]:
			p.append((i - 1, j))
	visited[i][j] = True
	sa += 1
for i in range(a):
	for j in range(b):
		if array[i][j] == '.' and (not visited[i][j]):
			array[i][j] = 'X'
for each in [''.join(i) for i in array]:
	print(each)


(n, m, k) = map(int, input().split(' '))
maze = []
s = None
for i in range(n):
	maze.append([])
	for (j, c) in enumerate(input()):
		maze[-1].append(c)
		if c == '.':
			s = (i, j)
d = {s}
s = [s]
while s and k:
	(i, j) = s[-1]
	if maze[i][j] != '.':
		d.remove(s.pop())
		continue
	ok = True
	for (p, q) in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
		if not (0 <= p < n and 0 <= q < m):
			continue
		if maze[p][q] != '.':
			continue
		if (p, q) in d:
			continue
		s.append((p, q))
		d.add((p, q))
		ok = False
	if ok:
		d.remove(s.pop())
		maze[i][j] = 'X'
		k -= 1
for l in maze:
	print(''.join(l))


def dfs(n, m, k, v, s, holes, numHoles):
	stack = []
	setHoles = set(holes)
	minDeg = 10000000000.0
	idx = 0
	for hole in holes:
		(x, y) = hole
		deg = 0
		if (x - 1, y) in setHoles:
			deg += 1
		if (x + 1, y) in setHoles:
			deg += 1
		if (x, y - 1) in setHoles:
			deg += 1
		if (x, y + 1) in setHoles:
			deg += 1
		if deg < minDeg:
			minDeg = deg
			ans = hole
	stack.append(ans)
	num = 0
	while len(stack) and num < numHoles - k:
		(i, j) = stack[-1]
		del stack[-1]
		if (i, j) not in v:
			num += 1
			v.add((i, j))
		if j - 1 >= 0 and j - 1 <= m - 1 and (s[i][j - 1] == '.') and ((i, j - 1) not in v):
			stack.append((i, j - 1))
		if j + 1 >= 0 and j + 1 <= m - 1 and (s[i][j + 1] == '.') and ((i, j + 1) not in v):
			stack.append((i, j + 1))
		if i - 1 >= 0 and i - 1 <= n - 1 and (s[i - 1][j] == '.') and ((i - 1, j) not in v):
			stack.append((i - 1, j))
		if i + 1 >= 0 and i + 1 <= n - 1 and (s[i + 1][j] == '.') and ((i + 1, j) not in v):
			stack.append((i + 1, j))

def main():
	num = numHoles = found = n = m = k = 0
	s = []
	holes = []
	v = set()
	(n, m, k) = list(map(int, input().strip().split()))
	for i in range(n):
		s.append(input().strip())
	for i in range(n):
		for j in range(m):
			if s[i][j] == '.':
				numHoles += 1
				holes.append((i, j))
	dfs(n, m, k, v, s, holes, numHoles)
	for i in range(n):
		for j in range(m):
			if s[i][j] == '#':
				print(s[i][j], end='')
			elif s[i][j] == '.':
				if (i, j) not in v:
					print('X', end='')
				else:
					print(s[i][j], end='')
		print()
main()


from collections import deque
(n, m, k) = (int(i) for i in input().split(' '))
maze = []
for _ in range(n):
	row = input()
	maze.append(row)
if k == 0:
	for row in maze:
		print(row)
else:
	ans = []
	for i in range(n):
		row = [0] * m
		ans.append(row)
	length = 0

	def bfs(x, y):
		global length, ans
		if length == diff:
			return
		cola = deque()
		cola.append((x, y))
		ans[x][y] = 1
		length += 1
		while cola:
			(i, j) = cola.popleft()
			if i > 0 and maze[i - 1][j] == '.' and (ans[i - 1][j] != 1) and (length < diff):
				ans[i - 1][j] = 1
				length += 1
				cola.append((i - 1, j))
			if j > 0 and maze[i][j - 1] == '.' and (ans[i][j - 1] != 1) and (length < diff):
				ans[i][j - 1] = 1
				length += 1
				cola.append((i, j - 1))
			if i < n - 1 and maze[i + 1][j] == '.' and (ans[i + 1][j] != 1) and (length < diff):
				ans[i + 1][j] = 1
				length += 1
				cola.append((i + 1, j))
			if j < m - 1 and maze[i][j + 1] == '.' and (ans[i][j + 1] != 1) and (length < diff):
				ans[i][j + 1] = 1
				length += 1
				cola.append((i, j + 1))
		return
	found = False
	s = 0
	(i0, j0) = (0, 0)
	for (i, row) in enumerate(maze):
		for (j, cell) in enumerate(row):
			if cell == '.':
				s += 1
				if not found:
					found = True
					(i0, j0) = (i, j)
	diff = s - k
	bfs(i0, j0)
	res = []
	for (i, row) in enumerate(maze):
		new_row = ''
		for (j, cell) in enumerate(row):
			if cell == '#' or (cell == '.' and ans[i][j] == 1):
				new_row += cell
			else:
				new_row += 'X'
		print(new_row)


import sys
from collections import defaultdict

def main():
	sys.setrecursionlimit(1 << 30)
	g = []
	adj = defaultdict(set)
	vis = set()

	def valid(x, y):
		nonlocal n, m
		return x >= 0 and x < n and (y >= 0) and (y < m)

	def bfs(x, y):
		nonlocal g, vis, adj
		q = []
		q.append((x, y))
		vis.add((x, y))
		s = 0
		while len(q) > 0:
			(x, y) = q.pop()
			s += 1
			for c in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
				nx = c[0] + x
				ny = c[1] + y
				if valid(nx, ny) and (nx, ny) not in vis:
					if g[nx][ny] == '.':
						vis.add((nx, ny))
						q.append((nx, ny))
		return s

	def bfs2(x, y):
		nonlocal g, vis, adj, count
		q = []
		q.append((x, y))
		vis.add((x, y))
		while len(q) > 0:
			(x, y) = q.pop()
			g[x][y] = 'o'
			count -= 1
			if count <= 0:
				return
			for c in [[-1, 0], [1, 0], [0, -1], [0, 1]]:
				nx = c[0] + x
				ny = c[1] + y
				if valid(nx, ny) and (nx, ny) not in vis:
					if g[nx][ny] == '.':
						vis.add((nx, ny))
						q.append((nx, ny))
	(n, m, k) = map(int, input().split(' '))
	for i in range(n):
		g.append(list(input()))
	s = 0
	f = False
	l = None
	for i in range(n):
		if f:
			break
		for j in range(m):
			if g[i][j] == '.' and (i, j) not in vis:
				s = bfs(i, j)
				l = (i, j)
				f = True
				break
	vis = set()
	count = s - k
	bfs2(l[0], l[1])
	f = lambda i: 'X' if i == '.' else '#' if i == '#' else '.'
	for row in g:
		print(''.join(list(map(f, row))))
main()


from typing import List, Tuple, Set

def find_neighbors(x: int, y: int, m: int, n: int) -> List[Tuple[int, int]]:
	neighbors = [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
	return [p for p in neighbors if 0 <= p[0] < n and 0 <= p[1] < m]

def dfs(n: int, m: int, maze: List[List[str]], start: Tuple[int, int], max_path_length: int) -> Set[Tuple[int, int]]:
	visited = [[0] * m for _ in range(n)]
	d = [start]
	path = set()
	while d:
		(x, y) = d.pop()
		visited[x][y] = 1
		path.add((x, y))
		for (xo, yo) in find_neighbors(x, y, m, n):
			if not visited[xo][yo] and maze[xo][yo] == '.':
				d.append((xo, yo))
		if len(path) == max_path_length:
			break
	return path

def place_blocks(n: int, m: int, k: int, maze: List[List[str]], path: Set[Tuple[int, int]]) -> List[List[str]]:
	for i in range(n):
		for j in range(m):
			if maze[i][j] == '.' and k > 0 and ((i, j) not in path):
				maze[i][j] = 'X'
				k -= 1
			if k == 0:
				return maze

def solve(n: int, m: int, k: int, maze: List[List[str]]) -> List[List[str]]:
	empty_cell_count = sum((row.count('.') for row in maze))
	for i in range(n):
		for j in range(m):
			if maze[i][j] != '#':
				path = dfs(n, m, maze, (i, j), empty_cell_count - k)
				if len(path) >= empty_cell_count - k:
					return place_blocks(n, m, k, maze, path)
(n, m, k) = list(map(int, input().split()))
maze = [list(input()) for _ in range(n)]
for line in solve(n, m, k, maze):
	print(''.join(line))


def dfs(mat, r, c, visited, limit):
	dfsStack = [(r, c)]
	while dfsStack and limit > 0:
		(i, j) = dfsStack.pop()
		if 0 <= i < len(mat) and 0 <= j < len(mat[i]) and (mat[i][j] == '.') and (not visited[i][j]):
			mat[i][j] = 'C'
			visited[i][j] = True
			limit -= 1
			dfsStack.append((i + 1, j))
			dfsStack.append((i - 1, j))
			dfsStack.append((i, j - 1))
			dfsStack.append((i, j + 1))
(height, width, walls) = map(int, input().split())
empty = 0
mat = []
visited = []
i = -1
j = -1
for r in range(height):
	line = input()
	if i == j == -1 and line.find('.') > -1:
		i = r
		j = line.index('.')
	mat.append(list(line))
	visited.append([False] * len(line))
	empty += line.count('.')
emptyLeft = empty - walls
dfs(mat, i, j, visited, emptyLeft)
for i in range(height):
	line = ''.join(mat[i])
	print(line.replace('.', 'X').replace('C', '.'))


from collections import deque
(n, m, k) = map(int, input().split())
grid = [[None for i in range(m)] for j in range(n)]
visited = [[False for i in range(m)] for i in range(n)]
(total, cnt) = (0, 0)
start = 0
moveX = [-1, 1, 0, 0]
moveY = [0, 0, 1, -1]
for i in range(n):
	s = list(input())
	for j in range(m):
		if s[j] == '.':
			start = (i, j)
			grid[i][j] = 'X'
			total += 1
		else:
			grid[i][j] = s[j]
q = deque()
q.append(start)
while q:
	(s1, s2) = q.popleft()
	if s1 < 0 or s1 >= n or s2 < 0 or (s2 >= m) or visited[s1][s2] or (cnt == total - k):
		continue
	elif grid[s1][s2] == 'X':
		grid[s1][s2] = '.'
		cnt += 1
		for f in range(4):
			f1 = moveX[f] + s1
			f2 = moveY[f] + s2
			if 0 <= f1 < n and 0 <= f2 < m:
				q.append((f1, f2))
for i in grid:
	print(''.join(i))


(n, m, k) = [int(i) for i in input().split()]
maze = []
for row in range(n):
	ro = []
	temp = input()
	for i in temp:
		if i == '.':
			ro.append(1)
		else:
			ro.append(0)
	maze.append(ro)
done = 0
for i in range(n):
	if done == 1:
		break
	for j in range(m):
		if maze[i][j] == 1:
			root_node = [i, j]
			done = 1
			break
visited = [[0 for i in range(m)] for j in range(n)]
visited[root_node[0]][root_node[1]] = 1
levels = []
levels.append([root_node])
stop = 0
while True:
	if stop == 1:
		break
	else:
		bottom_most_nodes = levels[-1]
		upcoming_nodes = []
		for node in bottom_most_nodes:
			(i, j) = (node[0], node[1])
			if i == 0:
				if j == 0:
					for (row, col) in [[min(i + 1, n - 1), j], [i, min(j + 1, m - 1)]]:
						if maze[row][col] == 1 and visited[row][col] == 0:
							upcoming_nodes.append([row, col])
							visited[row][col] = 1
				elif j == m - 1:
					for (row, col) in [[min(i + 1, n - 1), j], [i, max(j - 1, 0)]]:
						if maze[row][col] == 1 and visited[row][col] == 0:
							upcoming_nodes.append([row, col])
							visited[row][col] = 1
				else:
					for (row, col) in [[min(i + 1, n - 1), j], [i, min(j + 1, m - 1)], [i, max(j - 1, 0)]]:
						if maze[row][col] == 1 and visited[row][col] == 0:
							upcoming_nodes.append([row, col])
							visited[row][col] = 1
			elif i == n - 1:
				if j == 0:
					for (row, col) in [[max(i - 1, 0), j], [i, min(j + 1, m - 1)]]:
						if maze[row][col] == 1 and visited[row][col] == 0:
							upcoming_nodes.append([row, col])
							visited[row][col] = 1
				elif j == m - 1:
					for (row, col) in [[max(i - 1, 0), j], [i, max(j - 1, 0)]]:
						if maze[row][col] == 1 and visited[row][col] == 0:
							upcoming_nodes.append([row, col])
							visited[row][col] = 1
				else:
					for (row, col) in [[max(i - 1, 0), j], [i, min(j + 1, m - 1)], [i, max(j - 1, 0)]]:
						if maze[row][col] == 1 and visited[row][col] == 0:
							upcoming_nodes.append([row, col])
							visited[row][col] = 1
			elif j == 0:
				for (row, col) in [[max(i - 1, 0), j], [min(i + 1, n - 1), j], [i, min(j + 1, m - 1)]]:
					if maze[row][col] == 1 and visited[row][col] == 0:
						upcoming_nodes.append([row, col])
						visited[row][col] = 1
			elif j == m - 1:
				for (row, col) in [[min(i + 1, n - 1), j], [max(i - 1, 0), j], [i, max(j - 1, 0)]]:
					if maze[row][col] == 1 and visited[row][col] == 0:
						upcoming_nodes.append([row, col])
						visited[row][col] = 1
			else:
				for (row, col) in [[min(i + 1, n - 1), j], [i, min(j + 1, m - 1)], [max(i - 1, 0), j], [i, max(j - 1, 0)]]:
					if maze[row][col] == 1 and visited[row][col] == 0:
						upcoming_nodes.append([row, col])
						visited[row][col] = 1
		if upcoming_nodes == []:
			stop = 1
			break
		else:
			levels.append(upcoming_nodes)
final_arcitect = []
for i in maze:
	temp = []
	for j in i:
		temp.append(j)
	final_arcitect.append(temp)
remaining = k
while remaining > 0:
	current_level = levels.pop(-1)
	if len(current_level) <= remaining:
		for j in current_level:
			maze[j[0]][j[1]] = -1
		remaining -= len(current_level)
	else:
		for j in range(remaining):
			maze[current_level[j][0]][current_level[j][1]] = -1
		remaining = 0
for i in range(n):
	line = ''
	for j in range(m):
		if maze[i][j] == 1:
			line += '.'
		elif maze[i][j] == 0:
			line += '#'
		else:
			line += 'X'
	print(line)


def main():
	(n, m, k) = map(int, input().split())
	mn = m * n
	l = [_ == '.' for _ in range(n) for _ in input()]
	neigh = [[] for _ in range(mn)]
	for y in range(n - 1):
		for x in range(m):
			yx = y * m + x
			if l[yx] and l[yx + m]:
				neigh[yx].append(yx + m)
				neigh[yx + m].append(yx)
	for y in range(n):
		for x in range(m - 1):
			yx = y * m + x
			if l[yx] and l[yx + 1]:
				neigh[yx].append(yx + 1)
				neigh[yx + 1].append(yx)
	res = [True] * mn
	(cur, nxt) = (set(), {l.index(True)})
	cnt = sum(l) - k
	while cnt:
		(cur, nxt) = (nxt, cur)
		while cur:
			i = cur.pop()
			if res[i]:
				res[i] = False
				cnt -= 1
				if not cnt:
					break
				for j in neigh[i]:
					nxt.add(j)
	for (x, (a, b)) in enumerate(zip(res, l)):
		if a and b:
			l[x] = 2
	l = [''.join((('#', '.', 'X')[_] for _ in l[x:x + m])) for x in range(0, mn, m)]
	print('\n'.join(l))

def __starting_point():
	main()
__starting_point()


import sys
(n, m, k) = (int(x) for x in sys.stdin.readline().split(' '))
maze = []
for i in range(n):
	maze.append(list(sys.stdin.readline().strip()))
for y in range(n):
	for x in range(m):
		if maze[y][x] == '.':
			(x0, y0) = (x, y)
			break
	else:
		continue
	break
else:
	print('no spare room')
	return
stack = []
stack.append((x0, y0))
while stack:
	(x, y) = stack[-1]
	if maze[y][x] == '.':
		maze[y][x] = '0'
		if x > 0 and maze[y][x - 1] == '.':
			stack.append((x - 1, y))
	elif maze[y][x] == '0':
		maze[y][x] = '1'
		if y < n - 1 and maze[y + 1][x] == '.':
			stack.append((x, y + 1))
	elif maze[y][x] == '1':
		maze[y][x] = '2'
		if x < m - 1 and maze[y][x + 1] == '.':
			stack.append((x + 1, y))
	elif maze[y][x] == '2':
		maze[y][x] = '3'
		if y > 0 and maze[y - 1][x] == '.':
			stack.append((x, y - 1))
	elif maze[y][x] == '3':
		if k > 0:
			maze[y][x] = 'X'
			k -= 1
		stack.pop()
for y in range(n):
	for x in range(m):
		maze[y][x] = '.' if maze[y][x] == '3' else maze[y][x]
print('\n'.join([''.join(s) for s in maze]))


import sys
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
(n, m, k) = I()
l = []
x = y = -1
s = 0
for i in range(n):
	l.append(list(input().strip().replace('.', 'X')))
	if x == -1 and 'X' in l[-1]:
		x = i
		y = l[-1].index('X')
	s += l[-1].count('X')
q = [[x, y]]
ct = s
while q:
	(x, y) = q.pop()
	if l[x][y] == 'X':
		l[x][y] = '.'
		ct -= 1
	if ct == k:
		break
	if x > 0 and l[x - 1][y] == 'X':
		q.append([x - 1, y])
	if y > 0 and l[x][y - 1] == 'X':
		q.append([x, y - 1])
	if x < n - 1 and l[x + 1][y] == 'X':
		q.append([x + 1, y])
	if y < m - 1 and l[x][y + 1] == 'X':
		q.append([x, y + 1])
for i in range(n):
	print(''.join(l[i]))


(n, m, k) = map(int, input().split())
grid = [list(input()) for i in range(n)]
v = set()
v1 = set()
c = 0
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			c += 1
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.' and i * m + j not in v1:
			if v1:
				grid[i][j] = 'X'
				continue
			q = [i * m + j]
			while q and len(v1) < c - k:
				node = q[0]
				del q[0]
				x = node // m
				y = node % m
				v1.add(node)
				if x > 0 and grid[x - 1][y] == '.' and (node - m not in v):
					q.append(node - m)
					v.add(node - m)
				if x < n - 1 and grid[x + 1][y] == '.' and (node + m not in v):
					q.append(node + m)
					v.add(node + m)
				if y > 0 and grid[x][y - 1] == '.' and (node - 1 not in v):
					q.append(node - 1)
					v.add(node - 1)
				if y < m - 1 and grid[x][y + 1] == '.' and (node + 1 not in v):
					q.append(node + 1)
					v.add(node + 1)
for row in grid:
	print(''.join(row))


import sys
sys.setrecursionlimit(10 ** 6)
from collections import deque

def isValid(i, j, n, m, visited, g):
	if i >= n or j >= m or i < 0 or (j < 0):
		return False
	elif g[i][j] == 'X' and visited[i][j] == 0:
		return True
	else:
		return False
(n, m, k) = list(map(int, input().split()))
g = []
p = deque()
visited = []
for i in range(n):
	g.append(list(input()))
	visited.append([0] * m)
(x, y) = (0, 0)
s = 0
for i in range(n):
	for j in range(m):
		if g[i][j] == '.':
			g[i][j] = 'X'
			(x, y) = (i, j)
			s = s + 1
p.append([x, y])
visited[x][y] = 1
s = s - k
while p != []:
	(x, y) = p.popleft()
	g[x][y] = '.'
	s = s - 1
	if s == 0:
		break
	else:
		if isValid(x + 1, y, n, m, visited, g):
			p.append([x + 1, y])
			visited[x + 1][y] = 1
		if isValid(x - 1, y, n, m, visited, g):
			p.append([x - 1, y])
			visited[x - 1][y] = 1
		if isValid(x, y + 1, n, m, visited, g):
			p.append([x, y + 1])
			visited[x][y + 1] = 1
		if isValid(x, y - 1, n, m, visited, g):
			p.append([x, y - 1])
			visited[x][y - 1] = 1
for i in range(n):
	print(''.join(g[i]))


(n, m, k) = map(int, input().split())
maze = [['#'] * (m + 2)] + [list('#' + input() + '#') for i in range(n)] + [['#'] * (m + 2)]
steps = [[0, 1], [0, -1], [1, 0], [-1, 0]]
empty = -k
(x, y) = (None, None)
for i in range(n + 2):
	empty += maze[i].count('.')
	for j in range(m + 2):
		if maze[i][j] == '.':
			(x, y) = (i, j)
			break
stack = [(x, y)]
while empty:
	(x, y) = stack.pop()
	if maze[x][y] == 'v':
		continue
	for (dx, dy) in steps:
		if maze[x + dx][y + dy] == '.':
			stack.append((x + dx, y + dy))
	maze[x][y] = 'v'
	empty -= 1
for row in maze[1:-1]:
	print(''.join(row[1:-1]).replace('.', 'X').replace('v', '.'))


from collections import deque
(n, m, k) = map(int, input().split())
a = []
d = {'#': -1, '.': 0}
for _ in range(n):
	a.append(list(map(d.get, input())))
for i in range(n):
	for j in range(m):
		if a[i][j] == 0:
			(x, y) = (i, j)
			break
q = deque()
q.append((x, y))
a[x][y] = t = 1
while q:
	(x, y) = q.popleft()
	if x > 0 and a[x - 1][y] == 0:
		q.append((x - 1, y))
		t += 1
		a[x - 1][y] = t
	if x < n - 1 and a[x + 1][y] == 0:
		q.append((x + 1, y))
		t += 1
		a[x + 1][y] = t
	if y > 0 and a[x][y - 1] == 0:
		q.append((x, y - 1))
		t += 1
		a[x][y - 1] = t
	if y < m - 1 and a[x][y + 1] == 0:
		q.append((x, y + 1))
		t += 1
		a[x][y + 1] = t

def f(c):
	if c == -1:
		return '#'
	elif c <= t - k:
		return '.'
	else:
		return 'X'
for line in a:
	print(*map(f, line), sep='')


(n, m, k) = map(int, input().split())
arr = [list(input()) for _ in range(n)]
if k == 0:
	for i in range(n):
		print(''.join(arr[i]))
else:
	removeCells = 0
	(x, y) = (-1, -1)
	for i in range(len(arr)):
		for j in range(len(arr[i])):
			if arr[i][j] == '.':
				removeCells += 1
				x = i
				y = j
	stack = [(x, y)]
	removeCells = removeCells - k
	while removeCells > 0:
		(i, j) = stack.pop()
		removeCells -= 1
		arr[i][j] = '?'
		if i > 0 and arr[i - 1][j] == '.':
			stack.append((i - 1, j))
			arr[i - 1][j] = '@'
		if i < n - 1 and arr[i + 1][j] == '.':
			stack.append((i + 1, j))
			arr[i + 1][j] = '@'
		if j > 0 and arr[i][j - 1] == '.':
			stack.append((i, j - 1))
			arr[i][j - 1] = '@'
		if j < m - 1 and arr[i][j + 1] == '.':
			stack.append((i, j + 1))
			arr[i][j + 1] = '@'
	for i in range(len(arr)):
		for j in range(len(arr[i])):
			ele = arr[i][j]
			if ele == '?':
				print('.', end='')
			elif ele == '@' or ele == '.':
				print('X', end='')
			else:
				print(ele, end='')
		print()


import os
import sys
from io import BytesIO, IOBase

def main():
	(n, m, k) = map(int, input().split())
	arr = []
	for _ in range(n):
		arr.append(list(input()))
	s = 0
	if k == 0:
		for item in arr:
			print(*item, sep='')
		exit()
	stack = []
	flag = 1
	for r in range(n):
		for c in range(m):
			if arr[r][c] == '.' and flag:
				stack.append((r, c))
				flag = 0
				s += 1
			elif arr[r][c] == '.':
				s += 1
	s -= k
	visited = set()
	while stack:
		z = stack.pop()
		if z in visited:
			continue
		visited.add(z)
		if s:
			s -= 1
		else:
			arr[z[0]][z[1]] = 'X'
		(r, c) = (z[0], z[1])
		try:
			if arr[r - 1][c] == '.' and r > 0:
				stack.append((r - 1, c))
		except:
			pass
		try:
			if arr[r + 1][c] == '.' and r < n - 1:
				stack.append((r + 1, c))
		except:
			pass
		try:
			if arr[r][c - 1] == '.' and c > 0:
				stack.append((r, c - 1))
		except:
			pass
		try:
			if arr[r][c + 1] == '.' and c < m - 1:
				stack.append((r, c + 1))
		except:
			pass
	for item in arr:
		print(*item, sep='')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from collections import Counter
from math import log2
(n, m, k) = map(int, input().split())
g = []
var = 0
for i in range(n):
	s = input()
	var += s.count('.')
	g.append(list(s.replace('.', 'X')))
var = var - k
dx = (-1, 1, 0, 0)
dy = (0, 0, -1, 1)
p = []
f = 0
for i in range(n):
	for j in range(m):
		if g[i][j] == 'X':
			p = [(i, j)]
			g[i][j] = '.'
			var -= 1
			f = 1
			break
	if f == 1:
		break
while var:
	(x, y) = p.pop()
	for (i, j) in zip(dx, dy):
		if x + i < 0 or y + j < 0 or x + i >= n or (y + j >= m):
			continue
		if g[x + i][y + j] == 'X':
			g[x + i][y + j] = '.'
			p.append((x + i, y + j))
			var -= 1
			if var == 0:
				break
	if var == 0:
		break
for i in g:
	for j in i:
		print(j, end='')
	print()


import sys
reader = (line.rstrip() for line in sys.stdin)
input = reader.__next__

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())
import collections as c

def solve():
	(N, M, K) = getInts()
	maze = []
	for n in range(N):
		maze.append(listStr())
	graph = c.defaultdict(set)
	first_flag = False
	empty_count = 0
	for n in range(N):
		for m in range(M):
			if maze[n][m] == '#':
				continue
			empty_count += 1
			if not first_flag:
				(first_n, first_m) = (n, m)
			first_flag = True
			if n > 0 and maze[n - 1][m] != '#':
				graph[n, m].add((n - 1, m))
			if n < N - 1 and maze[n + 1][m] != '#':
				graph[n, m].add((n + 1, m))
			if m > 0 and maze[n][m - 1] != '#':
				graph[n, m].add((n, m - 1))
			if m < M - 1 and maze[n][m + 1] != '#':
				graph[n, m].add((n, m + 1))

	def bfs(graph, visited, node, queue, visited_dict, max_nodes):
		visited.append(node)
		visited_dict[node] = 1
		count = 0
		queue.append(node)
		queue = c.deque(queue)
		if len(visited) == max_nodes:
			return
		while queue:
			s = queue.popleft()
			for neighbour in graph[s]:
				if neighbour not in visited_dict:
					visited.append(neighbour)
					visited_dict[neighbour] = 1
					if len(visited) == max_nodes:
						return
					queue.append(neighbour)
		return
	visited = []
	visited_dict = c.defaultdict(int)
	bfs(graph, visited, (first_n, first_m), [], visited_dict, empty_count - K)
	for n in range(N):
		for m in range(M):
			if maze[n][m] != '#':
				if (n, m) not in visited_dict:
					maze[n][m] = 'X'
	for n in range(N):
		print(''.join(maze[n]))
	return
solve()


(n, m, k) = map(int, input().split())
arr = [list(input()) for _ in range(n)]
if k == 0:
	for row in arr:
		for element in row:
			print(element, end='')
		print('')
	exit(0)
(x, y) = (-1, -1)
to_visit = -k
for i in range(n):
	for j in range(m):
		if arr[i][j] == '.':
			to_visit += 1
			x = i
			y = j
s = [(x, y)]
while to_visit > 0 and len(s) > 0:
	(i, j) = s.pop()
	arr[i][j] = '?'
	to_visit -= 1
	if i > 0 and arr[i - 1][j] == '.':
		s.append((i - 1, j))
		arr[i - 1][j] = '@'
	if i < n - 1 and arr[i + 1][j] == '.':
		s.append((i + 1, j))
		arr[i + 1][j] = '@'
	if j > 0 and arr[i][j - 1] == '.':
		s.append((i, j - 1))
		arr[i][j - 1] = '@'
	if j < m - 1 and arr[i][j + 1] == '.':
		s.append((i, j + 1))
		arr[i][j + 1] = '@'
for row in arr:
	for element in row:
		if element == '?':
			print('.', end='')
		elif element == '.' or element == '@':
			print('X', end='')
		else:
			print(element, end='')
	print('')


import sys, io, os, time
from collections import defaultdict
from collections import Counter
from collections import deque
from itertools import combinations
from itertools import permutations
import bisect, math, heapq
alphabet = 'abcdefghijklmnopqrstuvwxyz'
input = sys.stdin.readline
(n, m, k) = map(int, input().split())
arr = []
empty = []
visited = [[False] * m for i in range(n)]
for i in range(n):
	temp = list(input())[:-1]
	arr.append(temp)
	for j in range(len(temp)):
		if temp[j] == '.':
			empty = [i, j]
order = []
visited[empty[0]][empty[1]] = True
q = deque([empty])
while q:
	(curx, cury) = q.popleft()
	order.append([curx, cury])
	for (dx, dy) in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
		x = dx + curx
		y = dy + cury
		if not 0 <= x <= n - 1 or not 0 <= y <= m - 1:
			continue
		if not visited[x][y] and arr[x][y] == '.':
			visited[x][y] = True
			q.append([x, y])
order = order[::-1]
for i in range(k):
	arr[order[i][0]][order[i][1]] = 'X'
for i in range(n):
	print(''.join(arr[i]))


(n, m, k) = map(int, input().split())
t = [input().replace('.', 'X') for i in range(n)]
k = n * m - k - sum((i.count('#') for i in t))
t = [list(i) for i in t]
(i, p) = (0, [])
while k:
	if 'X' in t[i]:
		j = t[i].index('X')
		(t[i][j], p) = ('.', [(i, j)])
		k -= 1
		break
	i += 1
while k:
	(x, y) = p.pop()
	for (i, j) in ((x, y - 1), (x, y + 1), (x - 1, y), (x + 1, y)):
		if i < 0 or j < 0:
			continue
		if i < n and j < m and (t[i][j] == 'X'):
			t[i][j] = '.'
			p.append((i, j))
			k -= 1
			if k == 0:
				break
for i in range(n):
	t[i] = ''.join(t[i])
print('\n'.join(t))


def print_lab(L, i, j):
	for q in range(i):
		for w in range(j):
			print(L[q][w], end='')
		print('')
	return

def dfs(L, x, y, n, m, s):
	global next_x
	global next_y
	L[x][y] = '.'
	s = s - 1
	if x > 0 and L[x - 1][y] == '0' and (s > 0):
		next_x.append(x - 1)
		next_y.append(y)
	if x < n - 1 and L[x + 1][y] == '0' and (s > 0):
		next_x.append(x + 1)
		next_y.append(y)
	if y > 0 and L[x][y - 1] == '0' and (s > 0):
		next_x.append(x)
		next_y.append(y - 1)
	if y < m - 1 and L[x][y + 1] == '0' and (s > 0):
		next_x.append(x)
		next_y.append(y + 1)
	next_x = next_x[1:]
	next_y = next_y[1:]
	return s
import sys
sys.setrecursionlimit(8000)
s = input().split()
n = int(s[0])
m = int(s[1])
k = int(s[2])
L = [['.' for i in range(m)] for j in range(n)]
L_upd = [['0' for i in range(m)] for j in range(n)]
c = 0
st_x = 0
st_y = 0
for i in range(n):
	s = list(input())
	for j in range(m):
		if s[j] == '#':
			L[i][j] = '#'
			L_upd[i][j] = '#'
		else:
			c += 1
			st_x = i
			st_y = j
t = c - k
next_x = [st_x]
next_y = [st_y]
if k == 0:
	print_lab(L, n, m)
else:
	try:
		while t > 0:
			if L_upd[next_x[0]][next_y[0]] == '0':
				t = dfs(L_upd, next_x[0], next_y[0], n, m, t)
			else:
				next_x = next_x[1:]
				next_y = next_y[1:]
	except Exception as e:
		print(e)
	for i in range(n):
		for j in range(m):
			if L_upd[i][j] == '0':
				L_upd[i][j] = 'X'
	print_lab(L_upd, n, m)


from sys import stdin, stdout
from collections import deque
ok = lambda tx, ty, n, m: tx >= 0 and tx < n and (ty >= 0) and (ty < m)
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

class G:

	def __init__(self, a, b):
		self.x = a
		self.y = b

def bfs(x, y, adlist, vis, nodes, k, n, m):
	q = deque()
	adlist[x][y] = 'X' if nodes <= k else adlist[x][y]
	(nodes, vis[x][y]) = (nodes - 1, 1)
	q.append(G(x, y))
	while len(q):
		u = q.popleft()
		for i in range(4):
			(tx, ty) = (dx[i] + u.x, dy[i] + u.y)
			if ok(tx, ty, n, m):
				if vis[tx][ty] == 0 and adlist[tx][ty] == '.':
					adlist[tx][ty] = 'X' if nodes <= k else adlist[tx][ty]
					(nodes, vis[tx][ty]) = (nodes - 1, 1)
					q.append(G(tx, ty))
	for i in range(n):
		stdout.write(''.join(adlist[i]))

def main():
	(n, m, k) = map(int, stdin.readline().split())
	adlist = {i: list(stdin.readline()) for i in range(n)}
	vis = {i: [0 for j in range(m)] for i in range(n)}
	(nodes, x, y) = (0, 0, 0)
	for i in range(n):
		for j in range(m):
			if adlist[i][j] == '.':
				(nodes, x, y) = (nodes + 1, i, j)
	bfs(x, y, adlist, vis, nodes, k, n, m)
main()


def get_nei(fi, fj):
	ret = []
	try:
		if maze[fi][fj + 1] == '.' and (not visited[fi][fj + 1]) and (fi >= 0) and (fj + 1 >= 0):
			ret.append((fi, fj + 1))
	except IndexError:
		pass
	try:
		if maze[fi][fj - 1] == '.' and (not visited[fi][fj - 1]) and (fi >= 0) and (fj - 1 >= 0):
			ret.append((fi, fj - 1))
	except IndexError:
		pass
	try:
		if maze[fi + 1][fj] == '.' and (not visited[fi + 1][fj]) and (fi + 1 >= 0) and (fj >= 0):
			ret.append((fi + 1, fj))
	except IndexError:
		pass
	try:
		if maze[fi - 1][fj] == '.' and (not visited[fi - 1][fj]) and (fi - 1 >= 0) and (fj >= 0):
			ret.append((fi - 1, fj))
	except IndexError:
		pass
	return ret
(n, m, k) = [int(__) for __ in input().strip().split()]
maze = []
for _ in range(n):
	maze.append(list(input().strip()))
all_dots_lis = []
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.':
			all_dots_lis.append((i, j))
all_dots = len(all_dots_lis)
(fi, fj) = all_dots_lis[0]
stop = all_dots - k
visited = [[False for j in range(m)] for i in range(n)]
visited[fi][fj] = True
vis = 1
cur = get_nei(fi, fj)
mark = []
while len(cur) > 0:
	nex = []
	for nei in cur:
		vis += 1
		if vis > stop:
			mark.append(nei)
		(x, y) = nei
		visited[x][y] = True
		neis = get_nei(x, y)
		for nnei in neis:
			if nnei not in nex:
				nex.append(nnei)
	cur = nex[:]
for m in mark:
	(x, y) = m
	maze[x][y] = 'X'
for x in maze:
	print(''.join(x))


def solve(N, M, K, maze):
	ans = maze
	dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)]
	(x, y) = (None, None)
	for i in range(M):
		for j in range(N):
			if maze[i][j] == '.':
				(x, y) = (i, j)
				break
		if x is not None:
			break
	vis = set()
	q = [(x, y)]
	traversal = []
	while q:
		(i, j) = q.pop()
		if (i, j) in vis:
			continue
		traversal.append((i, j))
		vis.add((i, j))
		for (x, y) in dirs:
			if not (0 <= i + x < M and 0 <= j + y < N):
				continue
			elif maze[i + x][j + y] != '.':
				continue
			q.append((i + x, j + y))
	while K:
		K -= 1
		(i, j) = traversal.pop()
		ans[i][j] = 'X'
	return ans
(M, N, K) = map(int, input().split())
maze = []
for i in range(M):
	line = list(input())
	maze.append(line)
ans = solve(N, M, K, maze)
for i in range(M):
	print(''.join(ans[i]))


import sys

def input():
	return sys.stdin.readline().strip()
(n, m, k) = map(int, input().split())
grid = []
for i in range(n):
	grid.append(list(input()))
i = 0
empty = False
while i < n:
	j = 0
	while j < m:
		if grid[i][j] == '.':
			empty = True
			break
		j += 1
	if empty:
		break
	i += 1
if i != n or j != m:
	cur = [[[i, -1], [j, -1]]]
	path = []
	visited = [[0 for i in range(m)] for j in range(n)]
	while len(cur) > 0:
		ele = cur.pop()
		i = ele[0][0]
		j = ele[1][0]
		prev_i = ele[0][1]
		prev_j = ele[1][1]
		path.append([i, j])
		if i + 1 < n and (prev_i != i + 1 or prev_j != j) and (grid[i + 1][j] == '.') and (not visited[i + 1][j]):
			cur.append([[i + 1, i], [j, j]])
			visited[i + 1][j] = 1
		if i - 1 >= 0 and (prev_i != i - 1 or prev_j != j) and (grid[i - 1][j] == '.') and (not visited[i - 1][j]):
			cur.append([[i - 1, i], [j, j]])
			visited[i - 1][j] = 1
		if j + 1 < m and (prev_i != i or prev_j != j + 1) and (grid[i][j + 1] == '.') and (not visited[i][j + 1]):
			cur.append([[i, i], [j + 1, j]])
			visited[i][j + 1] = 1
		if j - 1 >= 0 and (prev_i != i or prev_j != j - 1) and (grid[i][j - 1] == '.') and (not visited[i][j - 1]):
			cur.append([[i, i], [j - 1, j]])
			visited[i][j - 1] = 1
	for i in range(k):
		cur = path[-1 - i]
		grid[cur[0]][cur[1]] = 'X'
for i in range(n):
	print(''.join(grid[i]))


from collections import deque, namedtuple
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]

def main():
	(n, m, limit) = map(int, input().split())
	(a, sx, sy, tot) = ([], 0, 0, 0)
	for i in range(n):
		(s, t) = (input(), [])
		for (j, c) in enumerate(s):
			if c == '.':
				(sx, sy) = (i, j)
				tot += 1
				c = 'X'
			t.append(c)
		a.append(t[:])
	(dq, done) = (deque([(sx, sy)]), 0)
	while len(dq) > 0:
		now = dq.popleft()
		if done >= tot - limit:
			break
		if a[now[0]][now[1]] == 'X':
			done += 1
		else:
			continue
		a[now[0]][now[1]] = '.'
		for i in range(4):
			(tx, ty) = (dx[i] + now[0], dy[i] + now[1])
			if 0 <= tx < n and 0 <= ty < m and (a[tx][ty] == 'X'):
				dq.append((tx, ty))
	for i in a:
		print(''.join(i))
main()


def find_empty(n, m, maze):
	for x in range(m):
		for y in range(n):
			if maze[y][x] == '.':
				return (y, x)

def get_dict(n, m, maze, empty):
	distances = [[None for _ in range(m)] for _ in range(n)]
	distances[empty[0]][empty[1]] = 0
	last = {empty}
	dic = {0: empty}
	i = 0
	while len(last) != 0:
		i += 1
		dic[i] = []
		new_last = set()
		for coord in last:
			for d in ((1, 0), (-1, 0), (0, 1), (0, -1)):
				(y, x) = (coord[0] + d[0], coord[1] + d[1])
				if 0 <= y < n and 0 <= x < m:
					if maze[y][x] == '.' and distances[y][x] == None:
						distances[y][x] = i
						new_last.add((y, x))
						dic[i].append((y, x))
		last = new_last
	del dic[i]
	return dic
(n, m, k) = map(int, input().split())
maze = []
for _ in range(n):
	maze.append(list(input()))
dic = get_dict(n, m, maze, find_empty(n, m, maze))
c = 0
mx = max(dic.keys())
while True:
	l = len(dic[mx])
	if k - c <= l:
		for i in range(k - c):
			maze[dic[mx][i][0]][dic[mx][i][1]] = 'X'
		break
	else:
		for e in dic[mx]:
			maze[e[0]][e[1]] = 'X'
		c += l
	mx -= 1
for e in maze:
	print(''.join(e))


from sys import stdin

def main():
	(n, m, points) = map(int, stdin.readline().split())
	mat = []
	for _ in range(n):
		mat.append(list(stdin.readline()))
	check = [[False for _ in range(m)] for _ in range(n)]
	q = []
	end = {}
	time = 0
	for i in range(n):
		for j in range(m):
			if not check[i][j] and mat[i][j] == '.':
				q.append((i, j))
				check[i][j] = True
				while q:
					(x, y) = q.pop()
					time += 1
					dx = [-1, 1, 0, 0]
					dy = [0, 0, -1, 1]
					candidates = []
					for k in range(4):
						if 0 <= x + dx[k] < n and 0 <= y + dy[k] < m:
							if not check[x + dx[k]][y + dy[k]] and mat[x + dx[k]][y + dy[k]] == '.':
								candidates.append((x + dx[k], y + dy[k]))
								check[x + dx[k]][y + dy[k]] = True
					if not candidates:
						end[x, y] = time
					else:
						q.append((x, y))
						for p in candidates:
							q.append(p)
	keys = list(end.keys())
	keys.sort(key=lambda key: end[key])
	for i in range(points):
		(x, y) = keys[i]
		mat[x][y] = 'X'
	for r in mat:
		print(''.join(r), end='')
main()


(n, m, k) = map(int, input().split())
a = [0] * n
w = [0] * n
for i in range(n):
	a[i] = list(input())
	w[i] = [0] * m
for sx in range(n):
	if a[sx].count('.'):
		sy = a[sx].index('.')
		break
q = [0] * (n * m)
q[0] = (sx, sy)
w[sx][sy] = 1
ql = 0
qr = 1
while ql < qr:
	(x, y) = q[ql]
	ql += 1
	for (dx, dy) in ((0, 1), (0, -1), (1, 0), (-1, 0)):
		xx = x + dx
		yy = y + dy
		if xx >= 0 and xx < n and (yy >= 0) and (yy < m) and (a[xx][yy] == '.') and (w[xx][yy] == 0):
			w[xx][yy] = 1
			q[qr] = (xx, yy)
			qr += 1
for i in range(qr - 1, qr - 1 - k, -1):
	(x, y) = q[i]
	a[x][y] = 'X'
for i in range(n):
	print(*a[i], sep='')


import random, math, sys
from copy import deepcopy as dc
from bisect import bisect_left, bisect_right
from collections import Counter
input = sys.stdin.readline

def input_test():
	(n, m, k) = map(int, input().strip().split(' '))
	grid = []
	for i in range(n):
		grid.append(list(input().strip()))

	def dfsUtil(i, j):
		nonlocal n, m, k, grid
		adj = [[0, 1], [0, -1], [1, 0], [-1, 0]]
		stack = [[i, j]]
		while stack:
			if k <= 0:
				return
			(i, j) = (stack[-1][0], stack[-1][1])
			stack.pop()
			for kj in adj:
				(ni, nj) = (i + kj[0], j + kj[1])
				if 0 <= ni < n and 0 <= nj < m and (grid[ni][nj] == '.'):
					if k <= 0:
						return
					grid[ni][nj] = 'Y'
					k -= 1
					stack.append([ni, nj])
	(li, lj) = (0, 0)
	s = 0
	for i in range(n):
		for j in range(m):
			if grid[i][j] == '.':
				s += 1
				(li, lj) = (i + 1 - 1, j + 1 - 1)
	k = s - k - 1
	grid[li][lj] = 'Y'
	dfsUtil(li, lj)
	for i in range(n):
		for j in range(m):
			if grid[i][j] == 'Y':
				grid[i][j] = '.'
			elif grid[i][j] == '.':
				grid[i][j] = 'X'
	for row in grid:
		print(''.join(row))

def test():
	pass
input_test()


import queue
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
(n, m, k) = [int(x) for x in input().split()]
s = []
[s.append(input()) for i in range(n)]
vis = [[False for x in range(m)] for y in range(n)]
left = -k
for i in range(n):
	left = left + s[i].count('.')
for i in range(n):
	done = False
	for j in range(m):
		if s[i][j] == '.':
			q = queue.Queue()
			vis[i][j] = True
			left = left - 1
			q.put((i, j))
			while not q.empty():
				(x, y) = q.get()
				for i in range(4):
					if left <= 0:
						break
					nx = x + dx[i]
					ny = y + dy[i]
					if nx >= 0 and nx < n and (ny >= 0) and (ny < m):
						if not vis[nx][ny] and s[nx][ny] == '.':
							vis[nx][ny] = True
							left = left - 1
							q.put((nx, ny))
			done = True
			break
	if done:
		break
for i in range(n):
	for j in range(m):
		if s[i][j] == '.' and (not vis[i][j]):
			print('X', end='')
		else:
			print(s[i][j], end='')
	print('\n', end='')


import collections as cc
(n, m, k) = map(int, input().split())
s = []
for i in range(n):
	s.append(list(input()))
f = cc.defaultdict(set)
if k == 0:
	for i in s:
		print(''.join(i))
else:

	def dfs(graph, st):
		(visi, tr, pro, sta) = (set(), [], set(), [st])
		while sta:
			v = sta.pop()
			if v not in visi:
				visi.add(v)
				sta.extend(graph[v] - visi)
			if not v in pro:
				tr.append(v)
			pro.add(v)
		return tr
	for i in range(n):
		for j in range(m):
			if s[i][j] == '.':
				v = (i, j)
				if i > 0 and s[i - 1][j] == '.':
					u = (i - 1, j)
					f[u].add(v)
					f[v].add(u)
				if j > 0 and s[i][j - 1] == '.':
					u = (i, j - 1)
					f[u].add(v)
					f[v].add(u)
	p = dfs(f, next(iter(f.keys())))
	i = 0
	while i < k:
		v = p.pop()
		s[v[0]][v[1]] = 'X'
		i += 1
	for i in range(n):
		print(''.join(s[i]))


def main():
	(n, m, k) = map(int, input().split())
	matrix = []
	for i in range(n):
		matrix.append(input().split()[0])
	new_matrix = []
	for mat in matrix:
		xd = []
		for c in mat:
			xd.append(c)
		new_matrix.append(xd)
	matrix = new_matrix
	count = 0
	stack = []
	a = 0
	b = 0
	s = 0
	for i in range(n):
		for j in range(m):
			if matrix[i][j] == '.':
				s += 1
	for i in range(n):
		for j in range(m):
			if matrix[i][j] == '.':
				a = i
				b = j
				break
	stack = [(a, b)]
	while count < s - k:
		(a, b) = stack.pop()
		if matrix[a][b] != '.':
			continue
		matrix[a][b] = '0'
		count += 1
		if a < n - 1 and matrix[a + 1][b] == '.':
			stack.append((a + 1, b))
		if a > 0 and matrix[a - 1][b] == '.':
			stack.append((a - 1, b))
		if b < m - 1 and matrix[a][b + 1] == '.':
			stack.append((a, b + 1))
		if b > 0 and matrix[a][b - 1] == '.':
			stack.append((a, b - 1))
	for i in range(n):
		for j in range(m):
			if matrix[i][j] == '0':
				matrix[i][j] = '.'
			elif matrix[i][j] == '.':
				matrix[i][j] = 'X'
	for mat in matrix:
		for c in mat:
			print(c, end='')
		print()
main()


import sys
import heapq
from collections import deque
from collections import defaultdict
I = lambda : list(map(int, input().split(' ')))
(n, m, k) = I()
lst = [list(input()) for _ in range(n)]

def get_neighbors(node):
	(x, y) = node
	ret = []
	for (a, b) in [(x + 1, y), (x, y - 1), (x - 1, y), (x, y + 1)]:
		if a >= 0 and a < n and (b >= 0) and (b < m) and (lst[a][b] == '.'):
			ret.append((a, b))
	return ret
visited = {}
level = {}
for i in range(n):
	for j in range(m):
		if (i, j) not in visited and lst[i][j] == '.':
			node = (i, j)
			queue = deque()
			queue.append(node)
			visited[node] = 1
			level[node] = 0
			while queue:
				cur = queue.popleft()
				for w in get_neighbors(cur):
					if w in visited:
						continue
					visited[w] = 1
					level[w] = level[cur] + 1
					queue.append(w)
ll = sorted([node for node in list(level.keys())], key=lambda x: level[x])
while k:
	(x, y) = ll.pop()
	lst[x][y] = 'X'
	k -= 1
for i in range(n):
	print(''.join(lst[i]))


from functools import reduce
import os
import sys
from collections import *
from math import *
from bisect import *
from heapq import *
from io import BytesIO, IOBase
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def arr():
	return [int(i) for i in input().split()]

def sarr():
	return [int(i) for i in input()]

def starr():
	return [str(x) for x in input().split()]

def inn():
	return int(input())

def svalue():
	return tuple(map(str, input().split()))

def parr():
	return [value() for i in range(n)]
mo = 1000000007
(n, m, k) = value()
a = [[str(x) for x in input()] for i in range(n)]

def printf(visit):
	for i in range(n):
		for j in range(m):
			if a[i][j] == '.' and (i, j) not in visit:
				a[i][j] = 'X'
	for i in range(n):
		print(*a[i], sep='')

def bfs(x, y, need):
	visit = defaultdict(int)
	visit[x, y] += 1
	q = [(x, y)]
	need -= 1
	while len(q) != 0:
		res = q.pop()
		if res[0] > 0 and a[res[0] - 1][res[1]] == '.' and ((res[0] - 1, res[1]) not in visit):
			q = [(res[0] - 1, res[1])] + q
			visit[res[0] - 1, res[1]] += 1
			need -= 1
		if need == 0:
			printf(visit)
			return 1
		if res[0] < n - 1 and a[res[0] + 1][res[1]] == '.' and ((res[0] + 1, res[1]) not in visit):
			q = [(res[0] + 1, res[1])] + q
			visit[res[0] + 1, res[1]] += 1
			need -= 1
		if need == 0:
			printf(visit)
			return 1
		if res[1] > 0 and a[res[0]][res[1] - 1] == '.' and ((res[0], res[1] - 1) not in visit):
			q = [(res[0], res[1] - 1)] + q
			visit[res[0], res[1] - 1] += 1
			need -= 1
		if need == 0:
			printf(visit)
			return 1
		if res[1] < m - 1 and a[res[0]][res[1] + 1] == '.' and ((res[0], res[1] + 1) not in visit):
			q = [(res[0], res[1] + 1)] + q
			visit[res[0], res[1] + 1] += 1
			need -= 1
		if need == 0:
			printf(visit)
			return 1
	return 0
cnt = 0
for i in range(n):
	cnt += a[i].count('.')
cnt = cnt - k
for i in range(n):
	for j in range(m):
		if a[i][j] == '.':
			flag = bfs(i, j, cnt)
			if flag == 1:
				exit()


(n, m, k) = map(int, input().split())
M = [input() for i in range(n)]
T = [[] for i in range(n)]
p = 0
for i in range(n):
	for j in range(m):
		if M[i][j] == '#':
			T[i].append(M[i][j])
		else:
			T[i].append('X')
for i in range(n):
	p = p + M[i].count('#')
for i in range(n):
	for j in range(m):
		if M[i][j] == '.':
			a = i
			b = j
			break
t = n * m - p - k
l = [[a, b]]
T[a][b] = '.'
t = t - 1
while t > 0:
	r = l[0]
	del l[0]
	i = r[0]
	j = r[1]
	if i + 1 != n:
		if M[i + 1][j] == '.' and T[i + 1][j] != '.':
			l.append([i + 1, j])
			T[i + 1][j] = '.'
			t = t - 1
	if t <= 0:
		break
	if i - 1 != -1:
		if M[i - 1][j] == '.' and T[i - 1][j] != '.':
			l.append([i - 1, j])
			T[i - 1][j] = '.'
			t = t - 1
	if t <= 0:
		break
	if j + 1 != m:
		if M[i][j + 1] == '.' and T[i][j + 1] != '.':
			l.append([i, j + 1])
			T[i][j + 1] = '.'
			t = t - 1
	if t <= 0:
		break
	if j - 1 != -1:
		if M[i][j - 1] == '.' and T[i][j - 1] != '.':
			l.append([i, j - 1])
			T[i][j - 1] = '.'
			t = t - 1
for i in range(n):
	S = ''
	for j in range(m):
		S = S + T[i][j]
	print(S)


(n, m, k) = map(int, input().split())
b = [['#'] * (m + 2)] + [['#'] + list(input()) + ['#'] for _ in range(n)] + [['#'] * (m + 2)]
t = sum((l.count('.') for l in b))
st = []
for i in range(n + 2):
	for j in range(m + 2):
		if b[i][j] == '.':
			st.append((i, j))
			break
	if len(st) > 0:
		break
c = 0
while c < t - k:
	(i, j) = st.pop()
	if b[i][j] != '.':
		continue
	b[i][j] = 'O'
	c += 1
	for (x, y) in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):
		if b[x][y] == '.':
			st.append((x, y))
b = '\n'.join((''.join(l[1:-1]) for l in b[1:-1]))
print(b.replace('.', 'X').replace('O', '.'))


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]

def bfs(adj, s, k):
	vis = defaultdict(bool)
	vis[s] = True
	qu = [s]
	ans = set()
	while len(qu) != 0:
		if len(ans) == k:
			return ans
		e = qu.pop(0)
		ans.add(e)
		for i in adj[e]:
			if vis[i] != True:
				qu.append(i)
				vis[i] = True
	return ans
(r, c, k) = value()
a = []
for i in range(r):
	a.append(list(input()))
adj = defaultdict(list)
for i in range(r):
	for j in range(c):
		if a[i][j] == '.':
			node = (i, j)
			if i + 1 < r and a[i + 1][j] == '.':
				adj[i, j].append((i + 1, j))
				adj[i + 1, j].append((i, j))
			if j + 1 < c and a[i][j + 1] == '.':
				adj[i, j].append((i, j + 1))
				adj[i, j + 1].append((i, j))
ans = set()
k = len(adj) - k
for i in adj:
	ans = bfs(adj, i, k)
	if len(ans) == k:
		break
for i in adj:
	if i not in ans:
		a[i[0]][i[1]] = 'X'
for i in a:
	print(*i, sep='')


from collections import defaultdict, deque

def helper(row, col):
	queue = deque([(row, col)])
	visited = {(row, col)}
	while queue:
		(r, c) = queue.popleft()
		for (x, y) in [(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)]:
			if 0 <= x < n and 0 <= y < m and (grid[x][y] == '.') and ((x, y) not in visited):
				queue.append((x, y))
				visited.add((x, y))
				if len(visited) > s - k:
					grid[x][y] = 'X'
(n, m, k) = map(int, input().split())
grid = []
s = 0
for i in range(n):
	grid.append(list(input()))
	for j in range(m):
		if grid[i][j] == '.':
			s += 1
			(row, col) = (i, j)
if k:
	helper(row, col)
for i in range(n):
	print(''.join(grid[i]))


import sys
LI = lambda : list(map(int, sys.stdin.readline().strip('\n').split()))
MI = lambda : map(int, sys.stdin.readline().strip('\n').split())
SI = lambda : sys.stdin.readline().strip('\n')
II = lambda : int(sys.stdin.readline().strip('\n'))

def validate(i, j):
	global inp, n, m
	return i >= 0 and i < n and (j >= 0) and (j < m) and (inp[i][j] == '.')

def bfs(ui, uj):
	global inp, cnt, k
	(q, ind, num) = ([(ui, uj)], 0, 0)
	while ind < len(q):
		(i, j) = q[ind]
		ind += 1
		if not validate(i, j):
			continue
		inp[i][j] = 'V'
		num += 1
		if num == cnt - k:
			for i in range(n):
				for j in range(m):
					if inp[i][j] == 'V':
						inp[i][j] = '.'
					elif inp[i][j] == '.':
						inp[i][j] = 'X'
				print(''.join(inp[i]))
			break
		if validate(i - 1, j):
			q.append((i - 1, j))
		if validate(i, j - 1):
			q.append((i, j - 1))
		if validate(i + 1, j):
			q.append((i + 1, j))
		if validate(i, j + 1):
			q.append((i, j + 1))
(n, m, k) = MI()
(cnt, inp) = (0, [])
for i in range(n):
	s = list(SI())
	cnt += s.count('.')
	inp.append(s)
for i in range(n):
	for j in range(m):
		if inp[i][j] == '.':
			(a, b) = (i + 1, j + 1)
			break
	try:
		if a:
			break
	except:
		pass
bfs(a - 1, b - 1)


import sys

def explore_dfs(adj_list, visited, stack, c):
	node = stack.pop()
	if visited[node]:
		return c
	visited[node] = True
	c += 1
	for e in adj_list[node]:
		if visited[e] == False:
			stack.append(e)
	return c

def answer(n, m, k, mat):
	adj_list = [[] for _ in range(n * m + 1)]
	visited = [False for _ in range(n * m + 1)]
	s = 0
	for row in range(n):
		for col in range(m):
			char_p = mat[row][col]
			if char_p == '.':
				s += 1
				pos_p = row * m + col + 1
				valid_node = pos_p
				if row - 1 >= 0:
					pos_c = (row - 1) * m + col + 1
					char_c = mat[row - 1][col]
					if char_c == char_p == '.':
						adj_list[pos_p].append(pos_c)
				if row + 1 < n:
					pos_c = (row + 1) * m + col + 1
					char_c = mat[row + 1][col]
					if char_c == char_p == '.':
						adj_list[pos_p].append(pos_c)
				if col - 1 >= 0:
					pos_c = row * m + (col - 1) + 1
					char_c = mat[row][col - 1]
					if char_c == char_p == '.':
						adj_list[pos_p].append(pos_c)
				if col + 1 < m:
					pos_c = row * m + (col + 1) + 1
					char_c = mat[row][col + 1]
					if char_c == char_p == '.':
						adj_list[pos_p].append(pos_c)
	stack = [valid_node]
	c = 0
	while c < s - k:
		c = explore_dfs(adj_list, visited, stack, c)
	for row in range(n):
		for col in range(m):
			pos_p = row * m + col + 1
			if mat[row][col] == '.' and visited[pos_p] == False:
				mat[row][col] = 'X'
	for row in mat:
		print(''.join(row))
	return

def main():
	(n, m, k) = map(int, sys.stdin.readline().split())
	mat = []
	for i in range(n):
		mat.append(list(sys.stdin.readline().rstrip()))
	answer(n, m, k, mat)
	return

def main2():
	f = open('input.txt')
	(n, m, k) = map(int, f.readline().split())
	mat = []
	for i in range(n):
		mat.append(list(f.readline().rstrip()))
	answer(n, m, k, mat)
	f.close()
	return
main()


(N, M, K) = [int(slowo) for slowo in input().split()]
odw = [[False] * M for _ in range(N)]
P = []

def czy(i, j):
	return 0 <= i < N and 0 <= j < M

def wypisz():
	for wiersz in P:
		print(''.join(wiersz))
kropki = 0
for _ in range(N):
	wiersz = input()
	P.append(list(wiersz))
	kropki += wiersz.count('.')
if kropki == 0 or K == 0:
	wypisz()
	exit()
kolejka = []
ile_odw = 0
for i in range(N):
	koniec = False
	for j in range(M):
		if P[i][j] == '.':
			kolejka.append((i, j))
			odw[i][j] = True
			ile_odw = 1
			koniec = True
			break
	if koniec:
		break
nr = 0
while nr < len(kolejka):
	(i, j) = kolejka[nr]
	ruch_w = [-1, 1, 0, 0]
	ruch_k = [0, 0, -1, 1]
	for ruch in range(4):
		ii = i + ruch_w[ruch]
		jj = j + ruch_k[ruch]
		if czy(ii, jj) and P[ii][jj] == '.' and (not odw[ii][jj]) and (ile_odw < kropki - K):
			odw[ii][jj] = True
			ile_odw += 1
			kolejka.append((ii, jj))
	nr += 1
for i in range(N):
	for j in range(M):
		if not odw[i][j] and P[i][j] == '.':
			P[i][j] = 'X'
wypisz()


from collections import deque
(n, m, k) = map(int, input().split())
a = [list(input()) for i in range(n)]

def findEmpty():
	for i in range(n):
		for j in range(m):
			if a[i][j] == '.':
				return (i, j)
node = []
idx = 0
vis = [[0] * m for i in range(n)]
(r, c) = findEmpty()
vis[r][c] = 1
p = deque([(r, c, -1)])
while p:
	(row, col, father) = p.popleft()
	d = [(1, 0), (-1, 0), (0, 1), (0, -1)]
	sz = 0
	for (dx, dy) in d:
		(xx, yy) = (row + dx, col + dy)
		if 0 <= xx < n and 0 <= yy < m and (not vis[xx][yy]) and (a[xx][yy] != '#'):
			vis[xx][yy] = 1
			sz += 1
			p.append((xx, yy, idx))
	node.append([sz, None, father, row, col])
	idx += 1
q = deque(filter(lambda x: x[0] == 0, node))
for i in range(k):
	n = q.popleft()
	node[n[2]][0] -= 1
	if node[n[2]][0] == 0:
		q.append(node[n[2]])
	a[n[3]][n[4]] = 'X'
for line in a:
	print(*line, sep='')


s = list(map(int, input().split()))
(n, m, k) = (s[0], s[1], s[2])
g = []
(x, y) = (0, 0)
dots = 0
for i in range(n):
	line = []
	s = input()
	for j in range(m):
		if s[j] == '.':
			dots += 1
			y = j
			x = i
		line.append(s[j])
	g.append(line)

def valid(x, y):
	if x < 0 or y < 0 or x == n or (y == m):
		return False
	if g[x][y] == '.':
		return True
	return False
di = [-1, 1, 0, 0]
dj = [0, 0, -1, 1]
colored = 0
q = []
q.append((x, y))
while len(q) != 0:
	(x, y) = q.pop()
	colored += 1
	if colored > dots - k:
		g[x][y] = 'X'
	else:
		g[x][y] = '0'
	for i in range(4):
		if valid(x + di[i], y + dj[i]):
			q.append((x + di[i], y + dj[i]))
			g[x + di[i]][y + dj[i]] = '1'
for i in range(n):
	for j in range(m):
		if g[i][j] == '0':
			print('.', end='')
		else:
			print(g[i][j], end='')
	print()


from sys import stdin, stdout

def INI():
	return int(stdin.readline())

def INL():
	return [int(_) for _ in stdin.readline().split()]

def INS():
	return stdin.readline()

def MOD():
	return pow(10, 9) + 7

def OPS(ans):
	stdout.write(str(ans) + '\n')

def OPL(ans):
	[stdout.write(str(_) + ' ') for _ in ans]
	stdout.write('\n')
from collections import deque

def helper(i):
	q = deque()
	q.append(i)
	X[i[0]][i[1]] = True
	c = 1
	while q:
		(i, j) = q.popleft()
		for (i, j) in [[i + 1, j], [i - 1, j], [i, j + 1], [i, j - 1]]:
			if 0 <= i < n and 0 <= j < m and (X[i][j] == '.'):
				q.append([i, j])
				X[i][j] = True
				c += 1
				if c > s - k:
					X[i][j] = 'X'
(n, m, k) = INL()
X = []
i = -1
s = 0
for _ in range(n):
	x = input()
	s += x.count('.')
	if i == -1 and '.' in x:
		i = [_, x.index('.')]
	X.append(list(x))
if k:
	helper(i)
for _ in range(n):
	x = ''
	for __ in range(m):
		if X[_][__] == True:
			x += '.'
		else:
			x += X[_][__]
	X[_] = x
for _ in X:
	print(_)


import sys
sys.setrecursionlimit(10 ** 6)
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
(n, m, k) = map(int, input().split())
maze = []
tot = 0
dx = [1, -1, 0, 0]
dy = [0, 0, -1, 1]
for i in range(n):
	maze.append(list(input().strip()))
	tot += maze[i].count('.')
vis = [[0] * m for i in range(n)]
cnt = 0

@bootstrap
def dfs(i, j):
	global cnt
	vis[i][j] = 1
	for l in range(4):
		ii = dx[l] + i
		jj = dy[l] + j
		if n > ii >= 0 and m > jj >= 0 and (maze[ii][jj] == '.'):
			cnt += 1
			if cnt > tot - k:
				break
			maze[ii][jj] = 'X'
			yield dfs(ii, jj)
	yield 0
f = 0
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.':
			cnt += 1
			if cnt > tot - k:
				f = 1
				break
			maze[i][j] = 'X'
			dfs(i, j)
	if f:
		break
for i in range(n):
	for j in range(m):
		if maze[i][j] == 'X':
			maze[i][j] = '.'
		elif maze[i][j] == '.':
			maze[i][j] = 'X'
for i in maze:
	print(''.join(i))


(n, m, k) = map(int, input().split())
grid = []
hashes = 0
for i in range(n):
	grid.append(input())
	hashes += grid[i].count('#')
(s_r, s_c) = (0, 0)
for i in range(n):
	if '.' in grid[i]:
		(s_r, s_c) = (i, grid[i].index('.'))
		break
vn = 1
remaining = n * m - k - hashes
visited = set([(s_r, s_c)])
q = [(s_r, s_c)] if grid[s_r][s_c] == '.' else []
while len(q) > 0:
	if vn == remaining:
		break
	(s_r, s_c) = q.pop()
	if s_r > 0 and grid[s_r - 1][s_c] == '.' and ((s_r - 1, s_c) not in visited):
		q.append((s_r - 1, s_c))
		visited.add((s_r - 1, s_c))
		vn += 1
		if vn == remaining:
			break
	if s_r < n - 1 and grid[s_r + 1][s_c] == '.' and ((s_r + 1, s_c) not in visited):
		q.append((s_r + 1, s_c))
		visited.add((s_r + 1, s_c))
		vn += 1
		if vn == remaining:
			break
	if s_c > 0 and grid[s_r][s_c - 1] == '.' and ((s_r, s_c - 1) not in visited):
		q.append((s_r, s_c - 1))
		visited.add((s_r, s_c - 1))
		vn += 1
		if vn == remaining:
			break
	if s_c < m - 1 and grid[s_r][s_c + 1] == '.' and ((s_r, s_c + 1) not in visited):
		q.append((s_r, s_c + 1))
		visited.add((s_r, s_c + 1))
		vn += 1
		if vn == remaining:
			break
for i in range(n):
	row = []
	for j in range(m):
		if grid[i][j] == '.' and (i, j) in visited:
			row.append('.')
		elif grid[i][j] == '.' and (i, j) not in visited:
			row.append('X')
		else:
			row.append('#')
	print(''.join(row))


from collections import deque
(n, m, k) = map(int, input().split())
visited = [[False for i in range(m)] for j in range(n)]
maze = [[None for i in range(m)] for j in range(n)]
(total, cnt) = (0, 0)
Starting_Point = None
for i in range(n):
	l = list(input())
	for j in range(m):
		if l[j] == '.':
			maze[i][j] = 'X'
			Starting_Point = (i, j)
			total += 1
		else:
			maze[i][j] = l[j]
q = deque()
q.append(Starting_Point)
while q:
	(i, j) = q.popleft()
	if i < 0 or i >= n or j < 0 or (j >= m) or visited[i][j] or (cnt == total - k):
		continue
	if maze[i][j] == 'X':
		maze[i][j] = '.'
		cnt = cnt + 1
		q.append((i, j - 1))
		q.append((i, j + 1))
		q.append((i - 1, j))
		q.append((i + 1, j))
for i in maze:
	print(''.join(i))


from collections import deque as dq

class Graph:

	def __init__(self, n=0, m=0):
		self.g = [None for i in range(n)]
		self.vis = [[False for j in range(m)] for i in range(n)]
		self.dx = (1, 0, -1, 0)
		self.dy = (0, 1, 0, -1)

	def affiche(self):
		for i in range(len(self.g)):
			print(''.join(self.g[i]))

	def readG(self, n):
		for i in range(n):
			self.g[i] = list(input())

	def get(self, i, j):
		return self.g[i][j]

	def dfsIt(self, u):
		global k, A
		L = dq()
		A = []
		L.append(u)
		while len(L) != 0:
			u = L.pop()
			self.vis[u[0]][u[1]] = True
			b = True
			for t in range(4):
				x = u[0] + self.dx[t]
				y = u[1] + self.dy[t]
				if x >= 0 and x < n and (y >= 0) and (y < m) and (not self.vis[x][y]) and (self.g[x][y] != '#'):
					self.vis[x][y] = True
					L.append((x, y))
					b = False
			if b and k > 0:
				k -= 1
				self.g[u[0]][u[1]] = 'X'
			else:
				A.append(u)
(n, m, k) = map(int, input().split())
g = Graph(n, m)
g.readG(n)

def f():
	global n, m, g
	for i in range(n):
		for j in range(m):
			if g.get(i, j) == '.':
				return (i, j)
g.dfsIt(f())
while k != 0:
	k -= 1
	u = A.pop()
	g.g[u[0]][u[1]] = 'X'
g.affiche()


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
INF = 999999999999999999999999

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	for _ in range(tc):
		(n, m, k) = ria()
		grid = []
		visited = []
		for i in range(n):
			grid.append(list(rs()))
			visited.append([False] * m)

		def legit(x, y):
			if 0 <= x < n and 0 <= y < m and (grid[x][y] == '.'):
				return True
			return False
		dir = [[1, 0], [-1, 0], [0, 1], [0, -1]]
		order = deque([])

		def bfs(start):
			(px, py) = start
			q = deque([start])
			visited[px][py] = True
			while q:
				(px, py) = q.popleft()
				order.append([px, py])
				for (x, y) in dir:
					if legit(px + x, py + y) and (not visited[px + x][py + y]):
						visited[px + x][py + y] = True
						q.append([px + x, py + y])
		flag = 0
		for i in range(n):
			for j in range(m):
				if grid[i][j] == '.':
					bfs([i, j])
					flag = 1
					break
			if flag:
				break
		for i in range(k):
			(mx, my) = order.pop()
			grid[mx][my] = 'X'
		for i in grid:
			ws(''.join(i))
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

	def flush(self):
		os.write(self._fd, self.buffer.getvalue())
		(self.buffer.truncate(0), self.buffer.seek(0))

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


import sys
import time
from collections import deque

def read_line(cast=None):
	if cast is not None:
		return cast(input().strip())
	else:
		return input().strip()

def read_list(cast=int):
	return list(map(cast, read_line().split()))
INTMAX = 1000000007

def solve(n, m, k):
	nm = n * m
	tab = []
	for i in range(n):
		l = list(read_line())
		tab.append(l)
	g = [[] for _ in range(nm)]
	d = [(0, 1), (0, -1), (1, 0), (-1, 0)]
	sfn = set()
	ln = None
	for i in range(n):
		for j in range(m):
			if tab[i][j] == '.':
				cn = m * i + j
				sfn.add(cn)
				if ln is None:
					ln = cn
				for (di, dj) in d:
					(ii, jj) = (i + di, j + dj)
					if ii >= 0 and ii < n and (jj >= 0) and (jj < m) and (tab[ii][jj] == '.'):
						g[cn].append(m * ii + jj)
	st = [ln]
	vis = set()
	while len(sfn) > k:
		cn = st.pop()
		vis.add(cn)
		if cn in sfn:
			sfn.remove(cn)
		for nn in g[cn]:
			(ii, jj) = (nn // m, nn % m)
			if tab[ii][jj] == '.' and nn not in vis:
				st.append(nn)
	for cn in sfn:
		(i, j) = (cn // m, cn % m)
		tab[i][j] = 'X'
	printTab(n, m, tab)

def printTab(n, m, tab):
	v = 0
	for i in range(n):
		s = ''
		for j in range(m):
			s += tab[i][j]
			if tab[i][j] == 'X':
				v += 1
		print(s)
(n, m, k) = read_list()
solve(n, m, k)


(n, m, k) = map(int, input().split())
a = n * [0]
d = n * [0]
f = -1
for i in range(n):
	a[i] = input()
	d[i] = list(a[i])
	if f == -1:
		if '.' in a[i]:
			f = [i, a[i].index('.')]
if k:
	see = n * [1]
	for i in range(n):
		see[i] = m * [1]
	see[f[0]][f[1]] = 0
	o = 0
	q = [f]
	while o < len(q):
		w = q[o]
		if w[0] > 0:
			if a[w[0] - 1][w[1]] == '.' and see[w[0] - 1][w[1]]:
				q += [[w[0] - 1, w[1]]]
				see[w[0] - 1][w[1]] = 0
		if w[0] < n - 1:
			if a[w[0] + 1][w[1]] == '.' and see[w[0] + 1][w[1]]:
				q += [[w[0] + 1, w[1]]]
				see[w[0] + 1][w[1]] = 0
		if w[1] > 0:
			if a[w[0]][w[1] - 1] == '.' and see[w[0]][w[1] - 1]:
				q += [[w[0], w[1] - 1]]
				see[w[0]][w[1] - 1] = 0
		if w[1] < m - 1:
			if a[w[0]][w[1] + 1] == '.' and see[w[0]][w[1] + 1]:
				q += [[w[0], w[1] + 1]]
				see[w[0]][w[1] + 1] = 0
		o += 1
	for i in q[-k:]:
		d[i[0]][i[1]] = 'X'
for i in range(n):
	r = ''
	for j in d[i]:
		r += j
	print(r)


import queue
(n, m, k) = list(map(int, input().split()))
a = [['a'] * m for _ in range(n)]
visited = [[False] * m for _ in range(n)]
s = 0
start = (-1, -1)
for i in range(n):
	a[i] = list(input().rstrip())
	if k > 0:
		for j in range(m):
			if a[i][j] == '.':
				s += 1
				start = (i, j)
d = s - k
if k > 0 and d > 0:
	q = queue.Queue()
	q.put(start)
	visited[start[0]][start[1]] = True
	d -= 1
	while d > 0:
		cur = q.get()
		(i, j) = cur
		if i > 0 and a[i - 1][j] == '.' and (not visited[i - 1][j]):
			q.put((i - 1, j))
			visited[i - 1][j] = True
			d -= 1
			if d == 0:
				break
		if j > 0 and a[i][j - 1] == '.' and (not visited[i][j - 1]):
			q.put((i, j - 1))
			visited[i][j - 1] = True
			d -= 1
			if d == 0:
				break
		if i < n - 1 and a[i + 1][j] == '.' and (not visited[i + 1][j]):
			q.put((i + 1, j))
			visited[i + 1][j] = True
			d -= 1
			if d == 0:
				break
		if j < m - 1 and a[i][j + 1] == '.' and (not visited[i][j + 1]):
			q.put((i, j + 1))
			visited[i][j + 1] = True
			d -= 1
			if d == 0:
				break
	for i in range(n):
		for j in range(m):
			if a[i][j] == '.' and (not visited[i][j]):
				a[i][j] = 'X'
for row in a:
	print(''.join(row))


def solve():
	(n, m, k) = map(int, input().split())
	Maze = [list(input()) for row in range(n)]
	bfs(Maze, n, m, k)
	print('\n'.join((''.join(row) for row in Maze)))

def bfs(M, n, m, k):
	(r, c) = findEmptyCell(M)
	visited = [[False for col in range(m)] for row in range(n)]
	visited[r][c] = True
	queue = deque()
	queue.append((r, c))
	s = sum((sum((x == '.' for x in row), 0) for row in M))
	toConnect = s - k - 1
	while queue:
		coords = queue.popleft()
		for (r, c) in neighbors(coords, n, m):
			if not visited[r][c] and M[r][c] == '.':
				visited[r][c] = True
				queue.append((r, c))
				toConnect -= 1
				if toConnect < 0:
					M[r][c] = 'X'

def findEmptyCell(M):
	for (r, row) in enumerate(M):
		for (c, cell) in enumerate(row):
			if cell == '.':
				return (r, c)

def neighbors(coords, n, m):
	(r, c) = coords
	if r > 0:
		yield (r - 1, c)
	if r < n - 1:
		yield (r + 1, c)
	if c > 0:
		yield (r, c - 1)
	if c < m - 1:
		yield (r, c + 1)
from collections import deque
solve()


def solve(matrix, n, m, k):
	from collections import deque
	answer = []
	tovisit = deque()
	quit = False
	visited = set()
	for i in range(n):
		if quit:
			break
		for j in range(m):
			if matrix[i][j] == '.':
				tovisit.append((i, j))
				quit = True
				break
	while len(tovisit) > 0:
		(i, j) = tovisit.pop()
		if (i, j) in visited:
			continue
		answer.append((i, j))
		visited.add((i, j))
		for a in [[-1, 0], [1, 0], [0, 1], [0, -1]]:
			if 0 <= i + a[0] < n and 0 <= j + a[1] < m:
				if matrix[i + a[0]][j + a[1]] == '.':
					if (i + a[0], j + a[1]) not in visited:
						tovisit.append((i + a[0], j + a[1]))
	for i in range(k):
		matrix[answer[-i - 1][0]][answer[-i - 1][1]] = 'X'
	for x in matrix:
		print(''.join(x))

def main():
	(n, m, k) = tuple(map(int, input().rstrip().split()))
	matrix = []
	for i in range(n):
		matrix.append(list(input().rstrip()))
	solve(matrix, n, m, k)
main()


from sys import stdin, stdout
from collections import *
from math import gcd, floor, ceil
st = lambda : list(stdin.readline().strip())
li = lambda : list(map(int, stdin.readline().split()))
mp = lambda : map(int, stdin.readline().split())
inp = lambda : int(stdin.readline())
pr = lambda n: stdout.write(str(n) + '\n')
mod = 1000000007
INF = float('inf')
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def solve():

	def valid(x, y):
		if x < 0 or y < 0 or x >= n or (y >= m):
			return False
		if v[x][y]:
			return False
		return True

	def DFS(i, j):
		stack = [(i, j)]
		size = 1
		v[i][j] = 1
		while stack:
			if size == total:
				return
			(a, b) = stack.pop()
			for p in range(4):
				(newA, newB) = (a + dx[p], b + dy[p])
				if valid(newA, newB):
					stack.append((newA, newB))
					size += 1
					v[newA][newB] = 1
					if size == total:
						return
	(n, m, k) = mp()
	v = []
	l = []
	has = 0
	for i in range(n):
		s = st()
		x = [0] * m
		for j in range(m):
			if s[j] == '#':
				x[j] = 1
				has += 1
		v.append(x)
		l.append(s)
	total = n * m - has - k
	flag = 0
	for i in range(n):
		for j in range(m):
			if l[i][j] == '.' and (not v[i][j]):
				DFS(i, j)
				flag = 1
				break
		if flag:
			break
	for i in range(n):
		for j in range(m):
			if not v[i][j] and l[i][j] == '.':
				l[i][j] = 'X'
	for i in l:
		print(*i, sep='')
for _ in range(1):
	solve()


import sys

def solve(n, m, k, grid, r, c):
	move = [(0, 1), (0, -1), (1, 0), (-1, 0)]
	visited = [[False for i in range(m)] for j in range(n)]
	q = [(r, c)]
	grid[r][c] = 'O'
	visited[r][c] = True
	k -= 1
	while k != 0 and len(q) != 0:
		(r, c) = q.pop()
		for i in range(4):
			(x, y) = (r + move[i][0], c + move[i][1])
			if x >= 0 and x < n and (y >= 0) and (y < m) and (not visited[x][y]) and (grid[x][y] == '.'):
				q.append((x, y))
				grid[x][y] = 'O'
				visited[x][y] = True
				k -= 1
				if k == 0:
					break
(n, m, k) = list(map(int, sys.stdin.readline().split()))
grid = []
for i in range(n):
	s = list(input())
	grid.append(s)
r = 0
c = 0
cnt = 0
find = False
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			cnt += 1
			if not find:
				(r, c) = (i, j)
				find = True
solve(n, m, cnt - k, grid, r, c)
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			grid[i][j] = 'X'
for i in range(n):
	for j in range(m):
		if grid[i][j] == 'O':
			grid[i][j] = '.'
for i in range(n):
	print(''.join(map(str, grid[i])))


class Solution:

	def __init__(self, grid, n, m, k):
		self.grid = grid
		self.n = n
		self.m = m
		self.k = k
		self.neighbors = [(-1, 0), (1, 0), (0, -1), (0, 1)]
		self.visited = [[False] * m for _ in range(n)]

	def solve(self):
		free_cells = 0
		for row in range(self.n):
			for col in range(self.m):
				if self.grid[row][col] == '.':
					free_cells += 1
					start = (row, col)
		self.num2visit = free_cells - self.k
		self.bfs(*start)
		for row in range(self.n):
			for col in range(self.m):
				if not self.visited[row][col] and self.grid[row][col] == '.':
					self.grid[row][col] = 'X'
		ans = []
		for row in self.grid:
			ans.append(''.join(row))
		return '\n'.join(ans)

	def bfs(self, row, col):
		queue = [(row, col)]
		while queue:
			(x, y) = queue.pop()
			if self.visited[x][y]:
				continue
			self.visited[x][y] = True
			self.num2visit -= 1
			new_queue = []
			for (dr, dc) in self.neighbors:
				r = x + dr
				c = y + dc
				if 0 <= r < self.n and 0 <= c < self.m and (self.grid[r][c] == '.'):
					if not self.visited[r][c]:
						new_queue.append((r, c))
			queue += new_queue
			if self.num2visit == 0:
				return

def main():
	(n, m, k) = map(int, input().split())
	grid = []
	for _ in range(n):
		grid.append(list(input()))
	sol = Solution(grid, n, m, k)
	ans = sol.solve()
	print(ans)
main()


(n, m, k) = map(int, input().split())
L = []
for i in range(n):
	L.append(list(input()))
st = (-1, -1)
emp = -1
for i in range(n):
	for j in range(m):
		if L[i][j] == '.':
			st = (i, j)
			emp += 1
levels = [[st]]
L[st[0]][st[1]] = 'Y'
while emp != 0 and k != 0:
	X = []
	for (i, j) in levels[-1]:
		if i != 0:
			if L[i - 1][j] == '.':
				L[i - 1][j] = 'Y'
				X.append((i - 1, j))
				emp -= 1
		if i != n - 1:
			if L[i + 1][j] == '.':
				L[i + 1][j] = 'Y'
				X.append((i + 1, j))
				emp -= 1
		if j != 0:
			if L[i][j - 1] == '.':
				L[i][j - 1] = 'Y'
				X.append((i, j - 1))
				emp -= 1
		if j != m - 1:
			if L[i][j + 1] == '.':
				L[i][j + 1] = 'Y'
				X.append((i, j + 1))
				emp -= 1
	levels.append(X)
for i in range(n):
	for j in range(m):
		if L[i][j] == 'Y':
			L[i][j] = '.'
X = []
while k != 0:
	if X == []:
		X = levels.pop()
	(i, j) = X.pop()
	L[i][j] = 'X'
	k -= 1
for i in range(n):
	print(''.join(L[i]))


from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from itertools import permutations
from datetime import datetime
from math import ceil, sqrt, log, gcd

def ii():
	return int(input())

def si():
	return input()

def mi():
	return map(int, input().split())

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
abd = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
mod = 1000000007
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def powmod(a, b):
	a %= mod
	if a == 0:
		return 0
	res = 1
	while b > 0:
		if b & 1:
			res = res * a % mod
		a = a * a % mod
		b >>= 1
	return res

def main():
	(n, m, k) = mi()
	a = []
	for i in range(n):
		a.append(list(si()))
	vis = [[0 for i in range(505)] for j in range(505)]
	s = 0
	for i in range(n):
		for j in range(m):
			if a[i][j] == '.':
				s += 1
				x = i
				y = j
	s -= k
	if s > 0:
		b = []
		b.append([x, y])
		c = 1
		vis[x][y] = 1
		f = 0
		while len(b) > 0:
			x = b[0][0]
			y = b[0][1]
			del b[0]
			for i in range(4):
				x1 = x + dx[i]
				y1 = y + dy[i]
				if x1 < 0 or y1 < 0 or x1 >= n or (y1 >= m) or (a[x1][y1] != '.') or vis[x1][y1]:
					continue
				if c >= s:
					f = 1
					break
				c += 1
				vis[x1][y1] = 1
				b.append([x1, y1])
			if f:
				break
		for i in range(n):
			for j in range(m):
				if a[i][j] == '.' and vis[i][j] == 0:
					a[i][j] = 'X'
	for i in range(n):
		for j in range(m):
			print(a[i][j], end='')
		print()
main()


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def main():
	(n, m, k) = LI()
	aa = [[c for c in S()] for _ in range(n)]

	def search(s):
		d = collections.defaultdict(lambda : inf)
		d[s] = 0
		q = []
		heapq.heappush(q, (0, s))
		v = collections.defaultdict(bool)
		while len(q):
			(k, u) = heapq.heappop(q)
			if v[u]:
				continue
			v[u] = True
			cy = u[0]
			cx = u[1]
			for (dy, dx) in dd:
				ny = cy + dy
				nx = cx + dx
				uv = (ny, nx)
				if v[uv] or ny < 0 or ny >= n or (nx < 0) or (nx >= m) or (aa[ny][nx] == '#'):
					continue
				vd = k + 1
				if d[uv] > vd:
					d[uv] = vd
					heapq.heappush(q, (vd, uv))
		return d
	s = None
	for i in range(n):
		for j in range(m):
			if aa[i][j] == '.':
				s = (i, j)
				break
		if s:
			break
	d = search(s)
	va = sorted(d.items(), key=lambda x: [-x[1], x[0]])
	for (t, v) in va[:k]:
		(i, j) = t
		aa[i][j] = 'X'
	return '\n'.join(map(lambda x: ''.join(x), aa))
print(main())


class Queue:

	def __init__(self):
		self.list = []

	def push(self, value):
		self.list.append(value)

	def pop(self):
		return self.list.pop(0)

	def top(self):
		return self.list[0]

	def empty(self):
		return len(self.list) == 0

class Cell:

	def __init__(self, row, column):
		self.row = row
		self.column = column

	def neighbors(self):
		return [Cell(self.row + 1, self.column), Cell(self.row - 1, self.column), Cell(self.row, self.column + 1), Cell(self.row, self.column - 1)]
(rows, columns, k) = map(int, input().split())
top_row = ''.join(['#' for i in range(2 + columns)])
bottom_row = ''.join(['#' for i in range(2 + columns)])
matrix = [top_row] + ['#' + input() + '#' for i in range(rows)] + [bottom_row]
matrix = [list(i) for i in matrix]
emptyCellNum = 0
firstEmptyCell = False
for i in range(rows):
	for j in range(columns):
		if matrix[i + 1][j + 1] == '.':
			emptyCellNum += 1
			if not firstEmptyCell:
				startCell = Cell(i + 1, j + 1)
				firstEmptyCell = True
degree = [[0 for i in range(2 + columns)] for j in range(2 + rows)]
visited = [[False for i in range(2 + columns)] for j in range(2 + rows)]

def BFS(start):
	counter = 1
	q = Queue()
	q.push(start)
	visited[start.row][start.column] = True
	while not q.empty():
		cell = q.pop()
		for neighbor in cell.neighbors():
			if matrix[neighbor.row][neighbor.column] == '.':
				if not visited[neighbor.row][neighbor.column]:
					if counter == emptyCellNum - k:
						return
					visited[neighbor.row][neighbor.column] = True
					counter += 1
					q.push(neighbor)
BFS(startCell)
for i in range(1, 1 + rows):
	for j in range(1, 1 + columns):
		if matrix[i][j] == '.' and visited[i][j] == False:
			matrix[i][j] = 'X'
for i in range(2 + rows):
	matrix[i] = ''.join(matrix[i][1:-1])
print('\n'.join(matrix[1:-1]))


from collections import deque

def main():
	grid = []

	def solve(grid, k):
		(R, C) = (len(grid), len(grid[0]))
		starts = []
		s = 0
		for i in range(R):
			for j in range(C):
				if grid[i][j] == '.':
					starts.append((i, j))
					s += 1

		def isValid(a, b):
			if a >= 0 and a < R and (b >= 0) and (b < C) and (grid[a][b] == '.') and ((a, b) not in visited):
				return True
			return False
		moves = [(-1, 0), (0, -1), (1, 0), (0, 1)]
		visited = set()
		q = deque()
		q.append(starts[0])
		counter = 0
		while counter < s - k:
			(x, y) = q.popleft()
			if (x, y) not in visited:
				counter += 1
				visited.add((x, y))
				for (dx, dy) in moves:
					(nx, ny) = (x + dx, y + dy)
					if isValid(nx, ny):
						q.append((nx, ny))
		for i in range(R):
			for j in range(C):
				if (i, j) in visited or grid[i][j] == '#':
					continue
				else:
					grid[i][j] = 'X'
		return grid
	(n, m, k) = list(map(lambda x: int(x), input().split()))
	for i in range(n):
		temp = []
		for j in input():
			temp.append(j)
		grid.append(temp)
	ans = solve(grid, k)
	for i in ans:
		print(''.join(i))
py2 = round(0.5)
if py2:
	from future_builtins import ascii, filter, hex, map, oct, zip
	range = xrange
import os, sys
from io import IOBase, BytesIO
BUFSIZE = 8192

class FastIO(BytesIO):
	newlines = 0

	def __init__(self, file):
		self._file = file
		self._fd = file.fileno()
		self.writable = 'x' in file.mode or 'w' in file.mode
		self.write = super(FastIO, self).write if self.writable else None

	def _fill(self):
		s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
		self.seek((self.tell(), self.seek(0, 2), super(FastIO, self).write(s))[0])
		return s

	def read(self):
		while self._fill():
			pass
		return super(FastIO, self).read()

	def readline(self):
		while self.newlines == 0:
			s = self._fill()
			self.newlines = s.count(b'\n') + (not s)
		self.newlines -= 1
		return super(FastIO, self).readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.getvalue())
			(self.truncate(0), self.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		if py2:
			self.write = self.buffer.write
			self.read = self.buffer.read
			self.readline = self.buffer.readline
		else:
			self.write = lambda s: self.buffer.write(s.encode('ascii'))
			self.read = lambda : self.buffer.read().decode('ascii')
			self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from types import GeneratorType

def bootstrap(func, stack=[]):

	def wrapped_function(*args, **kwargs):
		if stack:
			return func(*args, **kwargs)
		else:
			call = func(*args, **kwargs)
			while True:
				if type(call) is GeneratorType:
					stack.append(call)
					call = next(call)
				else:
					stack.pop()
					if not stack:
						break
					call = stack[-1].send(call)
			return call
	return wrapped_function
main()


from sys import stdin
__author__ = 'artyom'

def read_int_ary():
	return map(int, stdin.readline().strip().split())

def dfs(graph, start):
	(visited, tree, processed, stack) = (set(), [], set(), [start])
	while stack:
		vertex = stack.pop()
		if vertex not in visited:
			visited.add(vertex)
			stack.extend(graph[vertex] - visited)
		if not vertex in processed:
			tree.append(vertex)
		processed.add(vertex)
	return tree
(n, m, k) = read_int_ary()
grid = []
for i in range(n):
	grid.append(list(stdin.readline().strip()))
graph = {}
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			v = (i, j)
			graph[v] = set()
			if i > 0 and grid[i - 1][j] == '.':
				u = (i - 1, j)
				graph[v].add(u)
				graph[u].add(v)
			if j > 0 and grid[i][j - 1] == '.':
				u = (i, j - 1)
				graph[v].add(u)
				graph[u].add(v)
processed = dfs(graph, next(iter(graph.keys())))
i = 0
while i < k:
	vertex = processed.pop()
	grid[vertex[0]][vertex[1]] = 'X'
	i += 1
for i in range(n):
	print(''.join(grid[i]))


def answer(n, m, k, A):
	flag = 1
	count = 0
	for i in range(n):
		for j in range(m):
			if A[i][j] == '.':
				count += 1
	vis = [[0 for i in range(m)] for j in range(n)]
	d = [(-1, 0), (1, 0), (0, -1), (0, 1)]
	for i in range(n):
		for j in range(m):
			if A[i][j] == '.' and flag:
				flag = 0
				s = [(i, j)]
				vis[i][j] = 1
				count -= 1
				sign = 0
				while True:
					item = s.pop()
					r = item[0]
					c = item[1]
					for (f, (x, y)) in enumerate(d):
						if count > k:
							if x + r >= 0 and x + r < n and (y + c >= 0) and (y + c < m) and (vis[x + r][y + c] == 0) and (A[r + x][y + c] == '.'):
								vis[x + r][y + c] = 1
								count -= 1
								s.append((x + r, y + c))
						else:
							sign = 1
							break
					if sign:
						break
	for i in range(n):
		for j in range(m):
			if A[i][j] == '.' and vis[i][j] == 0:
				A[i][j] = 'X'
	for i in range(n):
		A[i] = ''.join(A[i])
	return A
(n, m, k) = map(int, input().split())
arr = []
for i in range(n):
	arr.append(list(input()))
ans = answer(n, m, k, arr)
for i in ans:
	print(i)


maze = [['0' for j in range(510)] for i in range(510)]
visited = [[0 for j in range(510)] for i in range(510)]
(n, m, k) = tuple((int(i) for i in input().split()))
sx = -1
sy = -1
for i in range(n):
	s = input()
	for j in range(m):
		maze[i][j] = s[j]
		if sx == -1 and s[j] == '.':
			sx = i
			sy = j
stack = [(sx, sy)]
ans = []
while len(stack) != 0:
	curr = stack.pop()
	x = curr[0]
	y = curr[1]
	if x < 0 or y < 0 or x >= n or (y >= m) or (visited[x][y] == 1) or (maze[x][y] == '#'):
		continue
	visited[x][y] = 1
	stack.append((x + 1, y))
	stack.append((x - 1, y))
	stack.append((x, y + 1))
	stack.append((x, y - 1))
	ans.append(curr)
for i in range(k):
	curr = ans[len(ans) - i - 1]
	x = curr[0]
	y = curr[1]
	maze[x][y] = 'X'
s = ''
for i in range(n):
	for j in range(m):
		s += maze[i][j]
	s += '\n'
print(s)


def bfs(i, j):
	global k
	visitado[i][j] = 1
	queue = [(i, j)]
	k -= 1
	matriz[i][j] = '1'
	while queue:
		(i, j) = queue.pop(0)
		for x in [[0, 1], [1, 0], [0, -1], [-1, 0]]:
			if 0 <= i + x[0] < n and 0 <= j + x[1] < m and (matriz[i + x[0]][j + x[1]] == '.') and (not visitado[i + x[0]][j + x[1]]) and k:
				k -= 1
				visitado[i + x[0]][j + x[1]] = 1
				matriz[i + x[0]][j + x[1]] = '1'
				queue.append((i + x[0], j + x[1]))
(n, m, need) = [int(i) for i in input().split()]
visitado = [[0] * m for _ in range(n)]
matriz = []
inicio = (0, 0)
c = 0
for i in range(n):
	matriz.append(list(input()))
	c += matriz[i].count('.')
k = c - need
for i in range(n):
	for j in range(m):
		if matriz[i][j] == '.':
			inicio = (i, j)
			break
	else:
		continue
	break
bfs(inicio[0], inicio[1])
for i in matriz:
	for j in i:
		if j == '1':
			print('.', end='')
		elif j == '.':
			print('X', end='')
		else:
			print(j, end='')
	print()


import sys

def BFS(N, M, curr, visited, count, L):
	Q = [curr]
	while len(Q) != 0:
		curr = Q[0]
		if curr[0] + 1 < N and L[curr[0] + 1][curr[1]] == '.':
			nex = (curr[0] + 1, curr[1])
			if not nex in visited and count[0]:
				visited.add(nex)
				count[0] = count[0] - 1
				Q.append(nex)
		if curr[0] - 1 >= 0 and L[curr[0] - 1][curr[1]] == '.':
			nex = (curr[0] - 1, curr[1])
			if not nex in visited and count[0]:
				visited.add(nex)
				count[0] -= 1
				Q.append(nex)
		if curr[1] + 1 < M and L[curr[0]][curr[1] + 1] == '.':
			nex = (curr[0], curr[1] + 1)
			if not nex in visited and count[0]:
				visited.add(nex)
				count[0] = count[0] - 1
				Q.append(nex)
		if curr[1] - 1 >= 0 and L[curr[0]][curr[1] - 1] == '.':
			nex = (curr[0], curr[1] - 1)
			if not nex in visited and count[0]:
				visited.add(nex)
				count[0] -= 1
				Q.append(nex)
		Q.pop(0)

def DFS(N, M, curr, visited, count, L):
	if count[0] == 0:
		return
	if curr[0] + 1 < N and L[curr[0] + 1][curr[1]] == '.':
		nex = (curr[0] + 1, curr[1])
		if not nex in visited and count[0]:
			visited.add(nex)
			count[0] = count[0] - 1
			DFS(N, M, nex, visited, count, L)
	if curr[0] - 1 >= 0 and L[curr[0] - 1][curr[1]] == '.':
		nex = (curr[0] - 1, curr[1])
		if not nex in visited and count[0]:
			visited.add(nex)
			count[0] -= 1
			DFS(N, M, nex, visited, count, L)
	if curr[1] + 1 < M and L[curr[0]][curr[1] + 1] == '.':
		nex = (curr[0], curr[1] + 1)
		if not nex in visited and count[0]:
			visited.add(nex)
			count[0] = count[0] - 1
			DFS(N, M, nex, visited, count, L)
	if curr[1] - 1 >= 0 and L[curr[0]][curr[1] - 1] == '.':
		nex = (curr[0], curr[1] - 1)
		if not nex in visited and count[0]:
			visited.add(nex)
			count[0] -= 1
			DFS(N, M, nex, visited, count, L)
	return
(N, M, K) = map(int, input().strip().split())
L = []
for i in range(N):
	L.append(list(input()))
E = 0
if K == 0:
	for i in range(0, N):
		print(''.join(L[i]))
else:
	for i in range(len(L)):
		E += L[i].count('.')
	T = E - K
	visited = set()
	s = None
	for i in range(0, N):
		for j in range(0, M):
			if L[i][j] == '.':
				s = (i, j)
				break
		if s:
			break
	count = [T]
	if N > 300 or M >= 300:
		BFS(N, M, s, visited, count, L)
	else:
		DFS(N, M, s, visited, count, L)
	for i in range(0, N):
		for j in range(0, M):
			if L[i][j] == '.':
				if not (i, j) in visited:
					L[i][j] = 'X'
	for i in range(0, len(L)):
		print(''.join(L[i]))


from collections import defaultdict
from sys import stdin

def put():
	return map(int, stdin.readline().split())

def find():
	for i in range(n):
		for j in range(m):
			if mat[i][j] == '.':
				return (i, j)
	return (-1, -1)

def dfs(i, j):
	s = [(i, j)]
	t = 1
	vis[i][j] = 1
	while s:
		(i, j) = s.pop()
		for (x, y) in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
			(u, v) = (i + x, j + y)
			if u >= 0 and v >= 0 and (u < n) and (v < m) and (vis[u][v] == 0) and (mat[u][v] == '.'):
				t += 1
				vis[u][v] = t
				s.append((u, v))
	return t
(n, m, k) = put()
mat = []
for i in range(n):
	mat.append(list(input()))
vis = [[0] * m for i in range(n)]
(a, b) = find()
s = dfs(a, b)
for i in range(n):
	for j in range(m):
		if vis[i][j] > s - k:
			mat[i][j] = 'X'
for i in range(n):
	print(''.join(mat[i]))


(ROW, COL, k) = map(int, input().split())
arr = []
for i in range(ROW):
	arr.append(list(input()))
visited = [[False for i in range(COL)] for j in range(ROW)]

def isSafe(row, col, visited):
	if row >= 0 and row < ROW and (col >= 0) and (col < COL) and (arr[row][col] != '#') and (not visited[row][col]):
		return True
	return False

def bfs(row, col, n):
	visited[row][col] = True
	rowNbr = [1, -1, 0, 0]
	colNbr = [0, 0, 1, -1]
	cnt = 1
	queue = [[row, col]]
	while queue:
		(row, col) = queue.pop()
		for i in range(4):
			if isSafe(row + rowNbr[i], col + colNbr[i], visited) and cnt < n - k:
				cnt += 1
				visited[row + rowNbr[i]][col + colNbr[i]] = True
				queue.append([row + rowNbr[i], col + colNbr[i]])
n = 0
for row in range(ROW):
	for col in range(COL):
		if arr[row][col] == '.':
			n += 1
flag = False
for row in range(ROW):
	if flag:
		break
	for col in range(COL):
		if arr[row][col] == '.':
			bfs(row, col, n)
			flag = True
			break
for row in range(ROW):
	for col in range(COL):
		if not visited[row][col] and arr[row][col] != '#':
			arr[row][col] = 'X'
for i in arr:
	for j in i:
		print(j, end='')
	print()


def valid(i, j, n, m):
	if i >= 0 and j >= 0 and (i < n) and (j < m):
		return True
	return False

def solve():
	from collections import deque
	nmk = input().split()
	n = int(nmk[0])
	m = int(nmk[1])
	k = int(nmk[2])
	text = [['X' for _ in range(m)] for _ in range(n)]
	graph = {(i, j): list() for i in range(n) for j in range(m)}
	empty = list()
	add_i = [-1, 0, 0, 1]
	add_j = [0, 1, -1, 0]
	for i in range(n):
		line = input()
		for j in range(m):
			if line[j] == '#':
				text[i][j] = '#'
			else:
				empty.append((i, j))
	for i in range(n):
		for j in range(m):
			for u in range(4):
				next_i = i + add_i[u]
				next_j = j + add_j[u]
				if valid(next_i, next_j, n, m) and text[next_i][next_j] != '#' and (text[i][j] != '#'):
					graph[i, j].append((next_i, next_j))
	visited = {key: False for key in empty}
	cnt = 1
	need = len(empty) - k
	q = deque()
	q.append(empty[0])
	text[empty[0][0]][empty[0][1]] = '.'
	end = cnt == need
	while q:
		if end:
			break
		point = q.popleft()
		visited[point] = True
		for other in graph[point]:
			if not visited[other]:
				visited[other] = True
				text[other[0]][other[1]] = '.'
				cnt += 1
				q.append(other)
				if cnt == need:
					end = True
					break
	for i in range(n):
		for j in range(m):
			print(text[i][j], end='')
		print()
solve()


(rows, cols, walls) = map(int, input().split())
maze = [list(input()) for _ in range(rows)]
dotCount = sum([1 if maze[r][c] == '.' else 0 for r in range(rows) for c in range(cols)])
(visited, found) = ({}, False)
dirs = [(0, -1), (0, 1), (-1, 0), (1, 0)]
for r in range(rows):
	for c in range(cols):
		if maze[r][c] == '.':
			found = True
			visited.clear()
			(toVisit, count) = ([(r, c)], 0)
			while count < dotCount - walls:
				cell = toVisit.pop(0)
				if not visited.get(cell, False):
					visited[cell] = True
				else:
					continue
				count += 1
				for dir in dirs:
					(nr, nc) = (cell[0] + dir[0], cell[1] + dir[1])
					if nr >= 0 and nr < rows:
						if nc >= 0 and nc < cols:
							if maze[nr][nc] == '.' and (not visited.get((nr, nc), False)):
								toVisit.append((nr, nc))
		if found:
			break
	if found:
		break
for r in range(rows):
	for c in range(cols):
		if not visited.get((r, c), False) and maze[r][c] == '.':
			maze[r][c] = 'X'
print('\n'.join([''.join(row) for row in maze]))


from collections import deque
(n, m, k) = map(int, input().split())
visited = [[False for i in range(m)] for x in range(n)]
maze = [[None for i in range(m)] for x in range(n)]
c = 0
t = 0
initial = None
for i in range(n):
	l = list(input())
	for j in range(m):
		if l[j] == '.':
			maze[i][j] = 'X'
			initial = (i, j)
			c += 1
		else:
			maze[i][j] = l[j]
stack = deque()
stack.append(initial)
while stack:
	(i, j) = stack.pop()
	if i < 0 or i >= n or j < 0 or (j >= m) or visited[i][j] or (t == c - k):
		continue
	if maze[i][j] == 'X':
		maze[i][j] = '.'
		t = t + 1
		stack.append((i, j - 1))
		stack.append((i, j + 1))
		stack.append((i - 1, j))
		stack.append((i + 1, j))
for i in maze:
	print(''.join(i))


dr = [1, -1, 0, 0]
dc = [0, 0, 1, -1]
l = []

def bfs(sr, cnt):
	global l
	q = []
	if cnt < 1:
		return
	q.append(sr)
	l[sr[0]][sr[1]] = '_'
	cnt -= 1
	while q:
		(ux, uy) = q.pop(0)
		for i in range(4):
			tr = ux + dr[i]
			tc = uy + dc[i]
			if tr >= 0 and tr < n and (tc >= 0) and (tc < m):
				if cnt < 1:
					return
				if l[tr][tc] == '#' or l[tr][tc] == '_':
					continue
				l[tr][tc] = '_'
				cnt -= 1
				q.append((tr, tc))
				if cnt < 1:
					return 0
(n, m, k) = [int(x) for x in input().split()]
for i in range(n):
	tmp = list(input())
	l.append(tmp)
if k == 0:
	for i in range(n):
		print(''.join(l[i]))
else:
	find = False
	cnt = 0
	for i in range(n):
		for j in range(m):
			if l[i][j] == '#':
				cnt += 1
			elif l[i][j] == '.' and find == False:
				sr = (i, j)
				find = True
	bfs(sr, n * m - cnt - k)
	for i in range(n):
		for j in range(m):
			if l[i][j] == '_':
				l[i][j] = '.'
			elif l[i][j] == '.':
				l[i][j] = 'X'
	for i in range(n):
		print(''.join(l[i]))


from sys import stdin
from collections import *

def arr_inp(n):
	if n == 1:
		return [int(x) for x in stdin.readline().split()]
	elif n == 2:
		return [float(x) for x in stdin.readline().split()]
	else:
		return list(stdin.readline()[:-1])

def valid(i, j):
	global n, m
	return i > -1 and i < n and (j > -1) and (j < m)
(dx, dy) = ([-1, 0, 1, 0], [0, 1, 0, -1])

def print_maze():
	for i in range(n):
		print(*maze[i], sep='')

def bfs_util(i, j):
	(queue, visit, q2) = (deque([[i, j]]), defaultdict(int, {(i, j): 1}), deque([[i, j]]))
	while queue:
		s = queue.popleft()
		for i in range(4):
			(ni, nj) = (s[0] + dx[i], s[1] + dy[i])
			if valid(ni, nj) and (not visit[ni, nj]) and (maze[ni][nj] != '#'):
				queue.append([ni, nj])
				q2.append([ni, nj])
				visit[ni, nj] = 1
	for i in range(k):
		(ix1, ix2) = q2.pop()
		maze[ix1][ix2] = 'X'
	print_maze()
(n, m, k) = arr_inp(1)
maze = [arr_inp(3) for i in range(n)]
if k == 0:
	print_maze()
else:
	for i in range(n):
		try:
			ix = maze[i].index('.')
			if ix != -1:
				bfs_util(i, ix)
				break
		except:
			continue


import sys
input = sys.stdin.readline
from math import log2, log, ceil

def swaparr(arr, a, b):
	temp = arr[a]
	arr[a] = arr[b]
	arr[b] = temp

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def nCr(n, k):
	if k > n - k:
		k = n - k
	res = 1
	for i in range(k):
		res = res * (n - i)
		res = res / (i + 1)
	return res

def upper_bound(a, x, lo=0):
	hi = len(a)
	while lo < hi:
		mid = (lo + hi) // 2
		if a[mid] < x:
			lo = mid + 1
		else:
			hi = mid
	return lo

def primefs(n):
	primes = {}
	while n % 2 == 0:
		primes[2] = primes.get(2, 0) + 1
		n = n // 2
	for i in range(3, int(n ** 0.5) + 2, 2):
		while n % i == 0:
			primes[i] = primes.get(i, 0) + 1
			n = n // i
	if n > 2:
		primes[n] = primes.get(n, 0) + 1
	return primes

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def swap(a, b):
	temp = a
	a = b
	b = temp
	return (a, b)

def find(x, link):
	while x != link[x]:
		x = link[x]
	return x

def union(x, y, link, size):
	x = find(x, link)
	y = find(y, link)
	if size[x] < size[y]:
		(x, y) = swap(x, y)
	if x != y:
		size[x] += size[y]
		link[y] = x

def sieve(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime
MAXN = int(1000000.0 + 5)

def spf_sieve():
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, ceil(MAXN ** 0.5), 2):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def factoriazation(x):
	ret = {}
	while x != 1:
		ret[spf[x]] = ret.get(spf[x], 0) + 1
		x = x // spf[x]
	return ret

def int_array():
	return list(map(int, input().strip().split()))

def str_array():
	return input().strip().split()
MOD = int(1000000000.0) + 7
CMOD = 998244353
INF = float('inf')
NINF = -float('inf')
(n, m, k) = int_array()
maze = [list(input().strip()) for _ in range(n)]
dick = {}
count = 0
revs_dick = {}
safe = 0
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.':
			safe += 1
			dick[i, j] = count
			revs_dick[count] = (i, j)
			count += 1

def dfs():
	global total_nodes
	while stack:
		x = stack.pop()
		if visited[x] or total_nodes == safe - k:
			continue
		visited[x] = True
		total_nodes += 1
		if total_nodes == safe - k:
			continue
		for i in graph[x]:
			stack.append(i)
graph = [[] for _ in range(count + 1)]
for i in range(n):
	for j in range(m):
		ours = (i, j)
		if ours in dick:
			up = (i - 1, j)
			if up in dick:
				graph[dick[ours]].append(dick[up])
			down = (i + 1, j)
			if down in dick:
				graph[dick[ours]].append(dick[down])
			left = (i, j - 1)
			if left in dick:
				graph[dick[ours]].append(dick[left])
			right = (i, j + 1)
			if right in dick:
				graph[dick[ours]].append(dick[right])
visited = [False] * count
stack = [0]
total_nodes = 0
dfs()
for i in range(count):
	if not visited[i]:
		(x, y) = revs_dick[i]
		maze[x][y] = 'X'
for i in maze:
	print(''.join(i))


from queue import Queue, PriorityQueue
(n, m, k) = [int(x) for x in input().split()]
a = []
for i in range(n):
	a.append(list(input()))
lvl = [[0] * m for i in range(n)]
x = y = -1
for i in range(n):
	if '.' in a[i]:
		x = i
		y = a[i].index('.')
		break
q = Queue()
q.put((x, y))
ans = []
lvl[x][y] = 1
while not q.empty():
	(x, y) = q.get()
	for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
		nx = x + dx
		ny = y + dy
		if nx < 0 or ny < 0 or nx >= n or (ny >= m):
			continue
		if lvl[nx][ny]:
			continue
		if a[nx][ny] == '#':
			continue
		lvl[nx][ny] = lvl[x][y] + 1
		q.put((nx, ny))
		ans.append((-lvl[nx][ny], nx, ny))
ans.sort()
for i in range(k):
	(_, x, y) = ans[i]
	a[x][y] = 'X'
print('\n'.join((''.join(l) for l in a)))


import sys
import math
import collections
import heapq
import decimal
(n, m, k) = (int(i) for i in input().split())
l = []
for i in range(n):
	l.append(list(input()))

def neighbours(x, y):
	global n
	global m
	global l
	l1 = []
	if x - 1 >= 0 and l[x - 1][y] == '.':
		l1.append((x - 1, y))
	if x + 1 <= n - 1 and l[x + 1][y] == '.':
		l1.append((x + 1, y))
	if y - 1 >= 0 and l[x][y - 1] == '.':
		l1.append((x, y - 1))
	if y + 1 <= m - 1 and l[x][y + 1] == '.':
		l1.append((x, y + 1))
	return l1
d = {}
c1 = 0
for i in range(n):
	for j in range(m):
		d[i, j] = []
for i in range(n):
	for j in range(m):
		if l[i][j] == '.':
			c1 += 1
			nbd = neighbours(i, j)
			for x in nbd:
				d[i, j].append(x)
c = 0
v = [[0 for i in range(m)] for j in range(n)]
if c1 == 0:
	for i in range(n):
		print(''.join(l[i]))
else:
	queue = []
	for i in range(n):
		if c == 1:
			break
		for j in range(m):
			if l[i][j] == '.':
				queue.append((i, j))
				l[i][j] = 'X'
				v[i][j] = 1
				c += 1
				break
	while queue != []:
		if c == c1 - k:
			break
		s = queue.pop(0)
		for j in d[s]:
			if c == c1 - k:
				break
			if v[j[0]][j[1]] == 0:
				v[j[0]][j[1]] = 1
				l[j[0]][j[1]] = 'X'
				c += 1
				queue.append(j)
	for i in range(n):
		for j in range(m):
			if l[i][j] == 'X':
				l[i][j] = '.'
			elif l[i][j] == '.':
				l[i][j] = 'X'
	for i in range(n):
		print(''.join(l[i]))


from collections import defaultdict
from bisect import *

def solve(N, M, K, maze):
	ans = maze
	dirs = [(-1, 0), (0, -1), (1, 0), (0, 1)]

	def dfs(i, j, vis):
		if not (0 <= i < M and 0 <= j < N):
			return 0
		elif maze[i][j] != '.':
			return 0
		elif (i, j) in vis:
			return 1
		res = 0
		vis[i, j] = 0
		for (x, y) in dirs:
			res += dfs(i + x, j + y, vis)
		vis[i, j] = res
		return 1
	can = set()
	for i in range(M):
		for j in range(N):
			if maze[i][j] == '.':
				can.add((i, j))
	vis = set()
	q = [can.pop()]
	traversal = []
	while q:
		(i, j) = q.pop()
		if (i, j) in vis:
			continue
		traversal.append((i, j))
		vis.add((i, j))
		for (x, y) in dirs:
			if not (0 <= i + x < M and 0 <= j + y < N):
				continue
			elif maze[i + x][j + y] != '.':
				continue
			q.append((i + x, j + y))
	while K:
		K -= 1
		(i, j) = traversal.pop()
		ans[i][j] = 'X'
	return ans
(M, N, K) = map(int, input().split())
maze = []
for i in range(M):
	line = list(input())
	maze.append(line)
ans = solve(N, M, K, maze)
for i in range(M):
	print(''.join(ans[i]))


from collections import deque
(height, width, walls) = tuple(map(int, input().split()))
(visited_nodes, open_spots) = (0, 0)
maze = [[None for j in range(width)] for i in range(height)]
visited = [[False for j in range(width)] for i in range(height)]
start = None
for i in range(height):
	line = list(input())
	for j in range(width):
		if line[j] == '.':
			maze[i][j] = 'X'
			open_spots += 1
			start = (i, j)
		else:
			maze[i][j] = line[j]
stack = deque()
stack.append(start)
while stack:
	(i, j) = stack.pop()
	if i < 0 or i >= height or j < 0 or (j >= width) or visited[i][j] or (visited_nodes == open_spots - walls):
		continue
	if maze[i][j] == 'X':
		maze[i][j] = '.'
		visited[i][j] = True
		visited_nodes += 1
		stack.append((i, j - 1))
		stack.append((i, j + 1))
		stack.append((i - 1, j))
		stack.append((i + 1, j))
for row in maze:
	print(''.join(row))


import time
visit = [0 for i in range(250005)]

class Graph(object):

	def __init__(self, graph_dict=None):
		if graph_dict == None:
			graph_dict = {}
			self.num_vertices = 0
		else:
			self.num_vertices = len(graph_dict)
			self.__graph_dict = graph_dict

	def vertices(self):
		return list(self.__graph_dict.keys())

	def edges(self):
		return self.__generate_edges()

	def add_vertex(self, vertex):
		if vertex not in self.__graph_dict:
			self.__graph_dict[vertex] = []
			self.num_vertices += 1

	def add_edge(self, edge):
		edge = set(edge)
		(vertex1, vertex2) = tuple(edge)
		if vertex1 not in self.__graph_dict:
			self.add_vertex(vertex1)
		if vertex2 not in self.__graph_dict:
			self.add_vertex(vertex2)
		if vertex1 in self.__graph_dict:
			if vertex2 not in self.__graph_dict[vertex1]:
				self.__graph_dict[vertex1].append(vertex2)
		if vertex2 in self.__graph_dict:
			if vertex1 not in self.__graph_dict[vertex2]:
				self.__graph_dict[vertex2].append(vertex1)

	def __generate_edges(self):
		edges = []
		for vertex in self.__graph_dict:
			for neighbour in self.__graph_dict[vertex]:
				if {neighbour, vertex} not in edges:
					edges.append({vertex, neighbour})
		return edges

	def __str__(self):
		res = 'vertices: '
		for k in self.__graph_dict:
			res += str(k) + ' '
		res += '\nedges: '
		for edge in self.__generate_edges():
			res += str(edge) + ' '
		return res
		graph = self.__graph_dict
		isolated = []
		for vertex in graph:
			print(isolated, vertex)
			if not graph[vertex]:
				isolated += [vertex]
		return isolated

	def find_path(self, start_vertex, end_vertex, path=[]):
		graph = self.__graph_dict
		path = path + [start_vertex]
		if start_vertex == end_vertex:
			return path
		if start_vertex not in graph:
			return None
		for vertex in graph[start_vertex]:
			if vertex not in path:
				extended_path = self.find_path(vertex, end_vertex, path)
				if extended_path:
					return extended_path
		return None

	def BFS(self, s):
		graph = self.__graph_dict
		visited = [False] * len(graph)
		queue = []
		arr = []
		i = 0
		queue.append(s)
		visited[i] = True
		i += 1
		while queue:
			s = queue.pop(0)
			arr.append(s)
			print(s, end=' ')
			for adj in graph[s]:
				if adj in arr:
					if visited[arr.index(adj)] == False:
						queue.append(adj)
						visited[adj] = True
				else:
					queue.append(adj)
					visited[i] = True
					i += 1

	def DFS(self, s):
		graph = self.__graph_dict
		visited = [False] * len(graph)
		stack = []
		arr = []
		stack.append(s)
		i = 0
		visited[i] = True
		i += 1
		while stack:
			s = stack.pop()
			arr.append(s)
			print(s, end=' ')
			for adj in graph[s]:
				if adj in arr:
					if visited[arr.index(adj)] == False:
						stack.append(adj)
						visited[adj] = True
				else:
					stack.append(adj)
					visited[i] = True
					i += 1

	def find_all_paths(self, start_vertex, end_vertex, path=[]):
		graph = self.__graph_dict
		path = path + [start_vertex]
		if start_vertex == end_vertex:
			return [path]
		if start_vertex not in graph:
			return []
		paths = []
		for vertex in graph[start_vertex]:
			if vertex not in path:
				extended_paths = self.find_all_paths(vertex, end_vertex, path)
				for p in extended_paths:
					paths.append(p)
		return paths

	def is_connected(self, vertices_encountered=None, start_vertex=None):
		if vertices_encountered is None:
			vertices_encountered = set()
		gdict = self.__graph_dict
		vertices = gdict.keys()
		if not start_vertex:
			start_vertex = vertices[0]
		vertices_encountered.add(start_vertex)
		if len(vertices_encountered) != len(vertices):
			for vertex in gdict[start_vertex]:
				if vertex not in vertices_encountered:
					if self.is_connected(vertices_encountered, vertex):
						return True
		else:
			return True
		return False

	def vertex_degree(self, vertex):
		adj_vertices = self.__graph_dict[vertex]
		degree = len(adj_vertices) + adj_vertices.count(vertex)
		return degree

	def degree_sequence(self):
		seq = []
		for vertex in self.__graph_dict:
			seq.append(self.vertex_degree(vertex))
		seq.sort(reverse=True)
		return tuple(seq)

	@staticmethod
	def is_degree_sequence(sequence):
		return all((x >= y for (x, y) in zip(sequence, sequence[1:])))

	def delta(self):
		min = 100000000
		for vertex in self.__graph_dict:
			vertex_degree = self.vertex_degree(vertex)
			if vertex_degree < min:
				min = vertex_degree
		return min

	def Delta(self):
		max = 0
		for vertex in self.__graph_dict:
			vertex_degree = self.vertex_degree(vertex)
			if vertex_degree > max:
				max = vertex_degree
		return max

	def density(self):
		g = self.__graph_dict
		V = len(g.keys())
		E = len(self.edges())
		return 2.0 * E / (V * (V - 1))

	def diameter(self):
		v = self.vertices()
		pairs = [(v[i], v[j]) for i in range(len(v) - 1) for j in range(i + 1, len(v))]
		smallest_paths = []
		for (s, e) in pairs:
			paths = self.find_all_paths(s, e)
			smallest = sorted(paths, key=len)[0]
			smallest_paths.append(smallest)
		smallest_paths.sort(key=len)
		diameter = len(smallest_paths[-1])
		return diameter

	def DFSnow(self, s, s1, k, a, n, m):
		graph = self.__graph_dict
		visited = [False] * len(graph)
		stack = []
		arr = []
		stack.append(s)
		i = 0
		visited[i] = True
		i += 1
		while stack:
			s = stack.pop()
			arr.append(s)
			if i - 1 == s1 - k:
				for i in range(n):
					for j in range(m):
						if a[i][j] != 0 and a[i][j] not in arr:
							print('X', end='')
						elif a[i][j] == 0:
							print('#', end='')
						elif a[i][j] != 0 and a[i][j] in arr:
							print('.', end='')
					print('\n')
				return
			for adj in graph[s]:
				if adj in arr:
					if visited[arr.index(adj)] == False:
						stack.append(adj)
						visited[adj] = True
				else:
					stack.append(adj)
					visited[i] = True
					i += 1

	def DFSnew(self, s, s1, k, a, n, m):
		graph = self.__graph_dict
		stack = []
		stack.append(s)
		co = 0
		visit[1] = 1
		while stack:
			s = stack.pop()
			visit[s] += 1
			co += 1
			if co == s1 - k:
				for i in range(n):
					for j in range(m):
						if a[i][j]:
							if visit[a[i][j]] == 2:
								print('.', end='')
							else:
								print('X', end='')
						else:
							print('#', end='')
					print('\n')
				return None
			for adj in graph[s]:
				if visit[adj] == 0:
					stack.append(adj)
					visit[adj] = 1

	def BFSnew(self, s, s1, k, a, n, m):
		graph = self.__graph_dict
		queue = []
		queue.append(s)
		co = 0
		while queue:
			s = queue.pop(0)
			visit[s] = 1
			co += 1
			if co == s1 - k:
				for i in range(n):
					for j in range(m):
						if a[i][j]:
							if visit[a[i][j]]:
								print('.', end='')
							else:
								print('X', end='')
						else:
							print('#', end='')
					print('\n')
				return None
			for adj in graph[s]:
				if visit[adj] == 0:
					queue.append(adj)

	@staticmethod
	def erdoes_gallai(dsequence):
		if sum(dsequence) % 2:
			return False
		if Graph.is_degree_sequence(dsequence):
			for k in range(1, len(dsequence) + 1):
				left = sum(dsequence[:k])
				right = k * (k - 1) + sum([min(x, k) for x in dsequence[k:]])
				if left > right:
					return False
		else:
			return False
		return True
ts = time.time()
g = dict()
graph = Graph(g)
b = list(map(int, input().split(' ')))
(n, m, k) = (b[0], b[1], b[2])
c = []
for i in range(n):
	c.append(input())
s = 0
a = [[0 for i in range(m)] for j in range(n)]
for i in range(n):
	for j in range(m):
		if c[i][j] == '.':
			a[i][j] = s + 1
			s += 1
		else:
			a[i][j] = 0
for i in range(n):
	for j in range(m):
		if a[i][j]:
			graph.add_vertex(a[i][j])
			if i - 1 > -1:
				if a[i - 1][j]:
					graph.add_edge({a[i][j], a[i - 1][j]})
			if i + 1 < n:
				if a[i + 1][j]:
					graph.add_edge({a[i][j], a[i + 1][j]})
			if j - 1 > -1:
				if a[i][j - 1]:
					graph.add_edge({a[i][j], a[i][j - 1]})
			if j + 1 < m:
				if a[i][j + 1]:
					graph.add_edge({a[i][j], a[i][j + 1]})
graph.DFSnew(1, s, k, a, n, m)


import sys
import threading
(n, m, k) = list(map(int, input().split()))
li = [list(input()) for _ in range(n)]

def issafe(r, c):
	return 0 <= r < n and 0 <= c < m

def fun(r, c, cnt):
	if cnt[0] >= k:
		return
	li[r][c] = '1'
	if issafe(r - 1, c) and li[r - 1][c] == '.':
		fun(r - 1, c, cnt)
	if issafe(r + 1, c) and li[r + 1][c] == '.':
		fun(r + 1, c, cnt)
	if issafe(r, c + 1) and li[r][c + 1] == '.':
		fun(r, c + 1, cnt)
	if issafe(r, c - 1) and li[r][c - 1] == '.':
		fun(r, c - 1, cnt)
	if cnt[0] < k:
		cnt[0] += 1
		li[r][c] = 'X'

def main():
	(cnt, i) = ([0], 0)
	while i < n:
		for j in range(m):
			if cnt[0] < k and li[i][j] == '.':
				fun(i, j, cnt)
			if cnt[0] >= k:
				break
		if cnt[0] >= k:
			break
		i += 1
	for i in range(n):
		for j in range(m):
			if li[i][j] == '1':
				print('.', end='')
			else:
				print(li[i][j], end='')
		print()
sys.setrecursionlimit(10 ** 6)
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


(n, m, k) = map(int, input().split())
maze = [['#' for _ in range(m + 2)]]
for i in range(n):
	p = list('#' + input() + '#')
	maze.append(p)
maze.append(['#' for _ in range(m + 2)])
graph = {(i, j): [] for i in range(1, n + 1) for j in range(1, m + 1)}
dif = [(-1, 0), (1, 0), (0, 1), (0, -1)]
s_node = 0
for x in range(1, n + 1):
	for y in range(1, m + 1):
		node = maze[x][y]
		if node == '.':
			s_node = (x, y)
			for que in dif:
				(dx, dy) = que
				if maze[dx + x][dy + y] == '.':
					graph[x, y].append((dx + x, dy + y))
visited = [[False for i in range(m + 1)] for j in range(n + 1)]
from collections import deque
d = deque()
e = deque()
(sx, sy) = s_node
connect = [s_node]
visited[sx][sy] = True
d.append(s_node)
while d:
	while d:
		x = d.popleft()
		for node in graph[x]:
			(node_x, node_y) = node
			if visited[node_x][node_y] == False:
				visited[node_x][node_y] = True
				connect.append(node)
				e.append(node)
	if e:
		d = e
		e = deque()
	else:
		d = deque()
S = len(connect)
connect = connect[:S - k]
safe = {(i, j): False for i in range(1, n + 1) for j in range(1, m + 1)}
for que in connect:
	safe[que] = True
for i in range(1, n + 1):
	string = ''
	for j in range(1, m + 1):
		if maze[i][j] == '#':
			string += '#'
		elif maze[i][j] == '.':
			if safe[i, j]:
				string += '.'
			else:
				string += 'X'
	print(string)


(n, m, k) = map(int, input().split())
g = []
for i in range(n):
	g.append(list(input()))
flag = False
for i in range(n):
	for j in range(m):
		if g[i][j] == '.':
			temp = (i, j)
			flag = True
			break
	if flag:
		break

def check(x, y):
	return x >= 0 and x < n and (y >= 0) and (y < m)
p = 0
stack = []
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]
visited = [[0] * m for _ in range(n)]
s = sum((p.count('.') for p in g))
stack.append((i, j))
while len(stack):
	(x, y) = stack.pop(-1)
	if not visited[x][y]:
		visited[x][y] = 1
		p += 1
	else:
		continue
	if s - p == k:
		break
	for (dx, dy) in direction:
		if check(x + dx, y + dy) and (not visited[x + dx][y + dy]) and (g[x + dx][y + dy] == '.'):
			stack.append((x + dx, y + dy))
for x in range(n):
	for y in range(m):
		if g[x][y] == '#':
			print('#', end='')
		if g[x][y] == '.' and visited[x][y]:
			print('.', end='')
		if g[x][y] == '.' and (not visited[x][y]):
			print('X', end='')
	print()


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush, nsmallest
from math import ceil, floor, gcd, fabs, factorial, fmod, sqrt, inf
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
from decimal import Decimal
mod = pow(10, 9) + 7
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(var):
	sys.stdout.write(str(var))

def outa(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]

def valid(u, v):
	return 0 <= u < n and 0 <= v < m

def bfs(a, b):
	global dots
	if dots == K:
		return
	d = deque()
	d.append((a, b))
	dots -= 1
	vis.add((a, b))
	if dots == K:
		return
	while d:
		(a, b) = d.popleft()
		for k in range(4):
			(t1, t2) = (a + x[k], b + y[k])
			if valid(t1, t2) and mat[t1][t2] == '.' and ((t1, t2) not in vis):
				vis.add((t1, t2))
				d.append((t1, t2))
				dots -= 1
				if dots == K:
					return
		if dots == K:
			return
(x, y) = ([-1, 1, 0, 0], [0, 0, -1, 1])
(n, m, K) = sp()
mat = []
dots = 0
vis = set()
for i in range(n):
	mat.append(list(data()))
	dots += mat[i].count('.')
r = True
for j in range(m):
	for i in range(n):
		if mat[i][j] == '.':
			bfs(i, j)
			r = False
			break
	if not r:
		break
for i in range(n):
	for j in range(m):
		if mat[i][j] == '.' and (i, j) not in vis:
			mat[i][j] = 'X'
for i in mat:
	out(''.join(i) + '\n')


import sys
import threading
(n, m, k) = map(int, input().split())
matrix = []
for i in range(n):
	row = input()
	r = []
	for j in range(len(row)):
		r.append(row[j])
	matrix.append(r)
number_of_empty_cell = 0
global count
count = 0
for i in range(n):
	for j in range(m):
		if matrix[i][j] == '.':
			number_of_empty_cell += 1

def isSafe(i, j):
	return True if 0 <= i < n and 0 <= j < m else False

def boarder_check(i, j):
	return True if i == 0 or j == 0 or i == n - 1 or (j == m - 1) else False

def dfs(i, j):
	global count
	if count < number_of_empty_cell - k:
		matrix[i][j] = '$'
		count += 1
		if isSafe(i, j + 1) and matrix[i][j + 1] == '.':
			dfs(i, j + 1)
		if isSafe(i + 1, j) and matrix[i + 1][j] == '.':
			dfs(i + 1, j)
		if isSafe(i, j - 1) and matrix[i][j - 1] == '.':
			dfs(i, j - 1)
		if isSafe(i - 1, j) and matrix[i - 1][j] == '.':
			dfs(i - 1, j)

def main():
	for i in range(n):
		for j in range(m):
			if matrix[i][j] == '.':
				dfs(i, j)
	for i in range(n):
		for j in range(m):
			if matrix[i][j] == '$':
				matrix[i][j] = '.'
			elif matrix[i][j] == '.':
				matrix[i][j] = 'X'
	for i in range(n):
		s = ''.join(matrix[i])
		print(s, end='\n')
sys.setrecursionlimit(10 ** 6)
threading.stack_size(10 ** 8)
t = threading.Thread(target=main)
t.start()
t.join()


def getNeighs(ind, n, m):
	res = []
	if ind % m > 0:
		res.append(ind - 1)
	if ind % m < m - 1:
		res.append(ind + 1)
	if ind // m > 0:
		res.append(ind - m)
	if ind // m < n - 1:
		res.append(ind + m)
	return res
(n, m, k) = map(int, input().split())
maze = [list(input()) for x in range(n)]
count = 0
stack = []
visited = [[False for y in range(m)] for x in range(n)]
s = 0
for st in maze:
	for ch in st:
		if ch == '.':
			s += 1
root = 0
while maze[root // m][root % m] == '#':
	root += 1
stack.append(root)
while len(stack) > 0:
	curr = stack.pop()
	if visited[curr // m][curr % m]:
		continue
	count += 1
	visited[curr // m][curr % m] = True
	if count + k > s:
		maze[curr // m][curr % m] = 'X'
	neighs = getNeighs(curr, n, m)
	for neigh in neighs:
		if maze[neigh // m][neigh % m] == '#':
			continue
		stack.append(neigh)
for st in maze:
	for ch in st:
		print(ch, end='')
	print()


(n, m, k) = map(int, input().split())
graph = []
visited = []
x = 0
y = 0
ss = -k
for i in range(n):
	graph.append([])
	visited.append([0] * m)
for i in range(n):
	graph[i] = list(input())
	for j in range(m):
		if graph[i][j] == '.':
			x = i
			y = j
			ss += 1
			graph[i][j] = 'X'
		else:
			visited[i][j] = True
queue = []
queue.append((x, y))
if ss != 0:
	ss -= 1
	graph[x][y] = '.'
	visited[x][y] = True
while queue:
	s = queue.pop(0)
	x = s[0]
	y = s[1]
	if y + 1 < m and visited[x][y + 1] == False:
		queue.append((x, y + 1))
		visited[x][y + 1] = True
		if ss == 0:
			break
		else:
			ss -= 1
			graph[x][y + 1] = '.'
	if x + 1 < n and visited[x + 1][y] == False:
		queue.append((x + 1, y))
		visited[x + 1][y] = True
		if ss == 0:
			break
		else:
			ss -= 1
			graph[x + 1][y] = '.'
	if x - 1 >= 0 and visited[x - 1][y] == False:
		queue.append((x - 1, y))
		visited[x - 1][y] = True
		if ss == 0:
			break
		else:
			ss -= 1
			graph[x - 1][y] = '.'
	if y - 1 >= 0 and visited[x][y - 1] == False:
		queue.append((x, y - 1))
		visited[x][y - 1] = True
		if ss == 0:
			break
		else:
			ss -= 1
			graph[x][y - 1] = '.'
for i in range(n):
	for j in range(m):
		print(graph[i][j], end='')
	print('')


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
except:
	pass
global n, m, k, s
(n, m, k) = L()
A = [list(input()) for i in range(n)]

def bfs(i, j):
	global n, m, k, s
	vis = [[0 for i in range(m)] for j in range(n)]
	q = [[i, j]]
	vis[i][j] = 1
	cnt = 1
	while q:
		(x, y) = q[0]
		del q[0]
		if vis[x][y] > s - k:
			A[x][y] = 'X'
		row = [-1, 0, 0, 1]
		col = [0, -1, 1, 0]
		for i in range(4):
			a = x + row[i]
			b = y + col[i]
			if a >= 0 and b >= 0 and (a < n) and (b < m) and (vis[a][b] == 0) and (A[a][b] == '.'):
				cnt += 1
				vis[a][b] = cnt
				q.append([a, b])
s = 0
for i in range(n):
	s += A[i].count('.')
for i in range(n):
	for j in range(m):
		if A[i][j] == '.':
			bfs(i, j)
			print('\n'.join((''.join(ele) for ele in A)))
			exit()
endtime = time.time()


import sys
sys.setrecursionlimit(327500)
(n, m, k) = map(int, input().split())
maze = [list(input()) for _ in range(n)]
di = [-1, 0, 1, 0]
dj = [0, 1, 0, -1]
visited = [[False] * m for _ in range(n)]

def is_visitable(x, y):
	if not (0 <= x < n and 0 <= y < m):
		return False
	return maze[x][y] == '.' and (not visited[x][y])
open_count = 0
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.':
			open_count += 1
visited_count = 0
for i in range(n):
	for j in range(m):
		if maze[i][j] != '.' or visited[i][j]:
			continue
		if open_count - visited_count == k:
			break
		visited_count += 1
		visited[i][j] = True
		stack = [(i, j)]
		while stack and open_count - visited_count > k:
			(x, y) = stack.pop()
			if open_count - visited_count == k:
				break
			for d in range(4):
				if open_count - visited_count == k:
					break
				nx = x + di[d]
				ny = y + dj[d]
				if not is_visitable(nx, ny):
					continue
				visited_count += 1
				visited[nx][ny] = True
				stack.append((nx, ny))
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.' and (not visited[i][j]):
			maze[i][j] = 'X'
for _ in range(n):
	print(''.join(maze[_]))


def printTheLab():
	global n
	global m
	global lab
	for i in range(n):
		s = ''
		for j in range(m):
			if lab[i][j] == 0 or lab[i][j] == -1:
				s += '.'
			elif lab[i][j] == 1:
				s += '#'
			elif lab[i][j] == 2:
				s += 'X'
			else:
				s += '?'
		print(s)
(n, m, k) = map(int, input().split())
lab = []
lab_path = []
for i in range(n):
	s = input()
	s1 = s.replace('#', '1 ')
	s2 = s1.replace('.', '0 ')
	stroka_lab = list(map(int, s2.split()))
	lab.append(stroka_lab)
	stroka_lab_path = [[-1, -1] for j in range(m)]
	lab_path.append(stroka_lab_path)
emptyFound = False
i = 0
while not emptyFound:
	row1 = i // m
	col1 = i % m
	if lab[row1][col1] == 0:
		emptyFound = True
	i += 1
i = row1
j = col1
while k > 0:
	lab[i][j] = -1
	if j > 0 and lab[i][j - 1] == 0:
		lab_path[i][j - 1][0] = i
		lab_path[i][j - 1][1] = j
		i = i
		j -= 1
	elif i < n - 1 and lab[i + 1][j] == 0:
		lab_path[i + 1][j][0] = i
		lab_path[i + 1][j][1] = j
		i += 1
		j = j
	elif j < m - 1 and lab[i][j + 1] == 0:
		lab_path[i][j + 1][0] = i
		lab_path[i][j + 1][1] = j
		i = i
		j += 1
	elif i > 0 and lab[i - 1][j] == 0:
		lab_path[i - 1][j][0] = i
		lab_path[i - 1][j][1] = j
		i -= 1
		j = j
	else:
		lab[i][j] = 2
		k -= 1
		i1 = lab_path[i][j][0]
		j1 = lab_path[i][j][1]
		if i1 == -1 and j1 == -1:
			if j1 > 0 and lab[i1][j1 - 1] == 0:
				i1 = i1
				j1 -= 1
			elif i1 < n - 1 and lab[i1 + 1][j1] == 0:
				i1 += 1
				j1 = j1
			elif j1 < m - 1 and lab[i1][j1 + 1] == 0:
				i1 = i1
				j1 += 1
			else:
				i1 -= 1
				j1 = j1
		else:
			i = i1
			j = j1
printTheLab()


import sys
import itertools

def dfs(maze, startx, starty):
	visited = set()
	traversal = []
	stack = [(startx, starty)]
	while stack:
		(x, y) = stack.pop()
		visited.add((x, y))
		traversal.append((x, y))
		for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
			xx = x + dx
			yy = y + dy
			if 0 <= xx < len(maze[0]) and 0 <= yy < len(maze) and (maze[yy][xx] == '.') and ((xx, yy) not in visited):
				visited.add((xx, yy))
				stack.append((xx, yy))
	return traversal
lines = [l.strip() for l in sys.stdin.readlines()]
(height, width, k) = lines[0].split()
k = int(k)
maze = lines[1:]
avail = set()
for y in range(len(maze)):
	for x in range(len(maze[y])):
		if maze[y][x] == '.':
			avail.add((x, y))
(startx, starty) = next(iter(avail))
traversal = dfs(maze, startx, starty)
for (x, y) in itertools.islice(reversed(traversal), k):
	s = list(maze[y])
	s[x] = 'X'
	maze[y] = ''.join(s)
print('\n'.join(maze))


(n, m, k) = map(int, input().strip().split(' '))
adj = [set() for _ in range(n * m)]
cells = set()
debug = False
for i in range(n):
	line = input().strip()
	for (j, s) in enumerate(line):
		if s == '.':
			cells.add(i * m + j)
if debug:
	print(cells)
for i in range(n * m):
	if i not in cells:
		continue
	neib = []
	if i % m != 0 and i - 1 in cells:
		neib.append(i - 1)
	if i % m != m - 1 and i + 1 in cells:
		neib.append(i + 1)
	if i >= m and i - m in cells:
		neib.append(i - m)
	if i < (n - 1) * m and i + m in cells:
		neib.append(i + m)
	if debug:
		print(i, neib)
	for j in neib:
		adj[i].add(j)
		adj[j].add(i)
if debug:
	print(adj)
from collections import deque

def bfs(v, g):
	(order, visited) = ([], set())
	q = deque()
	q.append(v)
	while q:
		current_v = q.popleft()
		if current_v in visited:
			continue
		order.append(current_v)
		visited.add(current_v)
		for neib in g[current_v]:
			if neib not in visited:
				q.append(neib)
	return order
order = bfs(list(cells)[0], adj)
if debug:
	print(order)
closed_cells = set(order[::-1][:k])
for i in range(n):
	line = ''.join(('X' if j in closed_cells else '.' if j in cells else '#' for j in range(m * i, m * (i + 1))))
	print(line)


(n, m, k) = map(int, input().split())
l = []
for i in range(n):
	l.append(list(input()))
total = n * m
for i in range(n):
	for j in range(m):
		if l[i][j] == '#':
			total -= 1
		if l[i][j] == '.':
			start = (i, j)
k = total - k
posetil = set()
if k > 0:
	posetil.add(start)
	sosed = set()
	sosed.add(start)
	while len(posetil) < k:
		sosed2 = set()
		for i in sosed:
			if len(posetil) == k:
				break
			x = i[0]
			y = i[1]
			for dx in [-1, 0, 1]:
				if len(posetil) == k:
					break
				for dy in [-1, 0, 1]:
					if len(posetil) == k:
						break
					if abs(dx) + abs(dy) == 1:
						if x + dx >= 0 and x + dx < n and (y + dy >= 0) and (y + dy < m):
							if l[x + dx][y + dy] == '.':
								if (x + dx, y + dy) not in posetil:
									posetil.add((x + dx, y + dy))
									sosed2.add((x + dx, y + dy))
		sosed = sosed2.copy()
for i in range(n):
	for j in range(m):
		if l[i][j] == '.' and (i, j) not in posetil:
			l[i][j] = 'X'
for i in l:
	print(*i, sep='')


(n, m, c) = map(int, input().split())
empty = 0
a = [['#' for i in range(m + 2)]]
for i in range(n):
	a.append(list('#' + input() + '#'))
	empty += len(list(filter(lambda x: x == '.', a[-1])))
a.append(['#' for i in range(m + 2)])
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if a[i][j] == '.':
			(x, y) = (i, j)
			break
seen = set()
q = [(x, y)]
while len(seen) < empty - c:
	(x, y) = q.pop()
	if (x, y) in seen:
		continue
	seen.add((x, y))
	for (dx, dy) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
		(x2, y2) = (x + dx, y + dy)
		if a[x2][y2] != '.':
			continue
		q.append((x2, y2))
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if a[i][j] == '.' and (i, j) not in seen:
			a[i][j] = 'X'
for i in range(1, n + 1):
	print(''.join(a[i][1:-1]))


(n, m, k) = map(int, input().split())
a = [['' for x in range(m)] for x in range(n)]
dopi = 0
for i in range(n):
	a[i] = list(input())
	dopi += a[i].count('.')
b = a.copy()
if k != 0:
	pos = [-1, -1]
	for lin in range(n):
		if pos != [-1, -1]:
			break
		for i in range(m):
			if a[lin][i] == '.':
				pos = [i, lin]
				break
	import collections
	k = dopi - k
	if pos != [-1, -1]:
		b[pos[1]][pos[0]] = '1'
		k -= 1
		q = collections.deque([pos])
	while len(q) != 0 and k > 0:
		now = q.popleft()
		if now[1] - 1 >= 0 and b[now[1] - 1][now[0]] == '.':
			k -= 1
			b[now[1] - 1][now[0]] = '1'
			q.append([now[0], now[1] - 1])
			if k == 0:
				break
		if now[1] + 1 < n and b[now[1] + 1][now[0]] == '.':
			k -= 1
			b[now[1] + 1][now[0]] = '1'
			q.append([now[0], now[1] + 1])
			if k == 0:
				break
		if now[0] - 1 >= 0 and b[now[1]][now[0] - 1] == '.':
			k -= 1
			b[now[1]][now[0] - 1] = '1'
			q.append([now[0] - 1, now[1]])
			if k == 0:
				break
		if now[0] + 1 < m and b[now[1]][now[0] + 1] == '.':
			k -= 1
			b[now[1]][now[0] + 1] = '1'
			q.append([now[0] + 1, now[1]])
			if k == 0:
				break
	for i in range(n):
		for j in range(m):
			if b[i][j] == '1':
				b[i][j] = '.'
			elif b[i][j] == '.':
				b[i][j] = 'X'
		s = ''
		for j in b[i]:
			s += str(j)
		print(s)
else:
	for i in range(n):
		s = ''
		for j in b[i]:
			s += str(j)
		print(s)


(n, m, k) = map(int, input().split())
arr = list((list(input()) for _ in range(n)))
lvl = [[0] * m for i in range(n)]
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
res = []

def is_valid(i, j):
	return i >= 0 and j >= 0 and (i < n) and (j < m)

def bfs(x, y):
	q = []
	q.append((x, y))
	lvl[x][y] = 1
	while q:
		(x, y) = q[0]
		q.pop(0)
		for t in range(4):
			nx = x + dx[t]
			ny = y + dy[t]
			if is_valid(nx, ny) and lvl[nx][ny] == 0 and (arr[nx][ny] == '.'):
				lvl[nx][ny] = lvl[x][y] + 1
				q.append((nx, ny))
				res.append((-lvl[nx][ny], nx, ny))
(x, y) = (-1, -1)
for i in range(n):
	if '.' in arr[i]:
		x = i
		y = arr[i].index('.')
		break
bfs(x, y)
res.sort()
for i in range(k):
	(_, x, y) = res[i]
	arr[x][y] = 'X'
print('\n'.join((''.join(i) for i in arr)))


from collections import deque
(n, m, k) = map(int, input().split())
grid = []
empty_cells = []
for i in range(n):
	grid.append(list(input()))
	for j in range(m):
		if grid[i][j] == '.':
			empty_cells.append((i, j))
empty_cell = empty_cells[0]
visited = [[[True, False][grid[i][j] == '.'] for j in range(m)] for i in range(n)]
q = deque()
visited[empty_cell[0]][empty_cell[1]] = True
q.append(empty_cell)
delta_x = [0, 0, -1, 1]
delta_y = [-1, 1, 0, 0]
z = 1
while q and z < len(empty_cells) - k:
	(i, j) = q.popleft()
	for x in range(4):
		ni = i + delta_x[x]
		nj = j + delta_y[x]
		if 0 <= ni < n and 0 <= nj < m and (visited[ni][nj] == False) and (grid[ni][nj] == '.') and (z < len(empty_cells) - k):
			visited[ni][nj] = True
			z += 1
			q.append((ni, nj))
for i in range(n):
	for j in range(m):
		if visited[i][j] == False:
			grid[i][j] = 'X'
for i in range(n):
	print(''.join(grid[i]))


from collections import deque
(n, m, k) = map(int, input().split())
field = [[0] * m for i in range(n)]
f = [list(input()) for i in range(n)]
x = 0
y = 0
num2 = 0
for i in range(n):
	for j in range(m):
		if f[i][j] == '.':
			x = i
			y = j
			num2 += 1
		else:
			field[i][j] = 2
num = 0
stack = deque()
stack.append([x, y])
k = num2 - k
while num < k:
	temp = stack.pop()
	i = temp[0]
	j = temp[1]
	if field[i][j] == 0:
		num += 1
	field[i][j] = 1
	if j + 1 < m and field[i][j + 1] == 0:
		stack.append([i, j + 1])
	if j - 1 > -1 and field[i][j - 1] == 0:
		stack.append([i, j - 1])
	if i + 1 < n and field[i + 1][j] == 0:
		stack.append([i + 1, j])
	if i - 1 > -1 and field[i - 1][j] == 0:
		stack.append([i - 1, j])
for i in range(n):
	for j in range(m):
		if field[i][j] == 0:
			f[i][j] = 'X'
		print(f[i][j], end='')
	print()


from sys import stdin
import sys
input = stdin.readline
(n, m, k) = map(int, input().split())
s = [list(input().rstrip()) for i in range(n)]
q = []
c = 0
for i in range(n):
	for j in range(m):
		if s[i][j] == '.':
			q.append((i, j))
			c += 1

def is_ok(i, j):
	if 0 <= i < n and 0 <= j < m and (s[i][j] == '.'):
		return True
	else:
		return False
vis = [[False] * m for i in range(n)]
sa = 0
while sa < c - k:
	(y, x) = q[-1]
	q.pop()
	if not vis[y][x]:
		if is_ok(y - 1, x):
			if not vis[y - 1][x]:
				q.append((y - 1, x))
		if is_ok(y + 1, x):
			if not vis[y + 1][x]:
				q.append((y + 1, x))
		if is_ok(y, x - 1):
			if not vis[y][x - 1]:
				q.append((y, x - 1))
		if is_ok(y, x + 1):
			if not vis[y][x + 1]:
				q.append((y, x + 1))
		vis[y][x] = True
		sa += 1
for i in range(n):
	for j in range(m):
		if s[i][j] == '.' and (not vis[i][j]):
			s[i][j] = 'X'
	print(''.join(s[i]))


import math
from collections import deque
left = -1

def bfs(g, sx, sy):
	global left
	q = deque()
	q.append((sx, sy))
	while left > 0:
		p = q.popleft()
		x = p[0]
		y = p[1]
		if g[y][x] == '.':
			g[y][x] = 'F'
			left -= 1
			if x > 0 and g[y][x - 1] == '.':
				q.append((x - 1, y))
			if x < len(g[0]) - 1 and g[y][x + 1] == '.':
				q.append((x + 1, y))
			if y > 0 and g[y - 1][x] == '.':
				q.append((x, y - 1))
			if y < len(g) - 1 and g[y + 1][x] == '.':
				q.append((x, y + 1))

def main():
	(n, m, k) = map(int, input().split())
	g = []
	s = 0
	x = 0
	y = 0
	for i in range(n):
		g.append(list(input().strip()))
		for j in range(m):
			c = g[i][j]
			if c == '.':
				s += 1
				x = j
				y = i
	global left
	left = s - k
	bfs(g, x, y)
	for l in g:
		for c in l:
			if c == '.':
				print('X', end='')
			elif c == 'F':
				print('.', end='')
			else:
				print(c, end='')
		print()
main()


def bfs(x, y):
	p = 0
	queue = [(x, y)]
	visited[x][y] = 1
	while queue:
		a = queue.pop(0)
		p += 1
		if p > yh - k:
			t[a[0]][a[1]] = 'X'
		a0 = a[0]
		a1 = a[1]
		if a0 + 1 < n and t[a0 + 1][a1] != '#' and (visited[a0 + 1][a1] == 0):
			queue.append((a0 + 1, a1))
			visited[a0 + 1][a1] = 1
		if a0 - 1 >= 0 and t[a0 - 1][a1] != '#' and (visited[a0 - 1][a1] == 0):
			queue.append((a0 - 1, a1))
			visited[a0 - 1][a1] = 1
		if a1 + 1 < m and t[a0][a1 + 1] != '#' and (visited[a0][a1 + 1] == 0):
			queue.append((a0, a1 + 1))
			visited[a0][a1 + 1] = 1
		if a1 - 1 >= 0 and t[a0][a1 - 1] != '#' and (visited[a0][a1 - 1] == 0):
			queue.append((a0, a1 - 1))
			visited[a0][a1 - 1] = 1
(n, m, k) = map(int, input().split())
t = []
yh = 0
for i in range(n):
	s = list(input())
	t.append(s)
	yh += s.count('.')
	if '.' in s:
		p = (i, s.index('.'))
visited = [[0 for i in range(m)] for j in range(n)]
bfs(p[0], p[1])
for j in t:
	print(''.join(j))


from collections import defaultdict
import sys
input = __import__('sys').stdin.readline
sys.setrecursionlimit(10 ** 5)
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]

def dfs(x, y):
	global vis
	global grid
	global k
	vis[x][y] = True
	for i in range(4):
		tempx = x + dx[i]
		tempy = y + dy[i]
		if (tempx < n and tempx >= 0) and (tempy < m and tempy >= 0):
			if not vis[tempx][tempy] and grid[tempx][tempy] == '.':
				dfs(tempx, tempy)
	if k > 0:
		grid[x][y] = 'X'
		k -= 1
	return
(n, m, k) = map(int, input().split())
adj = defaultdict(list)
grid = []
cnt = 0
for i in range(n):
	a = list(input().strip())
	grid.append(a)
	cnt += a.count('.')
vis = [[False for i in range(m)] for i in range(n)]
yep = False
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			stack = [[i, j]]
			vis[i][j] = True
			cnt -= 1
			while stack:
				node = stack.pop()
				x = node[0]
				y = node[1]
				vis[x][y] = True
				for i in range(4):
					if yep:
						break
					if cnt > k:
						tempx = x + dx[i]
						tempy = y + dy[i]
						if (tempx < n and tempx >= 0) and (tempy < m and tempy >= 0):
							if not vis[tempx][tempy] and grid[tempx][tempy] == '.':
								vis[tempx][tempy] = True
								stack.append([tempx, tempy])
								cnt -= 1
					else:
						yep = True
				if yep:
					break
		if yep:
			break
	if yep:
		break
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.' and (not vis[i][j]):
			grid[i][j] = 'X'
for x in grid:
	print(*x, sep='')


(n, m, k) = map(int, input().split())
mat = []
cnt = 0
c = 0
for i in range(n):
	mat.append(list(input()))
from collections import defaultdict

def ok(i, j):
	return 0 <= i < n and 0 <= j < m and (mat[i][j] == '.')
d = defaultdict(list)
for i in range(n):
	for j in range(m):
		if mat[i][j] == '#':
			continue
		cnt += 1
		st = (i, j)
		if ok(i + 1, j):
			d[i, j].append((i + 1, j))
		if ok(i - 1, j):
			d[i, j].append((i - 1, j))
		if ok(i, j + 1):
			d[i, j].append((i, j + 1))
		if ok(i, j - 1):
			d[i, j].append((i, j - 1))
q = [st]
vis = [[0 for j in range(m)] for i in range(n)]
vis[st[0]][st[1]] = 1
c = 0
while q:
	t = q.pop(0)
	c += 1
	mat[t[0]][t[1]] = '1'
	if c == cnt - k:
		break
	for x in d[t]:
		if not vis[x[0]][x[1]]:
			vis[x[0]][x[1]] = 1
			q.append((x[0], x[1]))
for i in range(n):
	for j in range(m):
		if mat[i][j] == '1':
			print('.', end='')
		elif mat[i][j] == '.':
			print('X', end='')
		elif mat[i][j] == '#':
			print('#', end='')
	print()


import sys
input = sys.stdin.readline
from collections import deque

def prog():
	(n, m, k) = map(int, input().split())
	maze = [input().strip() for i in range(n)]
	adj_list = [[0 for j in range(m)] for i in range(n)]
	for i in range(n):
		for j in range(m):
			adj_list[i][j] = [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]
	found = False
	for i in range(n):
		if found:
			break
		for j in range(m):
			if maze[i][j] == '.':
				start = (i, j)
				found = True
				break
	remove = set()
	visited = set()
	s = deque([start])
	while s:
		curr = s[-1]
		visited.add(curr)
		(i, j) = curr
		had_neighbor = False
		neighbors = adj_list[i][j]
		left = len(neighbors)
		while left:
			neighbor = neighbors.pop()
			(new_i, new_j) = neighbor
			if 0 <= new_i < n and 0 <= new_j < m and (maze[new_i][new_j] == '.') and (neighbor not in visited):
				had_neighbor = True
				s.append(neighbor)
				break
			left -= 1
		if not had_neighbor:
			if k:
				remove.add(curr)
				k -= 1
			else:
				break
			s.pop()
	for i in range(n):
		for j in range(m):
			if (i, j) in remove:
				sys.stdout.write('X')
			else:
				sys.stdout.write(maze[i][j])
		sys.stdout.write('\n')
prog()


from sys import stdin, stdout
from collections import defaultdict, deque
import sys

def dfs(graph, matrix, visited, k, node, n, m, function_stack):
	while True:
		if len(function_stack) == 0:
			break
		node = function_stack.pop()
		visited[node] = True
		if len(graph[node]) > 0 and k[0] > 0:
			for i in graph[node]:
				flag = 0
				if visited[i] == False and k[0] > 0:
					function_stack.append(node)
					function_stack.append(i)
					flag = 1
					break
			if k[0] > 0 and flag == 0:
				matrix[node // m][node % m] = 'X'
				k[0] -= 1

def transform(graph, matrix, n, m, k):
	visited = dict()
	for i in range(m * n):
		visited[i] = False
	function_stack = []
	for i in range(m * n):
		if visited[i] == False and k[0] > 0:
			function_stack.append(i)
			dfs(graph, matrix, visited, k, i, n, m, function_stack)
(n, m, k) = list(map(int, stdin.readline().split()))
k = [k]
matrix = []
for i in range(n):
	matrix.append(list(stdin.readline().strip()))
graph = defaultdict(list)
for i in range(m * n):
	graph[i]
for i in range(n):
	for j in range(m):
		if matrix[i][j] == '.':
			if j + 1 < m and matrix[i][j + 1] == '.':
				graph[i * m + j].append(i * m + j + 1)
				graph[i * m + j + 1].append(i * m + j)
			if i + 1 < n and matrix[i + 1][j] == '.':
				graph[i * m + j].append((i + 1) * m + j)
				graph[(i + 1) * m + j].append(i * m + j)
transform(graph, matrix, n, m, k)
for i in range(n):
	for j in range(m):
		stdout.write(matrix[i][j])
	stdout.write('\n')
stdin.readline()


(n, m, k) = list(map(int, input().split()))
maze = []
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc

class Graph:

	def __init__(self, V):
		self.V = V
		self.adj = [[] for i in range(V)]

	@bootstrap
	def DFSUtil(self, temp, v, visited, nodes_to_remove):
		visited[v] = True
		temp.append(v)
		for i in self.adj[v]:
			if visited[i] == False:
				temp = (yield self.DFSUtil(temp, i, visited, nodes_to_remove))
		nodes_to_remove.append(v)
		yield temp

	def addEdge(self, v, w):
		self.adj[v].append(w)

def check(i, j):
	if i >= 0 and i < n and (j >= 0) and (j < m) and (maze[i][j] != '#'):
		return True
	return False

def m_to_n(i, j):
	return i * m + j

def n_to_m(x):
	return (x // m, x % m)
G = Graph(n * m)
for _ in range(n):
	maze.append(list(input()))
start = -1
for i in range(0, n):
	for j in range(0, m):
		if maze[i][j] == '#':
			continue
		if start == -1:
			start = m_to_n(i, j)
		if check(i, j - 1):
			G.addEdge(m_to_n(i, j), m_to_n(i, j - 1))
		if check(i, j + 1):
			G.addEdge(m_to_n(i, j), m_to_n(i, j + 1))
		if check(i - 1, j):
			G.addEdge(m_to_n(i, j), m_to_n(i - 1, j))
		if check(i + 1, j):
			G.addEdge(m_to_n(i, j), m_to_n(i + 1, j))
visited = [False for _ in range(n * m)]
nodes_to_remove = []
G.DFSUtil([], start, visited, nodes_to_remove)
nodes_to_remove = [n_to_m(x) for x in nodes_to_remove]
for i in range(0, k):
	(a, b) = nodes_to_remove[i]
	maze[a][b] = 'X'
for i in maze:
	print(''.join(i))


def dfs(ii, jj):
	st = [(ii, jj)]
	while st:
		(i, j) = st.pop()
		if vis[i][j]:
			continue
		vis[i][j] = 1
		l.append((i, j))
		if i + 1 < n and vis[i + 1][j] == 0 and (g[i + 1][j] == '.'):
			st.append((i + 1, j))
		if j + 1 < m and vis[i][j + 1] == 0 and (g[i][j + 1] == '.'):
			st.append((i, j + 1))
		if i - 1 >= 0 and vis[i - 1][j] == 0 and (g[i - 1][j] == '.'):
			st.append((i - 1, j))
		if j - 1 >= 0 and vis[i][j - 1] == 0 and (g[i][j - 1] == '.'):
			st.append((i, j - 1))
(n, m, k) = map(int, input().split())
(g, l) = ([], [])
vis = [[0] * m for i in range(n)]
for i in range(n):
	g.append(list(input()))
f = 0
for i in range(n):
	for j in range(m):
		if g[i][j] == '.':
			dfs(i, j)
			f = 1
			break
	if f:
		break
for i in range(k):
	(x, y) = l.pop()
	g[x][y] = 'X'
for i in range(n):
	print(''.join(g[i]))


import sys
import os
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from queue import Queue
(n, m, k) = (0, 0, 0)
mtrx = []
visited = []
count = 0

def check(u, v):
	global n, m, mtrx
	if u < 0 or u > n - 1 or v < 0 or (v > m - 1):
		return False
	if visited[u][v] == 1 or mtrx[u][v] == '#':
		return False
	return True
ldx = [-1, 0, 1, 0]
ldy = [0, 1, 0, -1]

def bfs(sx, sy):
	global mtrx, visited, count, k
	q = Queue()
	q.put((sx, sy))
	visited[sx][sy] = 1
	mtrx[sx][sy] = '.'
	ll = 1
	while not q.empty():
		(a, b) = q.get()
		for i in range(4):
			if check(a + ldx[i], b + ldy[i]):
				(na, nb) = (a + ldx[i], b + ldy[i])
				q.put((na, nb))
				visited[na][nb] = 1
				mtrx[na][nb] = '.'
				ll += 1
			if ll == count - k:
				break
		if ll == count - k:
			break

def main():
	global n, m, k, visited, mtrx, count
	(n, m, k) = map(int, input().split())
	if k == 0:
		for i in range(n):
			print(input())
	else:
		visited = [[0 for j in range(m)] for i in range(n)]
		mtrx = []
		count = 0
		for i in range(n):
			l = []
			l = list(input().replace('.', 'X'))
			count += l.count('X')
			mtrx.append(l)
		xx = yy = 0
		for i in range(n):
			if 'X' in mtrx[i]:
				(xx, yy) = (i, mtrx[i].index('X'))
				break
		bfs(xx, yy)
		for i in mtrx:
			print(''.join(i))
main()


import sys
input = sys.stdin.readline
(n, m, k) = [int(x) for x in input().split()]
maze = []
for z in range(n):
	arr = list(input())
	maze.append(arr)
(s, cnt, first) = (0, 0, 0)
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.':
			s += 1
			if first == 0:
				(p, q) = (i, j)
				first = 1

def DFS(i, j):
	global n, m, k, s
	adj = [[0, 1], [0, -1], [1, 0], [-1, 0]]
	stack = [[i, j]]
	t = s - k
	if t > 0:
		maze[i][j] = 'Y'
		t = t - 1
	while stack:
		if t <= 0:
			return
		(i, j) = (stack[-1][0], stack[-1][1])
		stack.pop()
		for pair in adj:
			(x, y) = (i + pair[0], j + pair[1])
			if 0 <= x < n and 0 <= y < m and (maze[x][y] == '.'):
				if t <= 0:
					return
				maze[x][y] = 'Y'
				t = t - 1
				stack.append([x, y])
if s and k > 0:
	DFS(p, q)
if k > 0:
	for i in range(n):
		for j in range(m):
			if maze[i][j] == '.':
				maze[i][j] = 'X'
			elif maze[i][j] == 'Y':
				maze[i][j] = '.'
for i in range(n):
	s = ''
	for j in range(m):
		s = s + maze[i][j]
	print(s)


DESLOCAMENTO = ((-1, 0), (1, 0), (0, -1), (0, 1))

def possivel(i, j, n, m):
	return 0 <= i < n and 0 <= j < m

def site_vazio(maze, n, m):
	for i in range(n):
		for j in range(m):
			if maze[i][j] == '.':
				return (i, j)

def dfs(maze, n, m, limite):
	visitados = [[False] * m for _ in range(n)]
	(i, j) = site_vazio(maze, n, m)
	vizinhos = [(i, j)]
	count = 0
	while len(vizinhos) != 0:
		(i, j) = vizinhos.pop()
		visitados[i][j] = True
		count += 1
		if count > limite:
			maze[i][j] = 'X'
		for (di, dj) in DESLOCAMENTO:
			novoi = i + di
			novoj = j + dj
			if possivel(novoi, novoj, n, m) and (not visitados[novoi][novoj]) and (maze[novoi][novoj] == '.'):
				vizinhos.append((novoi, novoj))
				visitados[novoi][novoj] = True
(n, m, k) = [int(x) for x in input().split()]
maze = [[s for s in input()] for _ in range(n)]
total_livre = sum((linha.count('.') for linha in maze))
dfs(maze, n, m, total_livre - k)
for linha in maze:
	print(*linha, sep='')


(r, c, n) = map(int, input().split())
field = []
field.append('#' * (c + 2))
for _ in range(r):
	field.append('#' + input() + '#')
field.append('#' * (c + 2))
p_x = 0
p_y = 0
not_walls = 0
for x in range(1, r + 1):
	for y in range(1, c + 1):
		if field[x][y] == '#':
			continue
		(p_x, p_y) = (x, y)
		not_walls += 1
process = [(p_x, p_y)]
valid = set()
while len(valid) < not_walls - n:
	(x, y) = process.pop()
	valid.add((x, y))
	for (a, b) in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
		if field[a + x][b + y] == '.' and (a + x, b + y) not in valid:
			process.append((x + a, y + b))
for x in range(1, r + 1):
	for y in range(1, c + 1):
		if field[x][y] == '#':
			continue
		if (x, y) not in valid:
			field[x] = field[x][:y] + 'X' + field[x][y + 1:]
field = [x[1:-1] for x in field[1:-1]]
print('\n'.join(field))


from sys import setrecursionlimit
setrecursionlimit(100000)
from collections import deque
(sizeI, sizeJ, k) = map(int, input().split())
a = [list(input()) for _ in range(sizeI)]

def dfs(i, j):
	if len(cells) < need:
		cells.append((i, j))
	visited[i][j] = True
	for (di, dj) in ((0, -1), (0, 1), (-1, 0), (1, 0)):
		(ni, nj) = (i + di, j + dj)
		if 0 <= ni < sizeI and 0 <= nj < sizeJ and (a[ni][nj] == '.') and (not visited[ni][nj]):
			dfs(ni, nj)

def bfs(startI, startJ):
	q = deque([(startI, startJ)])
	visited[startI][startJ] = True
	while q:
		(i, j) = q.pop()
		if len(cells) < need:
			cells.append((i, j))
		for (di, dj) in ((0, -1), (0, 1), (-1, 0), (1, 0)):
			(ni, nj) = (i + di, j + dj)
			if 0 <= ni < sizeI and 0 <= nj < sizeJ and (a[ni][nj] == '.') and (not visited[ni][nj]):
				visited[ni][nj] = True
				q.appendleft((ni, nj))
startI = startJ = None
cnt = 0
for i in range(sizeI):
	for j in range(sizeJ):
		if a[i][j] == '.':
			cnt += 1
			(startI, startJ) = (i, j)
need = cnt - k
cells = []
visited = [[False for _ in range(sizeJ)] for _ in range(sizeI)]
bfs(startI, startJ)
for i in range(sizeI):
	for j in range(sizeJ):
		if a[i][j] == '.':
			a[i][j] = 'X'
for (i, j) in cells:
	a[i][j] = '.'
print('\n'.join((''.join(row) for row in a)))