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:
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()


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()


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())


from sys import stdin
from collections import deque
(R, C, K) = 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)


from collections import deque

def neighbours(v):
	out = set()
	(x, y) = v
	if 0 <= x + 1 < m and 0 <= y < n:
		out.add((x + 1, y))
	if 0 <= x - 1 < m and 0 <= y < n:
		out.add((x - 1, y))
	if 0 <= x < m and 0 <= y + 1 < n:
		out.add((x, y + 1))
	if 0 <= x < m and 0 <= y - 1 < n:
		out.add((x, y - 1))
	return out

def bfs(v):
	queue = deque([v])
	visited_dots = 0
	while queue:
		(vx, vy) = queue.popleft()
		if g[vy][vx] == 2:
			continue
		g[vy][vx] = 2
		visited_dots += 1
		if visited_dots == dots - k:
			return
		for (ux, uy) in neighbours((vx, vy)):
			if g[uy][ux] == 0:
				queue.append((ux, uy))
(n, m, k) = map(int, input().split())
g = []
visited = set()
dots = 0
v = None
for j in range(n):
	s = list(map(lambda x: 0 if x == '.' else 1, input()))
	if not v and 0 in s:
		v = (s.index(0), j)
	dots += m - sum(s)
	g.append(s)
bfs(v)
for j in range(n):
	for i in range(m):
		if g[j][i] == 0:
			print('X', end='')
		elif g[j][i] == 1:
			print('#', end='')
		else:
			print('.', end='')
	print()


from collections import *
(n, m, k) = map(int, input().split())
b = [input() for _ in range(n)]
c = [[[] for z in range(m)] for _ in range(n)]
ans = 0
r = [[0] * m for i in range(n)]
s = 0
(q, w) = (-1, -1)

def f(i, y):
	an = []
	if i > 0:
		an.append([i - 1, y])
	if y > 0:
		an.append([i, y - 1])
	if i < n - 1:
		an.append([i + 1, y])
	if y < m - 1:
		an.append([i, y + 1])
	return an
for i in range(n):
	for y in range(m):
		if b[i][y] == '.':
			s += 1
			q = i
			w = y
			for j in f(i, y):
				if b[j[0]][j[1]] == '.':
					c[i][y].append(j)

def dfs(i, y):
	global ans
	d = deque()
	d.append([i, y])
	ans = 1
	r[i][y] = 1
	while ans != s - k:
		z = d.pop()
		(i, y) = (z[0], z[1])
		r[i][y] = 1
		for x in range(len(c[i][y])):
			if r[c[i][y][x][0]][c[i][y][x][1]] == 0:
				d.append([c[i][y][x][0], c[i][y][x][1]])
				r[c[i][y][x][0]][c[i][y][x][1]] = 1
				ans += 1
				if ans == s - k:
					break
if not q == w == -1:
	dfs(q, w)
for i in range(n):
	for y in range(m):
		if b[i][y] == '.' and r[i][y] == 0:
			r[i][y] = 'X'
		else:
			r[i][y] = b[i][y]
for i in range(n):
	print(''.join(r[i]))


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 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 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()


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))


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', '.'))


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]))


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
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

def pmat(A):
	for ele in A:
		print(*ele, end='\n')

def seive():
	prime = [1 for i in range(10 ** 6 + 1)]
	prime[0] = 0
	prime[1] = 0
	for i in range(10 ** 6 + 1):
		if prime[i]:
			for j in range(2 * i, 10 ** 6 + 1, i):
				prime[j] = 0
	return prime
(n, m, k) = L()
A = [list(sl()[0]) for i in range(n)]

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


from collections import deque
dirs = ((1, 0), (0, 1), (-1, 0), (0, -1))

def valid(r, c):
	return 0 <= r < n and 0 <= c < m and (grid[r][c] == '.')

def dfs(r, c, count, viewed):
	queue = deque()
	queue.append((r, c))
	viewed[r][c] = True
	count -= 1
	while len(queue) != 0 and count > 0:
		(r, c) = queue.popleft()
		for (dr, dc) in dirs:
			if valid(r + dr, c + dc) and (not viewed[r + dr][c + dc]):
				viewed[r + dr][c + dc] = True
				queue.append((r + dr, c + dc))
				count -= 1
			if count == 0:
				break
(n, m, k) = map(int, input().split())
grid = [list(input()) for _ in range(n)]
(r, c) = (-1, -1)
empty_count = 0
for (ii, i) in enumerate(grid):
	for (jj, j) in enumerate(i):
		if j == '.':
			(r, c) = (ii, jj)
			empty_count += 1
viewed = [[False] * m for _ in range(n)]
dfs(r, c, empty_count - k, viewed)
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.' and (not viewed[i][j]):
			grid[i][j] = 'X'
for i in grid:
	print(''.join(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', '.'))


(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))


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
(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)


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')


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()


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()


import sys
import math
sys.setrecursionlimit(300000)
MAXNUM = math.inf
MINNUM = -1 * math.inf

def getInt():
	return int(sys.stdin.readline().rstrip())

def getInts():
	return map(int, sys.stdin.readline().rstrip().split(' '))

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

def printOutput(ans):
	for line in ans:
		for ele in line:
			sys.stdout.write(ele)
		sys.stdout.write('\n')

def emptySquares(g):
	total = 0
	firstEmpty = None
	for i in range(len(g)):
		for j in range(len(g[0])):
			if g[i][j] != '#':
				total += 1
				firstEmpty = (i, j)
	return (total, firstEmpty)
toDelete = []

def dfs(grid, visited, toSave, x, y):
	if (x, y) not in visited:
		visited[x, y] = True
		if toSave:
			toSave -= 1
		else:
			toDelete.append((x, y))
		for (i, j) in zip((-1, 1, 0, 0), (0, 0, 1, -1)):
			if -1 < x + i < len(grid) and -1 < y + j < len(grid[0]) and ((x + i, y + j) not in visited) and (grid[x + i][y + j] != '#'):
				toSave = dfs(grid, visited, toSave, x + i, y + j)
	return toSave

def iterativedfs(grid, toSave, x, y):
	stack = [(x, y)]
	visited = {}
	visited[x, y] = True
	toDelete = []
	while stack:
		(x, y) = stack.pop()
		if toSave != 0:
			toSave -= 1
		else:
			toDelete.append((x, y))
		for (i, j) in zip((-1, 1, 0, 0), (0, 0, 1, -1)):
			if -1 < x + i < len(grid) and -1 < y + j < len(grid[0]) and ((x + i, y + j) not in visited) and (grid[x + i][y + j] != '#'):
				stack.append((x + i, y + j))
				visited[x + i, y + j] = True
	return toDelete

def solve(n, m, k, grid):
	if k == 0:
		return grid
	(empty, firstEmpty) = emptySquares(grid)
	(x, y) = firstEmpty
	toDelete = iterativedfs(grid, empty - k, x, y)
	for (a, b) in toDelete:
		grid[a][b] = 'X'
	return grid

def readinput():
	(n, m, k) = getInts()
	grid = []
	for _ in range(n):
		grid.append([i for i in getString()])
	printOutput(solve(n, m, k, grid))
readinput()