The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cell is either land or water. The map is surrounded by the ocean. 

Lakes are the maximal regions of water cells, connected by sides, which are not connected with the ocean. Formally, lake is a set of water cells, such that it's possible to get from any cell of the set to any other without leaving the set and moving only to cells adjacent by the side, none of them is located on the border of the rectangle, and it's impossible to add one more water cell to the set such that it will be connected with any other cell.

You task is to fill up with the earth the minimum number of water cells so that there will be exactly k lakes in Berland. Note that the initial number of lakes on the map is not less than k. 


-----Input-----

The first line of the input contains three integers n, m and k (1 ≤ n, m ≤ 50, 0 ≤ k ≤ 50) — the sizes of the map and the number of lakes which should be left on the map.

The next n lines contain m characters each — the description of the map. Each of the characters is either '.' (it means that the corresponding cell is water) or '*' (it means that the corresponding cell is land).

It is guaranteed that the map contain at least k lakes.


-----Output-----

In the first line print the minimum number of cells which should be transformed from water to land. 

In the next n lines print m symbols — the map after the changes. The format must strictly follow the format of the map in the input data (there is no need to print the size of the map). If there are several answers, print any of them. 

It is guaranteed that the answer exists on the given data.


-----Examples-----
Input
5 4 1
****
*..*
****
**.*
..**

Output
1
****
*..*
****
****
..**

Input
3 3 0
***
*.*
***

Output
1
***
***
***



-----Note-----

In the first example there are only two lakes — the first consists of the cells (2, 2) and (2, 3), the second consists of the cell (4, 3). It is profitable to cover the second lake because it is smaller. Pay attention that the area of water in the lower left corner is not a lake because this area share a border with the ocean.

Difficulty: MEDIUM_HARD
Tags: Graph algorithms

Graph traversal

Implementation

Greedy algorithms

Spanning trees
Skill types: Greedy algorithms

Starter code:

Solutions:
(n, m, k) = map(int, input().split())
grid = [['.' for x in range(m + 2)]]
for i in range(n):
	grid.append(['.'] + list(input()) + ['.'])
grid.append(['.' for x in range(m + 2)])
chk = [[0 for x in range(m + 2)] for x in range(n + 2)]
cur = 1
moves = [[0, 1], [0, -1], [1, 0], [-1, 0]]
lakes = []
for i in range(n + 2):
	for j in range(m + 2):
		if not chk[i][j] and grid[i][j] == '.':
			queue = [[i, j]]
			chk[i][j] = cur
			res = 1
			while queue:
				c = queue.pop(0)
				for l in moves:
					(y, x) = (c[0] + l[0], c[1] + l[1])
					if y >= n + 2 or y < 0 or x >= m + 2 or (x < 0):
						continue
					if grid[y][x] == '.' and (not chk[y][x]):
						queue.append([y, x])
						chk[y][x] = cur
						res += 1
			if i != 0:
				lakes.append([res, i, j])
lakes = sorted(lakes)
ans = 0
for i in range(len(lakes) - k):
	queue = [[lakes[i][1], lakes[i][2]]]
	grid[lakes[i][1]][lakes[i][2]] = '*'
	while queue:
		c = queue.pop(0)
		for l in moves:
			(y, x) = (c[0] + l[0], c[1] + l[1])
			if y >= n + 2 or y < 0 or x >= m + 2 or (x < 0):
				continue
			if grid[y][x] == '.':
				queue.append([y, x])
				grid[y][x] = '*'
	ans += lakes[i][0]
print(ans)
for i in range(1, n + 1):
	print(''.join(grid[i][1:-1]))


from collections import Counter, defaultdict
(n, m, k) = [int(x) for x in input().split()]
mp = [['.'] * (m + 2)] + [list('.' + input().strip() + '.') for _ in range(n)] + [['.'] * (m + 2)]
uf = {}
for i in range(n + 2):
	for j in range(m + 2):
		uf[i, j] = (i, j)

def find(u):
	if u != uf[u]:
		uf[u] = find(uf[u])
	return uf[u]

def union(u, v):
	pu = find(u)
	pv = find(v)
	if pu != pv:
		uf[pv] = pu
for i in range(n + 2):
	for j in range(m + 2):
		if mp[i][j] == '*':
			continue
		if i <= n and mp[i + 1][j] == '.':
			union((i, j), (i + 1, j))
		if j <= m and mp[i][j + 1] == '.':
			union((i, j), (i, j + 1))
d = defaultdict(int)
f0 = find((0, 0))
for i in range(n + 2):
	for j in range(m + 2):
		if mp[i][j] == '*':
			continue
		f = find((i, j))
		if f != f0:
			d[f] += 1
l = sorted([(v, k) for (k, v) in list(d.items())])
ll = len(l)
ps = set([u for (_, u) in l[:ll - k]])
r = 0
for i in range(1, n + 1):
	for j in range(1, m + 1):
		if mp[i][j] == '.' and find((i, j)) in ps:
			mp[i][j] = '*'
			r += 1
print(r)
print('\n'.join((''.join(m[1:-1]) for m in mp[1:-1])))


from copy import copy, deepcopy
import heapq
(m, n, num_lake) = [int(i) for i in input().split()]
Matrix = []
Real_Matrix = []
arr = []
for i in range(m):
	arr = [0 if j == '*' else 1 for j in input()]
	Real_Matrix.append(arr)
Matrix = deepcopy(Real_Matrix)

def is_border(pos_x, pos_y, m, n):
	if pos_x == 0 or pos_x == m - 1 or pos_y == 0 or (pos_y == n - 1):
		return True
	return False

def contain_border(result, m, n):
	for i in result:
		if is_border(i[0], i[1], m, n):
			return True
	return False

def generate_neighbour(matrix_input, pos_x, pos_y, m, n):
	arr = []
	for i in range(-1, 2):
		for j in range(-1, 2):
			if i == 0 and j == 0 or (i == -1 and j == -1) or (i == 1 and j == -1) or (i == -1 and j == 1) or (i == 1 and j == 1):
				continue
			if pos_x + i > -1 and pos_y + j > -1 and (pos_x + i < m) and (pos_y + j < n):
				if matrix_input[pos_x + i][pos_y + j] == 1:
					arr.append([pos_x + i, pos_y + j])
	return arr

def dfs_iterative(matrix, start_x_position, start_y_position, m, n):
	(stack, path) = ([[start_x_position, start_y_position]], [])
	while stack:
		(curren_x, curren_y) = stack.pop()
		if [curren_x, curren_y] in path:
			continue
		path.append([curren_x, curren_y])
		Matrix[curren_x][curren_y] = 2
		neighbour = generate_neighbour(Matrix, curren_x, curren_y, m, n)
		for (pos_x, pos_y) in neighbour:
			stack.append([pos_x, pos_y])
	return path

def make_lake(Matrix):
	land_array = []
	result = []
	min_cell = 9999999
	for i in range(m):
		for j in range(n):
			if Matrix[i][j] == 1:
				land_array = dfs_iterative(Matrix, i, j, m, n)
				if contain_border(land_array, m, n):
					continue
				heapq.heappush(result, (len(land_array), land_array))
	return result

def rebuild_Matrix(Matrix):
	result = ''
	for i in Matrix:
		result = ''.join(('*' if j == 0 else '.' for j in i))
		print(result)
m = make_lake(Matrix)
num_real_lake = len(m)
count = 0
for i in range(num_real_lake - num_lake):
	term_value = heapq.heappop(m)
	count = count + term_value[0]
	for j in term_value[1]:
		Real_Matrix[j[0]][j[1]] = 0
print(count)
rebuild_Matrix(Real_Matrix)


import sys
sys.setrecursionlimit(100000000)
s = []
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
a = []
global visited
global count
(n, m) = (None, None)

class lake:
	x = 0
	y = 0
	area = 0

	def __init__(self, x, y, area):
		self.x = x
		self.y = y
		self.area = area

	def __lt__(self, other):
		if self.area < other.area:
			return True
		return False

def check(x, y):
	if x < 0 or x > n - 1 or y < 0 or (y > m - 1):
		return False
	if s[x][y] != '.':
		return False
	if visited[x][y]:
		return False
	return True

def DFS(s, x, y):
	global visited
	visited[x][y] = True
	s[x][y] = '?'
	for i in range(4):
		xx = x + dx[i]
		yy = y + dy[i]
		if check(xx, yy):
			DFS(s, xx, yy)

def DFS2(s, x, y):
	global visited
	global count
	visited[x][y] = True
	count += 1
	for i in range(4):
		xx = x + dx[i]
		yy = y + dy[i]
		if check(xx, yy):
			DFS2(s, xx, yy)

def check3(x, y):
	if x < 0 or x > n - 1 or y < 0 or (y > m - 1):
		return False
	if s[x][y] != '.':
		return False
	return True

def DFS3(s, x, y):
	s[x][y] = '*'
	for i in range(4):
		xx = x + dx[i]
		yy = y + dy[i]
		if check3(xx, yy):
			DFS3(s, xx, yy)
(n, m, k) = map(int, input().split())
for i in range(n):
	s.append(list(input()))
visited = [[False for j in range(m)] for i in range(n)]
for i in range(n):
	for j in range(m):
		if (i == 0 or i == n - 1 or j == 0 or (j == m - 1)) and s[i][j] == '.':
			DFS(s, i, j)
for i in range(n):
	for j in range(m):
		if s[i][j] == '.' and visited[i][j] == False:
			count = 0
			DFS2(s, i, j)
			a.append(lake(i, j, count))
a.sort()
sum = 0
for i in range(len(a) - k):
	DFS3(s, a[i].x, a[i].y)
	sum += a[i].area
print(sum)
for i in range(n):
	for j in range(m):
		if s[i][j] == '?':
			print('.', end='')
		else:
			print(s[i][j], end='')
	print()


from sys import stdin, stdout
from sys import setrecursionlimit
setrecursionlimit(10 ** 6)
(n, m, k) = map(int, stdin.readline().split())
maps = []
lake = []
visit = [[0 for i in range(m)] for j in range(n)]

def check(s, c):
	global cnt
	cnt += 1
	visit[s][c] = 1
	if s + 1 < n and maps[s + 1][c] == '.' and (not visit[s + 1][c]):
		check(s + 1, c)
	if s - 1 >= 0 and maps[s - 1][c] == '.' and (not visit[s - 1][c]):
		check(s - 1, c)
	if c + 1 < m and maps[s][c + 1] == '.' and (not visit[s][c + 1]):
		check(s, c + 1)
	if c - 1 >= 0 and maps[s][c - 1] == '.' and (not visit[s][c - 1]):
		check(s, c - 1)
for i in range(n):
	maps.append(list(stdin.readline().strip()))
cnt = 0
for i in range(n):
	if maps[i][0] == '.':
		check(i, 0)
	if maps[i][m - 1] == '.':
		check(i, m - 1)
for j in range(m):
	if maps[0][j] == '.':
		check(0, j)
	if maps[n - 1][j] == '.':
		check(n - 1, j)
challengers = []
for i in range(n):
	for j in range(m):
		if maps[i][j] == '.' and (not visit[i][j]):
			cnt = 0
			check(i, j)
			challengers.append((cnt, (i, j)))
challengers.sort()
queue = []
visit = [[0 for i in range(m)] for j in range(n)]
cnt = 0
for i in range(len(challengers) - k):
	cnt += challengers[i][0]
	queue.append(challengers[i][1])
(h, t) = (0, len(challengers) - k)
while h < t:
	(s, c) = queue[h]
	maps[s][c] = '*'
	h += 1
	if s + 1 < n and maps[s + 1][c] == '.' and (not visit[s + 1][c]):
		visit[s + 1][c] = 1
		queue.append((s + 1, c))
		t += 1
	if s - 1 >= 0 and maps[s - 1][c] == '.' and (not visit[s - 1][c]):
		visit[s - 1][c] = 1
		queue.append((s - 1, c))
		t += 1
	if c + 1 < m and maps[s][c + 1] == '.' and (not visit[s][c + 1]):
		visit[s][c + 1] = 1
		queue.append((s, c + 1))
		t += 1
	if c - 1 >= 0 and maps[s][c - 1] == '.' and (not visit[s][c - 1]):
		visit[s][c - 1] = 1
		queue.append((s, c - 1))
		t += 1
stdout.write(str(cnt) + '\n')
for i in range(n):
	stdout.write(''.join(maps[i]) + '\n')


import collections

def do():
	(row, col, k) = map(int, input().split(' '))
	g = [[''] * col for _ in range(row)]
	for i in range(row):
		for (j, c) in enumerate(input()):
			g[i][j] = c
	d = {}
	seen = [[0] * col for _ in range(row)]

	def bfs(i, j, id):
		area = 0
		q = collections.deque()
		q.append((i, j))
		while q:
			(x, y) = q.popleft()
			g[x][y] = id
			area += 1
			for (nx, ny) in ((x + 1, y), (x - 1, y), (x, y - 1), (x, y + 1)):
				if 0 <= nx < row and 0 <= ny < col and (g[nx][ny] == '.') and (not seen[nx][ny]):
					seen[nx][ny] = 1
					q.append((nx, ny))
		d[id] = area
		return

	def bfs2(i, j):
		q = collections.deque()
		q.append((i, j))
		while q:
			(x, y) = q.popleft()
			g[x][y] = '..'
			for (nx, ny) in ((x + 1, y), (x - 1, y), (x, y - 1), (x, y + 1)):
				if 0 <= nx < row and 0 <= ny < col and (g[nx][ny] == '.') and (not seen[nx][ny]):
					seen[nx][ny] = 1
					q.append((nx, ny))
		return
	for i in range(row):
		if g[i][0] == '.' and (not seen[i][0]):
			seen[i][0] = 1
			bfs2(i, 0)
		if g[i][col - 1] == '.' and (not seen[i][col - 1]):
			seen[i][col - 1] = 1
			bfs2(i, col - 1)
	for j in range(col):
		if g[0][j] == '.' and (not seen[0][j]):
			seen[0][j] = 1
			bfs2(0, j)
		if g[row - 1][j] == '.' and (not seen[row - 1][j]):
			seen[row - 1][j] = 1
			bfs2(row - 1, j)
	cur = 0
	for i in range(row):
		for j in range(col):
			if g[i][j] == '.' and (not seen[i][j]):
				seen[i][j] = 1
				bfs(i, j, cur)
				cur += 1
	delete = set()
	if k < cur:
		delete = set(sorted(d.keys(), key=lambda x: d[x])[:cur - k])
	if delete:
		print(sum((d[_] for _ in delete)))
	else:
		print(0)
	for i in range(row):
		for j in range(col):
			if g[i][j] == '..':
				g[i][j] = '.'
			elif g[i][j] == '*':
				continue
			elif g[i][j] in delete:
				g[i][j] = '*'
			else:
				g[i][j] = '.'
	for _ in g:
		print(''.join(_))
	return
do()


import sys

def delete(j, m):
	global a
	i = 0
	while i < len(oz[j]):
		(w, b) = (oz[j][i], oz[j][i + 1])
		i += 2
		a[w][b] = '*'

def poi(i, j, k):
	visited[i][j] = True
	oz[k] += (i, j)
	ozsi[k] += 1
	if j - 1 >= 0 and a[i][j - 1] == '.' and (not visited[i][j - 1]):
		poi(i, j - 1, k)
	if j + 1 <= m + 1 and a[i][j + 1] == '.' and (not visited[i][j + 1]):
		poi(i, j + 1, k)
	if i - 1 >= 0 and a[i - 1][j] == '.' and (not visited[i - 1][j]):
		poi(i - 1, j, k)
	if i + 1 <= n + 1 and a[i + 1][j] == '.' and (not visited[i + 1][j]):
		poi(i + 1, j, k)
(n, m, vb) = map(int, input().split())
a = []
oz = []
ozsi = []
visited = [[False for r in range(m + 2)] for t in range(n + 2)]
a.append(['.'] * (m + 2))
sys.setrecursionlimit(3000)
for i in range(n):
	s = '.' + input() + '.'
	a.append([str(x) for x in s])
k = 0
a.append(['.'] * (m + 2))
for i in range(0, n + 2):
	for j in range(0, m + 2):
		if a[i][j] == '.':
			if not visited[i][j]:
				ozsi.append(0)
				oz.append([])
				poi(i, j, k)
				k += 1
t = len(ozsi) - vb - 1
e = 0
for i in range(t):
	min = 10 ** 10
	minj = 0
	for j in range(1, len(ozsi)):
		if ozsi[j] < min:
			min = ozsi[j]
			minj = j
	e += min
	delete(minj, min)
	ozsi[minj] = 10 ** 10
print(e)
for i in range(1, n + 1):
	for j in range(1, m + 1):
		print(a[i][j], end='')
	print()


DEFAULT = -3
OCEAN = -2
METALAKE = -1

def convert(c):
	if c == '*':
		return False
	return True

def get_root(leaf, lake):
	lk = lake[leaf]
	ind = leaf
	while lk[1] >= 0:
		ind = lk[1]
		lk = lake[lk[1]]
	ind2 = leaf
	while ind2 > ind:
		tmp = lake[ind2][1]
		lake[ind2] = (lake[ind2][0], ind)
		ind2 = tmp
	return ind
(n, m, k) = map(int, input().split())
land = []
for i in range(n):
	land.append(list(map(convert, input())))
curr_lake = 0
lake = []
attach = [[DEFAULT for _ in range(m)] for __ in range(n)]
for i in range(n):
	for j in range(m):
		if not land[i][j]:
			continue
		neigh = []
		if i > 0 and land[i - 1][j]:
			neigh.append(attach[i - 1][j])
		if j > 0 and land[i][j - 1]:
			neigh.append(attach[i][j - 1])
		if neigh == []:
			lk = (1, METALAKE)
			if min(i, j) == 0 or j == m - 1 or i == n - 1:
				lk = (1, OCEAN)
			lake.append(lk)
			attach[i][j] = curr_lake
			curr_lake += 1
		else:
			lks = sorted(list(map(lambda nbr: get_root(nbr, lake), neigh)))
			if min(i, j) == 0 or j == m - 1 or i == n - 1:
				lake_type = OCEAN
				total_area = 0
			else:
				lake_type = min(map(lambda ind: lake[ind][1], lks))
				total_area = 1 + sum(map(lambda ind: lake[ind][0], lks))
			for ind in lks[1:]:
				lake[ind] = (lake[ind][0], lks[0])
			attach[i][j] = lks[0]
			lake[lks[0]] = (total_area, lake_type)
parent_lakes = filter(lambda tup: tup[1][1] == METALAKE, list(enumerate(lake)))
not_needed = set(list(map(lambda tup: tup[0], sorted(parent_lakes, key=lambda tup: tup[1][0], reverse=True)))[k:])
changed = 0
for i in range(n):
	for j in range(m):
		if not land[i][j]:
			continue
		if attach[i][j] < 0:
			continue
		rt = get_root(attach[i][j], lake)
		if rt in not_needed:
			land[i][j] = False
			changed += 1
print(changed)
for i in range(n):
	print(''.join(map(lambda x: '.' if x else '*', land[i])))


def check_valid(u, v):
	if u < 0 or v < 0:
		return False
	if u >= N or v >= M:
		return False
	return True

def travel_graph_valid(u, v):
	nodes = []
	for (x, y) in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
		if check_valid(u + x, v + y):
			try:
				if rect[u + x][v + y] == '.':
					nodes.append((u + x, v + y))
			except:
				print(u + x, v + y)
	return nodes

def dfs_save_source_on_rectangle(su, sv, from_border=False):
	stack = []
	source[su][sv] = (su, sv)
	stack.append((su, sv))
	cnt_node_from_source = 1
	while len(stack) > 0:
		(u, v) = stack.pop()
		for (u_, v_) in travel_graph_valid(u, v):
			if source[u_][v_] == -1:
				source[u_][v_] = source[u][v]
				cnt_node_from_source += 1
				stack.append((u_, v_))
	if from_border == False:
		comp_size_from_source.append(((su, sv), cnt_node_from_source))

def check_unvisited_water(u, v):
	if rect[u][v] == '.' and source[u][v] == -1:
		return True
	return False

def solve():
	for i in range(M):
		if check_unvisited_water(0, i):
			dfs_save_source_on_rectangle(0, i, from_border=True)
		if check_unvisited_water(N - 1, i):
			dfs_save_source_on_rectangle(N - 1, i, from_border=True)
	for j in range(N):
		if check_unvisited_water(j, 0):
			dfs_save_source_on_rectangle(j, 0, from_border=True)
		if check_unvisited_water(j, M - 1):
			dfs_save_source_on_rectangle(j, M - 1, from_border=True)
	for i in range(1, N - 1):
		for j in range(1, M - 1):
			if check_unvisited_water(i, j):
				dfs_save_source_on_rectangle(i, j, from_border=False)
	comp_size_from_source.sort(key=lambda x: x[1])
	to_fill = comp_size_from_source[:len(comp_size_from_source) - K]
	water_to_fill_size = [x[1] for x in to_fill]
	source_to_fill = set([x[0] for x in to_fill])
	total_water_to_fill = sum(water_to_fill_size)
	for i in range(1, N - 1):
		for j in range(1, M - 1):
			if source[i][j] in source_to_fill:
				rect[i][j] = '*'
	print(total_water_to_fill)
	for i in range(N):
		print(''.join(rect[i]))
(N, M, K) = [int(_) for _ in input().split()]
rect = [list(input().strip()) for _ in range(N)]
source = [[-1] * M for _ in range(N)]
comp_size_from_source = []
solve()


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

def safe(i, j):
	if -1 < i < n and -1 < j < m:
		return True
	return False
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

@bootstrap
def dfs(i, j):
	V[i][j] = True
	global c
	global temp
	global f
	temp.append([i, j])
	c += 1
	if safe(i - 1, j):
		if X[i - 1][j] == '.' and (not V[i - 1][j]):
			yield dfs(i - 1, j)
	else:
		f = 0
	if safe(i, j - 1):
		if X[i][j - 1] == '.' and (not V[i][j - 1]):
			yield dfs(i, j - 1)
	else:
		f = 0
	if safe(i + 1, j):
		if X[i + 1][j] == '.' and (not V[i + 1][j]):
			yield dfs(i + 1, j)
	else:
		f = 0
	if safe(i, j + 1):
		if X[i][j + 1] == '.' and (not V[i][j + 1]):
			yield dfs(i, j + 1)
	else:
		f = 0
	yield
(n, m, k) = INL()
X = []
for _ in range(n):
	X.append(list(input()))
u = 0
for _ in range(n):
	u += X[_].count('.')
V = [[False for _ in range(m)] for _ in range(n)]
ANS = []
for _ in range(n):
	for __ in range(m):
		c = 0
		temp = []
		global f
		f = 1
		if X[_][__] == '.' and (not V[_][__]):
			dfs(_, __)
			if f:
				ANS.append([c, temp])
ANS.sort()
ans = 0
for _ in ANS[:len(ANS) - k]:
	s = _[0]
	pair = _[1]
	for (i, j) in pair:
		X[i][j] = '*'
		ans += 1
print(ans)
for _ in range(n):
	print(''.join(X[_]))


from os import path
from io import BytesIO, IOBase
import sys
from heapq import heappush, heappop
from functools import cmp_to_key as ctk
from collections import deque, Counter, defaultdict as dd
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().rstrip()

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

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
mod = 998244353
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def bo(i):
	return ord(i) - ord('0')
file = 1

def ceil(a, b):
	return (a + b - 1) // b

def solve():
	(n, m, k1) = mi()
	a = [[] for i in range(n * m)]
	grid = []
	for i in range(n):
		grid.append(list(si()))
	par = [-1 for i in range(n * m)]
	cnt = [0] * (n * m)

	def find(u):
		if u != par[u]:
			par[u] = find(par[u])
		return par[u]

	def merge(u, v):
		if par[v] == -1:
			par[v] = v
		u = find(u)
		v = find(v)
		if u != v:
			(r, c) = (u // m, u % m)
			if r == 0 or r == n - 1 or c == 0 or (c == m - 1):
				par[v] = u
			else:
				par[u] = v
	for i in range(n):
		for j in range(m):
			if grid[i][j] == '.':
				nodeidx = i * m + j
				if par[nodeidx] == -1:
					par[nodeidx] = nodeidx
				for k in range(4):
					x1 = i + dx[k]
					y1 = j + dy[k]
					if x1 < 0 or x1 >= n or y1 < 0 or (y1 >= m) or (grid[x1][y1] == '*'):
						continue
					merge(nodeidx, x1 * m + y1)
	for i in range(n * m):
		if par[i] == -1:
			continue
		par[i] = find(par[i])
		cnt[par[i]] += 1
	x = []
	for i in range(n * m):
		(r, c) = (i // m, i % m)
		if r == 0 or c == 0 or r == n - 1 or (c == m - 1):
			continue
		if cnt[i] > 0:
			x.append([cnt[i], i])
	x.sort()
	ans = 0
	s = set()
	for i in range(len(x) - k1):
		ans += x[i][0]
		s.add(x[i][1])
	print(ans)
	for i in range(n * m):
		if par[i] == -1 or par[i] not in s:
			continue
		r = i // m
		c = i % m
		grid[r][c] = '*'
	for i in range(n):
		print(''.join(grid[i]))
if file:
	if path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	else:
		input = sys.stdin.readline
solve()


dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]

def DFS_border(Edges, visited):
	stack = []
	for i in range(0, n):
		for j in range(0, m):
			if Edges[i][j] == '.' and (i == 0 or j == 0 or i == n - 1 or (j == m - 1)) and (visited[i][j] == 0):
				stack.append([i, j])
				visited[i][j] = 1
				while len(stack) > 0:
					cell = stack[-1]
					stack.pop()
					for k in range(4):
						kx = cell[0] + dx[k]
						ky = cell[1] + dy[k]
						if (kx >= 0 and kx < n) and (ky >= 0 and ky < m):
							if visited[kx][ky] == 0 and Edges[kx][ky] == '.':
								stack.append([kx, ky])
								visited[kx][ky] = 1

def DFS(n, m, Edges):
	L = []
	stack = []
	visited = [[0 for _ in range(m)] for _ in range(n)]
	DFS_border(Edges, visited)
	for i in range(1, n - 1):
		for j in range(1, m - 1):
			cnt = 0
			land_cells = []
			if Edges[i][j] == '.' and visited[i][j] == 0:
				visited[i][j] = 1
				stack.append([i, j])
				land_cells.append([i, j])
				cnt += 1
				while len(stack) > 0:
					cell = stack[-1]
					stack.pop()
					for k in range(4):
						kx = cell[0] + dx[k]
						ky = cell[1] + dy[k]
						if (kx >= 1 and kx < n - 1) and (ky >= 1 and ky < m - 1):
							if visited[kx][ky] == 0 and Edges[kx][ky] == '.':
								stack.append([kx, ky])
								land_cells.append([kx, ky])
								visited[kx][ky] = 1
								cnt += 1
				land_cells.append(cnt)
				L.append(land_cells)
	return L
M = []
(n, m, k) = map(int, input().split())
for i in range(n):
	M.append([j for j in input()])
lakes = DFS(n, m, M)
lakes.sort(key=lambda x: x[-1], reverse=True)
num_water_cells = 0
while len(lakes) != k:
	land_cell = lakes[-1]
	num_water_cells += land_cell[-1]
	lakes.pop()
	for i in range(len(land_cell) - 1):
		mod_cell = land_cell[i]
		M[mod_cell[0]][mod_cell[1]] = '*'
print(num_water_cells)
for i in range(n):
	for j in range(m):
		print(M[i][j], end='')
	print()


def mark(z):
	while z:
		z = z[0]
	return z

def mark2(z):
	while z and type(z) == list:
		z = z[0]
	return z
__debug = None
(n, m, kk) = map(int, input().split())
data = [list(input()) for i in range(n)]
ocean = []
earth = []
work = [[] for i in range(m * n)]
for k in range(m):
	if data[0][k] == '.':
		work[m * 0 + k].append(ocean)
	if data[n - 1][k] == '.':
		work[m * (n - 1) + k].append(ocean)
for i in range(n):
	if data[i][0] == '.':
		work[m * i + 0].append(ocean)
	if data[i][m - 1] == '.':
		work[m * i + m - 1].append(ocean)
for i in range(n):
	for k in range(m):
		if data[i][k] == '.':
			z = mark(work[m * i + k])
			if i and data[i - 1][k] == '.':
				zi = mark(work[m * (i - 1) + k])
				if z is not zi:
					if z is ocean:
						zi.append(z)
					else:
						z.append(zi)
						z = zi
			if k and data[i][k - 1] == '.':
				zk = mark(work[m * i + k - 1])
				if z is not zk:
					if z is ocean:
						zk.append(z)
					else:
						z.append(zk)
isl = {}
no = 1
for i in range(n):
	for k in range(m):
		if data[i][k] == '.':
			if __debug:
				print(i, end=' ')
			if __debug:
				print(k, end=': ')
			z = mark2(work[m * i + k])
			if z:
				isl[z].append((i, k))
				if __debug:
					print(z, end=', old')
			elif z is not ocean:
				z.append(no)
				if __debug:
					print(no, end=', new')
				isl[no] = [(i, k)]
				no += 1
			if __debug:
				print()
if __debug:
	print(isl)
isl_s = list(isl.values())
if __debug:
	print(isl_s)
isl_s.sort(key=len)
if __debug:
	print(isl_s)
delta = len(isl_s) - kk
if __debug:
	print(len(isl_s), end=' ')
if __debug:
	print(kk)
for t in range(delta):
	for (i, k) in isl_s[t]:
		data[i][k] = '*'
print(sum(map(len, isl_s[:delta])))
for i in range(n):
	print(''.join(data[i]))


(n, m, k) = map(int, input().split())
a = []
for i in range(n):
	b = []
	s = input()
	for j in s:
		b.append(j)
	a.append(b)
x = [1, 0, -1, 0]
y = [0, 1, 0, -1]
tp = []
for i in range(n):
	for j in range(m):
		q = []
		if a[i][j] == '.' and 0 < i < n - 1 and (0 < j < m - 1):
			(cn, ch) = (1, 1)
			q.append((i, j))
			a[i][j] = '+'
			while q:
				(x1, y1) = q.pop()
				for o in range(4):
					(i1, j1) = (x1 + x[o], y1 + y[o])
					if a[i1][j1] == '.' and 0 < i1 < n - 1 and (0 < j1 < m - 1):
						cn += 1
						a[i1][j1] = '+'
						q.append((i1, j1))
					elif a[i1][j1] == '.' and (i1 == 0 or i1 == n - 1 or j1 == 0 or (j1 == m - 1)):
						ch = 0
			if ch == 1:
				tp.append((cn, i, j))
tp.sort(key=lambda x: x[0])
ans = 0
for i in range(len(tp) - k):
	(cn, p1, p2) = (tp[i][0], tp[i][1], tp[i][2])
	ans += cn
	q = [(p1, p2)]
	while q:
		(r1, r2) = q.pop()
		a[r1][r2] = '*'
		for j in range(4):
			(i1, j1) = (r1 + x[j], r2 + y[j])
			if a[i1][j1] == '+' and 0 < i1 < n - 1 and (0 < j1 < m - 1):
				a[i1][j1] = '*'
				q.append((i1, j1))
for i in range(n):
	for j in range(m):
		if a[i][j] == '+':
			a[i][j] = '.'
print(ans)
for i in range(n):
	for j in range(m):
		print(a[i][j], end='')
	print()


def getResult():
	(n, m, k) = [int(a) for a in input().split(' ')]
	area = [[c for c in input()] for a in range(n)]
	explr = [[False for i in range(m)] for j in range(n)]

	def getArea(sx, sy):
		if explr[sy][sx] or area[sy][sx] == '*':
			return None
		front = [(sy, sx)]
		explr[sy][sx] = True
		valid = True
		for cur in front:
			move = [(1, 0), (0, 1), (-1, 0), (0, -1)]
			for mv in move:
				next = (cur[0] + mv[0], cur[1] + mv[1])
				if next[0] < 0 or next[0] >= n or next[1] < 0 or (next[1] >= m):
					valid = False
				elif not explr[next[0]][next[1]] and area[next[0]][next[1]] == '.':
					explr[next[0]][next[1]] = True
					front.append(next)
		if valid:
			return front
		return None
	lakes = []
	for y in range(n):
		for x in range(m):
			carea = getArea(x, y)
			if carea != None:
				lakes.append(carea)
	lakes.sort(key=lambda a: len(a), reverse=True)
	count = 0
	while len(lakes) > k:
		clake = lakes.pop()
		count += len(clake)
		for cp in clake:
			area[cp[0]][cp[1]] = '*'
	ret = [''.join(s) for s in area]
	return str(count) + '\n' + '\n'.join(ret)
print(getResult())


import sys
sys.setrecursionlimit(100000)

def find(x, y, tag):
	if mplake[x][y] == tag or mp[x][y] == '*':
		return
	mplake[x][y] = tag
	lakes[tag] += 1
	for i in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
		if 0 <= x + i[0] and x + i[0] < n and (0 <= y + i[1]) and (y + i[1] < m):
			find(x + i[0], y + i[1], tag)

def fill(x, y, tag):
	global cnt
	if mplake[x][y] == tag:
		mplake[x][y] = -1
		mp[x][y] = '*'
		cnt += 1
		for i in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
			if 0 <= x + i[0] and x + i[0] < n and (0 <= y + i[1]) and (y + i[1] < m):
				fill(x + i[0], y + i[1], tag)
(n, m, k) = [int(i) for i in input().split()]
mp = []
mplake = []
for i in range(n):
	mp.append(list(input()))
	mplake.append([-1 for i in range(m)])
start = [(0, 0)]
lakes = [0]
cnt = 0
for i in range(n):
	find(i, 0, 0)
	find(i, m - 1, 0)
for i in range(m):
	find(0, i, 0)
	find(n - 1, i, 0)
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if mp[i][j] == '.' and mplake[i][j] == -1:
			start.append((i, j))
			lakes.append(0)
			find(i, j, len(lakes) - 1)
r = sorted([(lakes[i], start[i]) for i in range(1, len(lakes))])
for i in range(len(r) - k):
	fill(r[i][1][0], r[i][1][1], mplake[r[i][1][0]][r[i][1][1]])
print(cnt)
for i in range(n):
	print(''.join(mp[i]))


import sys
sys.setrecursionlimit(1000000)

class Lake:

	def __init__(self, x, y, cnt):
		self.x = x
		self.y = y
		self.countCell = cnt

	def __lt__(self, other):
		if self.countCell < other.countCell:
			return True
		return False

def visitOcean(i, j):
	if i < 0 or i == n or j < 0 or (j == m) or (map[i][j] == '*') or visited[i][j]:
		return
	visited[i][j] = True
	visitOcean(i + 1, j)
	visitOcean(i - 1, j)
	visitOcean(i, j - 1)
	visitOcean(i, j + 1)

def countCellsInLake(i, j):
	if visited[i][j] or i < 0 or i == n or (j < 0) or (j == m) or (map[i][j] == '*'):
		return 0
	visited[i][j] = True
	return 1 + countCellsInLake(i + 1, j) + countCellsInLake(i - 1, j) + countCellsInLake(i, j + 1) + countCellsInLake(i, j - 1)

def fillLake(i, j):
	if i < 0 or i == n or j < 0 or (j == m) or (map[i][j] == '*') or visited[i][j]:
		return
	map[i] = map[i][:j] + '*' + map[i][j + 1:m]
	visited[i][j] = True
	fillLake(i + 1, j)
	fillLake(i - 1, j)
	fillLake(i, j - 1)
	fillLake(i, j + 1)
(n, m, k) = map(int, input().split())
visited = [[False for i in range(m)] for j in range(n)]
map = []
lakes = []
cellToDel = 0
for i in range(n):
	line = input()
	map.append(line)
for i in range(m):
	if not visited[0][i] and map[0][i] == '.':
		visitOcean(0, i)
	if not visited[n - 1][i] and map[n - 1][i] == '.':
		visitOcean(n - 1, i)
for i in range(n):
	if not visited[i][0] and map[i][0] == '.':
		visitOcean(i, 0)
	if not visited[i][m - 1] and map[i][m - 1] == '.':
		visitOcean(i, m - 1)
for i in range(n):
	for j in range(m):
		if not visited[i][j] and map[i][j] == '.':
			count = countCellsInLake(i, j)
			lakes.append(Lake(i, j, count))
lakes.sort()
visited = [[False for i in range(m)] for j in range(n)]
for i in range(len(lakes) - k):
	cellToDel += lakes[i].countCell
	fillLake(lakes[i].x, lakes[i].y)
print(cellToDel)
for i in range(n):
	print(map[i])


def DFS_Cover(i, j, n, m, matrix):
	s = []
	s.append([i, j])
	matrix[i][j] = '*'
	d_x = [0, -1, 0, 1]
	d_y = [-1, 0, 1, 0]
	while len(s) != 0:
		u = s[-1]
		u_i = u[0]
		u_j = u[1]
		s.pop()
		for i in range(4):
			v_i = u_i + d_x[i]
			v_j = u_j + d_y[i]
			if valid(v_i, v_j, n, m) and matrix[v_i][v_j] == '.':
				matrix[v_i][v_j] = '*'
				s.append([v_i, v_j])

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

def DFS(i, j, n, m, matrix):
	s = []
	visited[i][j] = True
	s.append([i, j])
	d_x = [0, -1, 0, 1]
	d_y = [-1, 0, 1, 0]
	area = 1
	while len(s) != 0:
		u = s[-1]
		u_i = u[0]
		u_j = u[1]
		s.pop()
		for i in range(4):
			v_i = u_i + d_x[i]
			v_j = u_j + d_y[i]
			if valid(v_i, v_j, n, m) and matrix[v_i][v_j] == '.' and (visited[v_i][v_j] == False):
				visited[v_i][v_j] = True
				area += 1
				s.append([v_i, v_j])
	return area
(n, m, k) = map(int, input().split())
matrix = []
for i in range(n):
	matrix.append(list(input()))
visited = [[False for i in range(m)] for j in range(n)]
for i in range(n):
	for j in range(m):
		if (i == 0 or i == n - 1 or j == 0 or (j == m - 1)) and matrix[i][j] == '.':
			DFS(i, j, n, m, matrix)
lake_point_list = []
for i in range(n):
	for j in range(m):
		if matrix[i][j] == '.' and visited[i][j] == False:
			area = DFS(i, j, n, m, matrix)
			lake_point_list.append([i, j, area])
del_lake = len(lake_point_list) - k
lake_point_list.sort(key=lambda x: x[2])
sum_cover = 0
for i in range(del_lake):
	sum_cover += lake_point_list[i][2]
	DFS_Cover(lake_point_list[i][0], lake_point_list[i][1], n, m, matrix)
print(sum_cover)
for line in matrix:
	print(*line, sep='')


class Point:

	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y

class Lake:

	def __init__(self, points=[], count=0):
		self.points = points
		self.count = count

	def __lt__(self, other):
		if self.count < other.count:
			return True
		return False
(n, m, k) = map(int, input().split())
land = []
for _ in range(n):
	land.append(input())
lakes = []
visited = [[False for xx in range(m)] for yy in range(n)]

def isValid(v, matrix):
	return v.x >= 0 and v.x < n and (v.y >= 0) and (v.y < m) and (matrix[v.x][v.y] == '.')

def onBorder(v):
	return v.x == 0 or v.x == n - 1 or v.y == 0 or (v.y == m - 1)

def DFS(start):
	dx = [-1, 1, 0, 0]
	dy = [0, 0, -1, 1]
	points = [Point(start.x, start.y)]
	stack = []
	stack.append(start)
	visited[start.x][start.y] = True
	isOcean = False
	while len(stack) != 0:
		u = stack.pop()
		if onBorder(u):
			isOcean = True
		for z in range(4):
			v = Point(u.x + dx[z], u.y + dy[z])
			if isValid(v, land) and (not visited[v.x][v.y]):
				visited[v.x][v.y] = True
				points.append(v)
				stack.append(v)
	if not isOcean:
		lake = Lake(points, len(points))
		lakes.append(lake)
for i in range(n):
	for j in range(m):
		if land[i][j] == '.' and (not visited[i][j]):
			DFS(Point(i, j))
lakes.sort()
ncells = 0
for i in range(len(lakes) - k):
	ncells += lakes[i].count
	for j in range(lakes[i].count):
		(ux, uy) = (lakes[i].points[j].x, lakes[i].points[j].y)
		land[ux] = land[ux][:uy] + '*' + land[ux][uy + 1:]
print(ncells)
for z in range(n):
	print(land[z])


def isBorder(point, n, m):
	if point[0] in (0, n - 1) or point[1] in (0, m - 1):
		return True
	return False

def DFS(src):
	stack = []
	stack.clear()
	lake = []
	lake.clear()
	lake.append(src)
	visited[src[0]][src[1]] = True
	stack.append(src)
	dx = [0, 0, 1, -1]
	dy = [1, -1, 0, 0]
	reject = False
	while len(stack) > 0:
		u = stack[-1]
		stack.pop()
		if 0 < u[0] < n - 1 and 0 < u[1] < m - 1:
			for i in range(4):
				if matrix[u[0] + dx[i]][u[1] + dy[i]] == '.' and visited[u[0] + dx[i]][u[1] + dy[i]] == False:
					lake.append([u[0] + dx[i], u[1] + dy[i]])
					visited[u[0] + dx[i]][u[1] + dy[i]] = True
					stack.append([u[0] + dx[i], u[1] + dy[i]])
					if isBorder([u[0] + dx[i], u[1] + dy[i]], n, m) == True:
						reject = True
	if reject == False:
		group_of_lake.append(lake)
(n, m, k) = map(int, input().split())
matrix = []
for i in range(n):
	matrix.append(list(input()))
V = n * m
visited = [[False for i in range(m)] for j in range(n)]
group_of_lake = []
for p in range(n):
	for q in range(m):
		if matrix[p][q] == '.' and visited[p][q] == False and (isBorder([p, q], n, m) == False):
			DFS([p, q])
final_result = sorted(group_of_lake, key=len)
print(sum([len(z) for z in final_result[:len(group_of_lake) - k]]))
for lk in final_result[:len(group_of_lake) - k]:
	for pt in lk:
		matrix[pt[0]][pt[1]] = '*'
for p in range(n):
	print(''.join(matrix[p]))


class pair:
	x = 0
	y = 0

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

def isValid(u, maze):
	return u.x >= 0 and u.x < n and (u.y >= 0) and (u.y < m) and (maze[u.x][u.y] == '.')

def isShareBorderOcean(u):
	return u.x == 0 or u.x == n - 1 or u.y == 0 or (u.y == m - 1)

def DFS(maze, points):
	dh = [0, -1, 0, 1]
	dc = [1, 0, -1, 0]
	visited = [[False for xx in range(m)] for yy in range(n)]
	lakes = []
	for i in range(len(points)):
		stack = []
		start = points[i]
		if visited[start.x][start.y] == False:
			visited[start.x][start.y] = True
			stack.append(start)
			points_in_lake = []
			points_in_lake.append(start)
			if isShareBorderOcean(start):
				number_of_points = 2501
			else:
				number_of_points = 1
			while len(stack) > 0:
				u = stack[-1]
				stack.pop()
				for k in range(4):
					v = pair(u.x + dh[k], u.y + dc[k])
					if isValid(v, maze) and visited[v.x][v.y] == False:
						visited[v.x][v.y] = True
						points_in_lake.append(v)
						stack.append(v)
						if isShareBorderOcean(v):
							number_of_points += 2500
						else:
							number_of_points += 1
			if number_of_points < 2500:
				lakes.append([number_of_points, points_in_lake])
	return lakes
(n, m, k) = map(int, input().split())
maze = []
for _ in range(n):
	maze.append(input())
points = []
for i in range(n):
	for j in range(m):
		if maze[i][j] == '.':
			points.append(pair(i, j))
lakes = DFS(maze, points)
lakes.sort(key=lambda x: x[0])
ans = 0
for i in range(len(lakes) - k):
	number_of_points = lakes[i][0]
	ans += number_of_points
	for j in range(number_of_points):
		x = lakes[i][1][j].x
		y = lakes[i][1][j].y
		tmp_str = list(maze[x])
		tmp_str[y] = '*'
		maze[x] = ''.join(tmp_str)
print(ans)
for itemMaze in maze:
	print(itemMaze)


import sys
sys.setrecursionlimit(100000)
(n, m, k) = map(int, input().split())
graph = []
delX = [-1, 0, 0, 1]
delY = [0, -1, 1, 0]
lakes = []
for i in range(n):
	x = input()
	temp = []
	temp.extend(x)
	graph.append(temp)

def DFS(x, y, mark, n, m):
	graph[x][y] = mark
	for i in range(4):
		if x + delX[i] >= 0 and x + delX[i] < n and (y + delY[i] >= 0) and (y + delY[i] < m) and (graph[x + delX[i]][y + delY[i]] == '.'):
			DFS(x + delX[i], y + delY[i], mark, n, m)

def lakeSize(i, j, mark):
	count = 0
	for i in range(n):
		for j in range(m):
			if graph[i][j] == mark:
				count += 1
	return count

def checkLake(n, m, mark):
	for i in range(m):
		if graph[0][i] == mark:
			return False
	for i in range(n):
		if graph[i][0] == mark:
			return False
	for i in range(n):
		if graph[i][m - 1] == mark:
			return False
	for i in range(m):
		if graph[n - 1][i] == mark:
			return False
	return True

def fillLake(x, y, mark):
	graph[x][y] = '*'
	for i in range(4):
		if x + delX[i] >= 0 and x + delX[i] < n and (y + delY[i] >= 0) and (y + delY[i] < m) and (graph[x + delX[i]][y + delY[i]] == mark):
			fillLake(x + delX[i], y + delY[i], mark)
mark = 1
for i in range(n):
	for j in range(m):
		if graph[i][j] == '.':
			pos_i = i
			pos_j = j
			DFS(i, j, str(mark), n, m)
			_lakeSize = lakeSize(i, j, str(mark))
			lake = [pos_i, pos_j, _lakeSize, str(mark)]
			if checkLake(n, m, str(mark)):
				lakes.append(lake)
			mark += 1
lakes.sort(key=lambda x: x[2])
count = 0
while len(lakes) > k:
	fillLake(lakes[0][0], lakes[0][1], lakes[0][3])
	count += lakes[0][2]
	lakes.pop(0)
print(count)
for i in range(n):
	for j in range(m):
		if graph[i][j] != '*':
			graph[i][j] = '.'
for i in range(n):
	for j in range(m):
		print(graph[i][j], end='')
	print()


import sys

def dfs(i, j):
	nonlocal used, ans
	used[i][j] = True
	ans.append((i, j))
	if i - 1 >= 0 and j >= 0 and (not used[i - 1][j]):
		dfs(i - 1, j)
	if i >= 0 and j + 1 <= m - 1 and (not used[i][j + 1]):
		dfs(i, j + 1)
	if i + 1 <= n - 1 and j <= m - 1 and (not used[i + 1][j]):
		dfs(i + 1, j)
	if i <= n - 1 and j - 1 >= 0 and (not used[i][j - 1]):
		dfs(i, j - 1)
sys.setrecursionlimit(1000000)
(n, m, k) = map(int, input().split())
used = [[True for i in range(m)] for j in range(n)]
hole = [[True for i in range(m)] for j in range(n)]
for i in range(n):
	h = input()
	for j in range(m):
		if h[j] == '.':
			used[i][j] = False
			hole[i][j] = False
ansi = []
for i in range(n):
	for j in range(m):
		ans = []
		if not used[i][j]:
			dfs(i, j)
		if len(ans):
			f = False
			for elem in ans:
				if not elem[0] or not elem[1] or elem[0] == n - 1 or (elem[1] == m - 1):
					f = True
			if not f:
				ansl = [len(ans)] + ans
				ansi.append(ansl)
ansi.sort()
s = 0
for i in range(len(ansi) - k):
	s += ansi[i][0]
	for j in range(1, ansi[i][0] + 1):
		hole[ansi[i][j][0]][ansi[i][j][1]] = True
print(s)
for i in range(n):
	op = ''
	for j in range(m):
		if hole[i][j]:
			op += '*'
		else:
			op += '.'
	print(op)


import sys
import queue
sys.setrecursionlimit(100000)

def dfs(s):
	visited[s] = True
	for v in graph[s]:
		if not visited[v]:
			dfs(v)
(n, m, k) = map(int, input().split())
grid = [[] for i in range(n)]
visited = [[False] * m for i in range(n)]
directions = [[0, 1], [1, 0], [-1, 0], [0, -1]]
for i in range(n):
	a = list(str(input()))
	grid[i].extend(a)

def inside(row, col):
	if (0 <= row and row < n) and (0 <= col and col < m):
		return True
	return False

def inBorder(row, col):
	if row == 0 or row == n - 1 or col == 0 or (col == m - 1):
		return True
	return False
lakes = []
for row in range(n):
	for col in range(m):
		if not visited[row][col] and grid[row][col] == '.':
			q = queue.Queue()
			q.put([row, col])
			size = 1
			isSelected = True
			tmp = []
			visited[row][col] = True
			while not q.empty():
				p = q.get()
				tmp.append((p[0], p[1]))
				if inBorder(p[0], p[1]):
					isSelected = False
				for dir in directions:
					new_row = p[0] + dir[0]
					new_col = p[1] + dir[1]
					if inside(new_row, new_col) and (not visited[new_row][new_col]) and (grid[new_row][new_col] == '.'):
						q.put([new_row, new_col])
						visited[new_row][new_col] = True
						size += 1
			if isSelected:
				lakes.append(tmp)
res = 0
lakes.sort(key=lambda lake: len(lake))
for i in range(len(lakes) - k):
	res += len(lakes[i])
	for (r, c) in lakes[i]:
		grid[r][c] = '*'
print(res)
for i in range(n):
	print(''.join(grid[i]))


from collections import defaultdict, deque, Counter
from sys import stdin, stdout
from heapq import heappush, heappop
import math
import io
import os
import math
import bisect

def isPrime(x):
	for i in range(2, x):
		if i * i > x:
			break
		if x % i == 0:
			return False
	return True

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

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

def digits(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def ceil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def mapin():
	return map(int, input().split())
visited = [[0 for i in range(101)] for j in range(101)]
adj = [[0 for i in range(101)] for j in range(101)]
n = 0
m = 0
final = []

def DFS(s):
	fl = True
	stack = []
	temp = []
	stack.append(tuple(s))
	visited[s[0]][s[1]] = 1
	while len(stack):
		s = stack[-1]
		stack.pop()
		if s[0] == n - 1 or s[1] == m - 1 or s[0] == 0 or (s[1] == 0):
			fl = False
		temp.append(s)
		sy = list(s).copy()
		tx = list(s).copy()
		ty = list(s).copy()
		sx = list(s).copy()
		sx[0] += 1
		sy[1] += 1
		tx[0] -= 1
		ty[1] -= 1
		if sy[1] < m and adj[sy[0]][sy[1]] == 1 and (visited[sy[0]][sy[1]] == 0):
			visited[sy[0]][sy[1]] = 1
			stack.append(tuple(sy))
		if ty[1] >= 0 and adj[ty[0]][ty[1]] == 1 and (visited[ty[0]][ty[1]] == 0):
			visited[ty[0]][ty[1]] = 1
			stack.append(tuple(ty))
		if sx[0] < n and adj[sx[0]][sx[1]] == 1 and (visited[sx[0]][sx[1]] == 0):
			visited[sx[0]][sx[1]] = 1
			stack.append(tuple(sx))
		if tx[0] >= 0 and adj[tx[0]][tx[1]] == 1 and (visited[tx[0]][tx[1]] == 0):
			visited[tx[0]][tx[1]] = 1
			stack.append(tuple(tx))
	if fl:
		final.append(list(set(temp)))
(n, m, k) = mapin()
d = []
for i in range(n):
	l = list(input())
	for j in range(m):
		if l[j] == '.':
			adj[i][j] = 1
		else:
			adj[i][j] = 0
for i in range(n):
	for j in range(m):
		if adj[i][j] == 1 and visited[i][j] == 0:
			DFS([i, j])
final.sort(key=len)
ans = 0
for i in range(len(final) - k):
	ans += len(final[i])
	for j in final[i]:
		adj[j[0]][j[1]] = 0
print(ans)
for i in range(n):
	for j in range(m):
		if adj[i][j] == 0:
			print('*', end='')
		else:
			print('.', end='')
	print('')


import sys
sys.setrecursionlimit(10 ** 6)

def lakes(n, m, matrix, k):

	def checkBorder(u, v):
		if u >= 0 and u < m and (v >= 0) and (v < n):
			return True
		return False
	visited = [[False for _ in range(m)] for _ in range(n)]
	size = []
	startt = []
	dx = [-1, 1, 0, 0]
	dy = [0, 0, 1, -1]
	is_open = False
	s = 0

	def dfs(start):
		nonlocal is_open
		nonlocal s
		visited[start[0]][start[1]] = True
		s += 1
		if start[0] == 0 or start[0] == n - 1 or start[1] == 0 or (start[1] == m - 1):
			is_open = True
		for k in range(4):
			(y, x) = (start[0] + dy[k], start[1] + dx[k])
			if checkBorder(x, y) and visited[y][x] == False and (matrix[y][x] == '.'):
				dfs((y, x))

	def dapho(s):
		nonlocal matrix
		nonlocal r
		matrix[s[0]][s[1]] = '*'
		r += 1
		for k in range(4):
			(y, x) = (s[0] + dy[k], s[1] + dx[k])
			if checkBorder(x, y) and matrix[y][x] == '.':
				dapho((y, x))
	lakes = 0
	for v in range(n):
		for u in range(m):
			if matrix[v][u] == '.' and visited[v][u] == False:
				dfs((v, u))
				if is_open:
					is_open = False
				else:
					lakes += 1
					startt.append((v, u))
					size.append(s)
				s = 0
	size_start = list(zip(size, startt))
	a = sorted(size_start, key=lambda x: x[0])
	if lakes == k:
		print(0)
		for i in range(n):
			print(''.join(matrix[i]))
	else:
		r = 0
		for i in range(lakes - k):
			lake = a[i]
			start = lake[1]
			dapho(start)
		print(r)
		for i in range(n):
			print(''.join(matrix[i]))
(n, m, k) = map(int, input().strip().split(' '))
matrix = []
for _ in range(n):
	matrix.append(list(input().strip()))
lakes(n, m, matrix, k)


(n, m, k) = map(int, input().split())
arr = []
for i in range(n):
	s = list(input())
	arr.append(s)

def dfs(arr, x, y, visited, id):
	st = []
	st.append((x, y))
	visited[x][y] = id
	size = 1
	neighbors = [(0, 1), (0, -1), (-1, 0), (1, 0)]
	isOcean = False
	while len(st) != 0:
		(x, y) = st.pop()
		if x == 0 or x == len(arr) - 1 or y == 0 or (y == len(arr[0]) - 1):
			isOcean = True
		for (di, dj) in neighbors:
			i = di + x
			j = dj + y
			if 0 <= i < len(arr) and 0 <= j < len(arr[0]) and (visited[i][j] == -1) and (arr[i][j] == '.'):
				visited[i][j] = id
				st.append((i, j))
				size += 1
	return 0 if isOcean == True else size
visited = [[-1] * m for i in range(n)]
lakes = []
id = 0
for i in range(n):
	for j in range(m):
		if arr[i][j] == '.' and visited[i][j] == -1:
			id += 1
			size = dfs(arr, i, j, visited, id)
			if size > 0:
				lakes.append((size, id))
lakes.sort(key=lambda x: x[0])
toBeFilled = [False] * (id + 1)
minNumberOfCells = 0
for i in range(0, len(lakes) - k, 1):
	lake = lakes[i]
	minNumberOfCells += lake[0]
	toBeFilled[lake[1]] = True
print(minNumberOfCells)
for i in range(n):
	for j in range(m):
		print('*' if visited[i][j] == -1 or toBeFilled[visited[i][j]] else '.', end='')
	print()


import sys
sys.setrecursionlimit(100000)
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
cnt = 0
a = [['' for _ in range(55)] for _ in range(55)]
tmp = [['' for _ in range(55)] for _ in range(55)]

def DFS(x, y):
	global cnt
	a[x][y] = '*'
	cnt += 1
	for i in range(4):
		xx = x + dx[i]
		yy = y + dy[i]
		if xx >= 0 and xx < n and (yy >= 0) and (yy < m) and (a[xx][yy] == '.'):
			DFS(xx, yy)
(n, m, k) = map(int, input().strip().split())
save = []
for i in range(n):
	s = input().strip()
	for j in range(m):
		a[i][j] = s[j]
for i in range(n):
	for j in range(m):
		tmp[i][j] = a[i][j]
for i in range(n):
	for j in range(m):
		if (i == 0 or i == n - 1 or j == 0 or (j == m - 1)) and a[i][j] == '.':
			DFS(i, j)
for i in range(n):
	for j in range(m):
		if a[i][j] == '.':
			cnt = 0
			DFS(i, j)
			save.append((cnt, i, j))
save.sort()
for i in range(n):
	for j in range(m):
		a[i][j] = tmp[i][j]
sz = len(save)
res = 0
for i in range(sz - k):
	(square, x, y) = save[i]
	res += square
	DFS(x, y)
print(res)
for i in range(n):
	for j in range(m):
		print(a[i][j], end='')
	print()


def make_set(a):
	parent[a] = a
	size[a] = 1

def find_set(a):
	if a == parent[a]:
		return a
	else:
		parent[a] = find_set(parent[a])
	return parent[a]

def union_sets(a, b):
	a = find_set(a)
	b = find_set(b)
	if a != b:
		if size[a] < size[b]:
			(a, b) = (b, a)
		parent[b] = a
		size[a] += size[b]

def is_valid(a):
	i = a[0]
	j = a[1]
	if 0 <= i <= n - 1 and 0 <= j <= m - 1:
		if A[i][j] == '.':
			if (i, j) not in parent:
				return False
			else:
				return True
		else:
			return True
	else:
		return True
parent = dict()
size = dict()
(n, m, ks) = map(int, input().split())
A = [0] * n
for i in range(n):
	A[i] = list(input())
for i in range(n):
	for j in range(m):
		if i != 0 and j != 0 and (i != n - 1) and (j != m - 1):
			if A[i][j] == '.':
				if is_valid((i - 1, j)) and is_valid((i, j - 1)):
					make_set((i, j))
					if (i - 1, j) in parent:
						union_sets((i - 1, j), (i, j))
					if (i, j - 1) in parent:
						union_sets((i, j - 1), (i, j))
				elif A[i][j] == '.':
					dels = []
					if (i - 1, j) in parent:
						a1 = find_set((i - 1, j))
						for k in parent:
							if find_set(k) == a1:
								dels.append(k)
					for f in dels:
						parent.pop(f)
					dels = []
					if (i, j - 1) in parent:
						a1 = find_set((i, j - 1))
						for k in parent:
							if find_set(k) == a1:
								dels.append(k)
					for f in dels:
						parent.pop(f)
		elif A[i][j] == '.':
			dels = []
			if (i - 1, j) in parent:
				a1 = find_set((i - 1, j))
				for k in parent:
					if find_set(k) == a1:
						dels.append(k)
			for f in dels:
				parent.pop(f)
			dels = []
			if (i, j - 1) in parent:
				a1 = find_set((i, j - 1))
				for k in parent:
					if find_set(k) == a1:
						dels.append(k)
			for f in dels:
				parent.pop(f)
ans = 0
ass = 0
ans2 = []
for j in parent:
	a1 = find_set(j)
	if a1 not in ans2:
		ans2.append(a1)
		ans += 1
for j in range(ans - ks):
	mins = float('infinity')
	numer = 0
	new_sizes = dict()
	for t in parent:
		a1 = find_set(t)
		if a1 in new_sizes:
			new_sizes[a1] += 1
		else:
			new_sizes[a1] = 1
	for t in new_sizes:
		if new_sizes[t] < mins:
			mins = new_sizes[t]
			numer = t
	ass += mins
	dels = []
	for t in parent:
		if find_set(t) == numer:
			dels.append(t)
			A[t[0]][t[1]] = '*'
	for t in dels:
		parent.pop(t)
print(ass)
for j in range(n):
	print(''.join(A[j]))


def is_border(cell, n, m):
	if cell[0] == 0 or cell[0] == n - 1:
		return True
	if cell[1] == 0 or cell[1] == m - 1:
		return True

def solve():
	(n, m, k) = map(int, input().split())
	berland = [list(input().strip()) for _ in range(n)]
	edges = {(i, j): list() for i in range(n) for j in range(m)}
	visited = {(i, j): False for i in range(n) for j in range(m)}
	offsets = [(-1, 0), (0, 1), (1, 0), (0, -1)]
	for i in range(n):
		for j in range(m):
			if berland[i][j] == '.':
				for offset in offsets:
					near_cell = (i + offset[0], j + offset[1])
					if 0 <= near_cell[0] < n and 0 <= near_cell[1] < m and (berland[near_cell[0]][near_cell[1]] == '.'):
						edges[i, j].append(near_cell)
	lakes = list()
	for i in range(n):
		for j in range(m):
			if berland[i][j] == '.' and (not visited[i, j]):
				lake = []
				stack = list()
				stack.append((i, j))
				is_lake = True
				while stack:
					cur_cell = stack.pop()
					visited[cur_cell] = True
					lake.append(cur_cell)
					if is_border(cur_cell, n, m):
						is_lake = False
					for near_cell in edges[cur_cell]:
						if not visited[near_cell]:
							visited[near_cell] = True
							stack.append(near_cell)
				if is_lake:
					lakes.append(lake)
	lakes = sorted(lakes, key=lambda lake: -len(lake))
	transform_cells = 0
	while len(lakes) > k:
		lake = lakes.pop()
		for cell in lake:
			berland[cell[0]][cell[1]] = '*'
			transform_cells += 1
	print(transform_cells)
	for i in range(n):
		for j in range(m):
			print(berland[i][j], end='')
		print()
solve()


import math, sys, bisect, heapq, os
from collections import defaultdict, Counter, deque
from itertools import groupby, accumulate
from functools import lru_cache
int1 = lambda x: int(x) - 1

def input():
	return sys.stdin.readline().rstrip('\r\n')
aj = lambda : list(map(int, input().split()))

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def Y(c):
	print(['NO', 'YES'][c])

def y(c):
	print(['no', 'yes'][c])

def Yy(c):
	print(['No', 'Yes'][c])
import copy

def solve():
	d1 = [0, 0, 1, -1]
	d2 = [1, -1, 0, 0]

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

	def ch2(x, y):
		if mat2[x][y] == '*':
			return False
		return True

	def dfs1(i, j):
		st = deque()
		st.append((i, j))
		while st:
			(x, y) = st.pop()
			mat2[x][y] = '*'
			for (i, j) in zip(d1, d2):
				xx = x + i
				yy = y + j
				if ch1(xx, yy):
					if ch2(xx, yy):
						st.append((xx, yy))
					vis[xx][yy] = True

	def dfs(i, j):
		st = deque()
		st.append((i, j))
		s = set()
		while st:
			(x, y) = st.pop()
			s.add((x, y))
			for (i, j) in zip(d1, d2):
				xx = x + i
				yy = y + j
				if ch1(xx, yy):
					if ch2(xx, yy):
						st.append((xx, yy))
					vis[xx][yy] = True
		return s
	(n, m, k) = aj()
	mat = []
	for i in range(n):
		B = [*input()]
		mat.append(B)
	vis = [[False] * m for i in range(n)]
	Ans = []
	mat2 = copy.deepcopy(mat)
	for i in range(n):
		for j in range(m):
			if i == 0 or j == 0 or i == n - 1 or (j == m - 1):
				if not vis[i][j] and ch2(i, j):
					vis[i][j] = True
					dfs1(i, j)
	G = defaultdict(list)
	count = 0
	for i in range(n):
		for j in range(m):
			if not vis[i][j] and ch2(i, j):
				vis[i][j] = True
				s = dfs(i, j)
				G[len(s)].append(s)
				count += 1
	v = sorted(G.keys(), reverse=True)
	c = 0
	while count > k:
		count -= 1
		while not G[v[-1]]:
			v.pop()
		x = G[v[-1]].pop()
		for (i, j) in x:
			mat[i][j] = '*'
			c += 1
	print(c)
	for i in mat:
		print(''.join(i))
try:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
except:
	pass
solve()


def checkF(n, m, k, g, xs, ys):
	visit = [[0 for j in range(m)] for i in range(n)]
	path = [[-1 for j in range(m)] for i in range(n)]
	dx = [1, 0, -1, 0]
	dy = [0, -1, 0, 1]
	st = []
	stt = []
	rst = []
	res = 0
	stt.append([xs, ys])
	visit[xs][ys] = 1
	while len(stt) > 0:
		u = stt.pop()
		x = u[0]
		y = u[1]
		for i in range(4):
			nx = x + dx[i]
			ny = y + dy[i]
			if 0 <= nx < n and 0 <= ny < m and (visit[nx][ny] != 1):
				visit[nx][ny] = 1
				t = g[nx][ny]
				if t == '.':
					st.append([nx, ny])
					cc = DFS(st, stt, visit, g, n, m, dx, dy)
					if cc != -1:
						rst.append([cc, nx, ny])
				else:
					stt.append([nx, ny])
	rst.sort()
	su = 0
	st1 = []
	while len(rst) > k:
		u1 = rst.pop(0)
		su += u1[0]
		x = u1[1]
		y = u1[2]
		st1.append([x, y])
		t = g[x]
		t = t[:y] + '*' + t[y + 1:]
		g[x] = t
		while len(st1) > 0:
			u = st1.pop()
			x = u[0]
			y = u[1]
			for i in range(4):
				nx = x + dx[i]
				ny = y + dy[i]
				if 0 <= nx < n and 0 <= ny < m and (g[nx][ny] == '.'):
					t = g[nx]
					t = t[:ny] + '*' + t[ny + 1:]
					g[nx] = t
					st1.append([nx, ny])
	print(su)
	for i in range(n):
		print(g[i])

def DFS(st, stt, visit, g, n, m, dx, dy):
	cc = 0
	f = 0
	while len(st) > 0:
		u = st.pop()
		cc += 1
		x = u[0]
		y = u[1]
		if x == 0 or x == n - 1 or y == 0 or (y == m - 1):
			f = 1
		for i in range(4):
			nx = x + dx[i]
			ny = y + dy[i]
			if 0 <= nx < n and 0 <= ny < m and (visit[nx][ny] != 1):
				visit[nx][ny] = 1
				t = g[nx][ny]
				if t == '.':
					st.append([nx, ny])
				else:
					stt.append([nx, ny])
	return cc if f == 0 else -1
(n, m, k) = map(int, input().split())
g = []
xs = -1
ys = -1
for i in range(n):
	t = input()
	if '*' in t:
		ys = t.index('*')
		xs = i
	g.append(t)
checkF(n, m, k, g, xs, ys)


import sys
import copy
sys.setrecursionlimit(10000000)
(h, w, k) = list(map(int, input().split()))
ground = [list(input()) for j in range(h)]
ground2 = copy.deepcopy(ground)
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]
cnt = 0

def dfs(x, y, count):
	ground[y][x] = str(count)
	for k in range(4):
		if 0 <= x + dx[k] < w and 0 <= y + dy[k] < h:
			if ground[y + dy[k]][x + dx[k]] == '.':
				dfs(x + dx[k], y + dy[k], count)
for j in range(h):
	for i in range(w):
		if ground[j][i] == '.':
			dfs(i, j, cnt)
			cnt += 1
arr = [[0, i] for i in range(cnt)]
for num in range(cnt):
	f = True
	for j in range(h):
		for i in range(w):
			if ground[j][i] == str(num):
				arr[num][0] += 1
				if i == 0 or i == w - 1 or j == 0 or (j == h - 1):
					f = False
					arr[num][0] += 10 ** 10
					break
			if not f:
				break
		if not f:
			break
arr.sort()
for j in range(len(arr)):
	if arr[j][0] > 10 ** 10:
		cnt -= 1
num_lake = cnt
ans = 0
if cnt == k:
	print(ans)
	for j in range(h):
		print(''.join(ground2[j][:]))
	return
for num in range(cnt):
	groundbef = ground[:][:]
	f = True
	cells = 0
	for j in range(h):
		for i in range(w):
			if ground[j][i] == str(arr[num][1]):
				if i < 0 or i > w - 1 or j < 0 or (j > h - 1):
					f = False
					print('F', i, j)
					break
				ground[j][i] = '*'
				cells += 1
	if not f:
		ground = groundbef[:][:]
		num_lake -= 1
	else:
		num_lake -= 1
		ans += cells
	if num_lake == k:
		break
for j in range(h):
	for i in range(w):
		if ground[j][i] == '*':
			continue
		else:
			ground[j][i] = '.'
print(ans)
for j in range(h):
	print(''.join(ground[j][:]))


corr = lambda x, y: 0 <= x < n and 0 <= y < m and (a[x][y] == '.')
ocean = lambda x, y: x in (0, n - 1) or y in (0, m - 1)
D = ((0, 1), (0, -1), (1, 0), (-1, 0))
from sys import setrecursionlimit
setrecursionlimit(10 ** 5)

def dfs(x, y):
	global size, flag
	was[x][y] = clr
	size += 1
	if ocean(x, y):
		flag = True
	for (dx, dy) in D:
		(nx, ny) = (x + dx, y + dy)
		if corr(nx, ny) and (not was[nx][ny]):
			dfs(nx, ny)
read = lambda : map(int, input().split())
(n, m, k) = read()
a = [input() for i in range(n)]
s = []
was = [[0] * m for i in range(n)]
clr = 1
for i in range(n):
	for j in range(m):
		if not was[i][j] and a[i][j] == '.':
			flag = False
			size = 0
			dfs(i, j)
			if not flag:
				s.append((size, clr))
			clr += 1
s.sort()
ans = 0
color = set()
for i in range(len(s) - k):
	ans += s[i][0]
	color.add(s[i][1])
b = [list(a[i]) for i in range(n)]
for i in range(n):
	for j in range(m):
		if was[i][j] in color:
			b[i][j] = '*'
print(ans)
[print(''.join(i)) for i in b]


from __future__ import print_function
import sys
from collections import *
from heapq import *
from functools import *
import re
from itertools import *
INF = float('inf')
NINF = float('-inf')
try:
	input = raw_input
except:
	pass

def read_string():
	return input()

def read_string_line():
	return [x for x in input().split(' ')]

def read_int_line():
	return [int(x) for x in input().split(' ')]

def read_int():
	return int(input())
(n, m, k) = read_int_line()
ocean = n * m
grid = []
p = [-1] * (n * m + 1)

def find(x):
	if p[x] < 0:
		return x
	p[x] = find(p[x])
	return p[x]

def union(x, y):
	(x, y) = (find(x), find(y))
	if x == y:
		return
	if x == ocean:
		p[x] += p[y]
		p[y] = x
	else:
		p[y] += p[x]
		p[x] = y
for _ in range(n):
	grid.append(list(read_string()))
for y in range(0, n):
	for x in range(0, m):
		if grid[y][x] == '*':
			continue
		if y == 0 or y + 1 == n or x == 0 or (x + 1 == m):
			union(y * m + x, ocean)
		if x + 1 < m and grid[y][x + 1] == '.':
			union(y * m + x, y * m + x + 1)
		if y + 1 < n and grid[y + 1][x] == '.':
			union(y * m + x, (y + 1) * m + x)

def iswater(index):
	return grid[index // m][index % m] == '.'
roots = [x for x in range(ocean) if iswater(x) and find(x) == x]
roots.sort(key=lambda x: p[x], reverse=True)
roots = set(roots[0:len(roots) - k])
if roots:
	for y in range(n):
		for x in range(m):
			if grid[y][x] == '.' and find(y * m + x) in roots:
				grid[y][x] = '*'
ans = sum([-p[x] for x in roots])
print('%d' % ans)
for row in grid:
	print(''.join(row))


class Cell:

	def __init__(self, row, clm):
		self.row = row
		self.clm = clm
dr = [0, 0, -1, 1]
dc = [1, -1, 0, 0]
Berland = []
visited = [[False] * 51 for i in range(51)]
Lakes = []

def DFS(s):
	stack = [s]
	visited[s.row][s.clm] = True
	Ocean = False
	lake = []
	while len(stack):
		u = stack.pop()
		lake.append(u)
		if u.row == 0 or u.row == n - 1 or u.clm == 0 or (u.clm == m - 1):
			Ocean = True
		for i in range(4):
			v = Cell(u.row + dr[i], u.clm + dc[i])
			if v.row >= 0 and v.row < n and (v.clm >= 0) and (v.clm < m) and (Berland[v.row][v.clm] == '.') and (not visited[v.row][v.clm]):
				visited[v.row][v.clm] = True
				stack.append(v)
	if not Ocean:
		Lakes.append(lake)
(n, m, k) = map(int, input().split())
for i in range(n):
	Berland.append(list(input()))
for i in range(n):
	for j in range(m):
		if not visited[i][j] and Berland[i][j] == '.':
			DFS(Cell(i, j))
Lakes.sort(key=lambda lake: len(lake))
change = len(Lakes) - k
cells_change = 0
for i in range(change):
	cells_change += len(Lakes[i])
	for s in Lakes[i]:
		Berland[s.row][s.clm] = '*'
print(cells_change)
for i in range(n):
	print(*Berland[i], sep='')


import threading
import sys

def inp():
	return map(int, input().split(' '))
dx = [0, -1, 0, 1]
dy = [-1, 0, 1, 0]
global cnt

class node:
	count = 0
	x = 0
	y = 0

	def __init__(self, count, x, y):
		self.x = x
		self.y = y
		self.count = count

def checkCell(s, x, y):
	return x >= 0 and y >= 0 and (x < len(s)) and (y < len(s[0])) and (s[x][y] == '.')

def DFS(x, y, s, used):
	used[x][y] = True
	global cnt
	cnt += 1
	for d in range(4):
		xx = x + dx[d]
		yy = y + dy[d]
		if not checkCell(s, xx, yy):
			continue
		if used[xx][yy]:
			continue
		DFS(xx, yy, s, used)

def DFS2(s, x, y):
	s[x][y] = '*'
	for d in range(4):
		xx = x + dx[d]
		yy = y + dy[d]
		if not checkCell(s, xx, yy):
			continue
		DFS2(s, xx, yy)

def solve():
	(n, m, k) = inp()
	s = []
	a = []
	global cnt
	cnt = 0
	for i in range(n):
		s.append(list(input()))
	used = [[False for y in range(m)] for x in range(n)]
	for i in range(n):
		for j in range(m):
			if i > 0 and i < n - 1 and (j > 0) and (j < m - 1):
				continue
			if s[i][j] == '*':
				continue
			DFS(i, j, s, used)
	for i in range(n):
		for j in range(m):
			if s[i][j] == '*':
				continue
			if used[i][j]:
				continue
			cnt = 0
			DFS(i, j, s, used)
			a.append(node(cnt, i, j))
	a = sorted(a, key=lambda node: node.count, reverse=True)
	sz = len(a)
	sum = 0
	for i in range(k, sz):
		sum += a[i].count
		DFS2(s, a[i].x, a[i].y)
	print(sum)
	for i in range(n):
		print(''.join(s[i]))
threading.stack_size(67108864)
sys.setrecursionlimit(2 ** 20)
thread = threading.Thread(target=solve)
thread.start()


import queue

class Cell:

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

class Lake:

	def __init__(self, cell_list, length):
		self.cell_list = cell_list
		self.length = length
row_direction = [-1, 1, 0, 0]
col_direction = [0, 0, -1, 1]

def dfs(graph: list, visited: list, rows, cols, current_row, current_col):
	visited_stacks = []
	cell = Cell(current_row, current_col)
	visited_stacks.append(cell)
	visited[current_row][current_col] = True
	cells = []
	cells.append(cell)
	while len(visited_stacks) > 0:
		current_cell = visited_stacks.pop()
		(cur_row, cur_col) = (current_cell.row, current_cell.col)
		for index in range(4):
			next_row = cur_row + row_direction[index]
			next_col = cur_col + col_direction[index]
			if 0 <= next_row <= rows - 1 and 0 <= next_col <= cols - 1 and (visited[next_row][next_col] is False) and (graph[next_row][next_col] == '.'):
				visited[next_row][next_col] = True
				next_cell = Cell(next_row, next_col)
				cells.append(next_cell)
				visited_stacks.append(next_cell)
	if len(cells) > 0:
		for res_cell in cells:
			if res_cell.row == 0 or res_cell.row == rows - 1 or res_cell.col == 0 or (res_cell.col == cols - 1):
				return []
	return cells
graph = []
(rows, cols, k) = map(int, input().split())
visited = [[False for c in range(cols + 1)] for r in range(rows + 1)]
for i in range(rows):
	line = list(input())
	graph.append(line)
lake_arr = []
for c_row in range(rows):
	for c_col in range(cols):
		if graph[c_row][c_col] == '.' and 0 < c_row < rows - 1 and (0 < c_col < cols - 1) and (visited[c_row][c_col] is False):
			cell_list = dfs(graph, visited, rows, cols, c_row, c_col)
			count = len(cell_list)
			if count > 0:
				lake = Lake(cell_list, len(cell_list))
				lake_arr.append(lake)
count = len(lake_arr)
total = 0
need_remove = count - k
lake_arr.sort(key=lambda l: l.length)
for i in range(need_remove):
	lake = lake_arr[i]
	cell_list = lake.cell_list
	for cell in cell_list:
		total += 1
		graph[cell.row][cell.col] = '*'
print(total)
for i in range(len(graph)):
	for ch in graph[i]:
		print(ch, end='')
	print()


from pprint import pprint
import itertools
import collections
(n, m, k) = [int(s) for s in input().split()]
g = [[0] * m for _ in range(n)]
for i in range(n):
	r = input()
	for (j, c) in enumerate(r):
		if c == '.':
			g[i][j] = 1
sidecomps = set()
curlab = 1
labels = [[0] * m for _ in range(n)]
for i in range(n):
	for j in range(m):
		if g[i][j] != 1 or labels[i][j] > 0:
			continue
		labels[i][j] = curlab
		stack = [(i, j)]
		if i == 0 or j == 0 or i == n - 1 or (j == m - 1):
			sidecomps.add(curlab)
		while stack:
			(i1, j1) = stack.pop()
			for (i2, j2) in [(i1 - 1, j1), (i1 + 1, j1), (i1, j1 - 1), (i1, j1 + 1)]:
				if 0 <= i2 and i2 < n and (0 <= j2) and (j2 < m) and (g[i2][j2] == 1) and (labels[i2][j2] == 0):
					labels[i2][j2] = curlab
					stack.append((i2, j2))
					if i2 == 0 or j2 == 0 or i2 == n - 1 or (j2 == m - 1):
						sidecomps.add(curlab)
		curlab += 1
lakes = collections.defaultdict(list)
for (i, j) in itertools.product(list(range(n)), list(range(m))):
	lab = labels[i][j]
	if lab > 0 and lab not in sidecomps:
		lakes[lab].append((i, j))
lakesizes = sorted(((len(lakes[lab]), lab) for lab in lakes))
num_remove = len(lakesizes) - k
ans = 0
for (_, lab) in lakesizes[:num_remove]:
	for (i, j) in lakes[lab]:
		g[i][j] = 0
		ans += 1
print(ans)
for i in range(n):
	print(''.join(('.' if g[i][j] else '*' for j in range(m))))


import sys
sys.setrecursionlimit(1000000)
(n, m, k) = map(int, input().split())
land = [[] for _ in range(n)]
for i in range(n):
	land[i] = list(input())

def dfs(a, b, value):
	global visited, dist_y, dist_x
	visited[a][b] = value
	for i in range(4):
		(new_a, new_b) = (a + dist_x[i], b + dist_y[i])
		if 0 <= new_a < len(visited) and 0 <= new_b < len(visited[0]) and (visited[new_a][new_b] == -1) and (land[new_a][new_b] == '.'):
			dfs(new_a, new_b, value)
dist_x = [0, 0, -1, 1]
dist_y = [1, -1, 0, 0]
visited = [[-1 for _ in range(m)] for x in range(n)]
for a in range(n):
	for b in range(m):
		if a == 0 or a == n - 1 or b == 0 or (b == m - 1):
			if land[a][b] == '.' and visited[a][b] == -1:
				dfs(a, b, 0)
lake_count = 0
for a in range(1, n):
	for b in range(1, m):
		if visited[a][b] == -1:
			if land[a][b] == '.':
				lake_count += 1
				dfs(a, b, lake_count)
lake = [[i, 0] for i in range(lake_count + 1)]
for a in range(1, n):
	for b in range(1, m):
		if visited[a][b] >= 1:
			lake[visited[a][b]][1] += 1
lake.pop(0)
res = 0
lake.sort(key=lambda x: x[1])
for i in range(lake_count - k):
	res += lake[i][1]
	for a in range(1, n):
		for b in range(1, m):
			if visited[a][b] == lake[i][0]:
				land[a][b] = '*'
print(res)
for i in land:
	print(''.join(i))


def main():

	def dfs(x, y):
		nonlocal inner
		if land[y][x] == '.':
			s = 1
			land[y][x] = '*'
			if x:
				s += dfs(x - 1, y)
			else:
				inner = False
			if x + 1 < m:
				s += dfs(x + 1, y)
			else:
				inner = False
			if y:
				s += dfs(x, y - 1)
			else:
				inner = False
			if y + 1 < n:
				s += dfs(x, y + 1)
			else:
				inner = False
			return s
		return 0
	(n, m, k) = list(map(int, input().split()))
	land = [list(input()) for _ in range(n)]
	sav = [row[:] for row in land]
	lakes = []
	for (y, row) in enumerate(land):
		for (x, f) in enumerate(row):
			inner = True
			s = dfs(x, y)
			if s and inner:
				lakes.append((s, x, y))
	(land, res) = (sav, 0)
	for (_, x, y) in sorted(lakes)[:len(lakes) - k]:
		res += dfs(x, y)
	print(res)
	for row in land:
		print(''.join(row))

def __starting_point():
	from sys import setrecursionlimit
	setrecursionlimit(3000)
	main()
__starting_point()


import sys
from math import sqrt, gcd, ceil, log
from collections import defaultdict, Counter, deque
input = sys.stdin.readline
read = lambda : list(map(int, input().strip().split()))
sys.setrecursionlimit(10 ** 6)

def main():
	(n, m, k) = read()
	mat = []
	for i in range(n):
		mat.append(list(input().strip()))
	cells = defaultdict(list)
	cell = 0
	visited = defaultdict(int)

	def dfs(x, y, cell):
		visited[x, y] = 1
		cells[cell].append((x, y))
		for child in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
			(i, j) = child
			if 0 < i < n - 1 and 0 < j < m - 1 and (not visited[i, j]) and (mat[i][j] == '.'):
				dfs(i, j, cell)
	for i in range(n):
		step = 1
		if not i in [0, n - 1]:
			step = m - 1
		for j in range(0, m, step):
			if mat[i][j] == '.' and (not visited[i, j]):
				dfs(i, j, cell)
	cells = defaultdict(list)
	for i in range(1, n - 1):
		for j in range(1, m - 1):
			if mat[i][j] == '.' and (not visited[i, j]):
				cell += 1
				dfs(i, j, cell)
	arr = [(len(cells[i]), i) for i in cells]
	arr.sort()
	count = 0
	for i in range(len(arr) - k):
		cell = arr[i][1]
		for j in cells[cell]:
			mat[j[0]][j[1]] = '*'
			count += 1
	print(count)
	for i in mat:
		print(''.join(i))
main()


datain = True
if datain:
	(n, m, k) = map(int, input().split())
	a = []
	for i in range(n):
		b = list(input())
		a.append(b)
else:
	(n, m, k) = (4, 4, 0)
	a = [['*', '*', '*', '*'], ['*', '.', '.', '*'], ['*', '.', '.', '*'], ['*', '*', '*', '*']]
node = n * m
graph = [[] for i in range(node)]
nodes = []
ocean = []
visited = [False for i in range(node)]
ind = -1
for i in range(n):
	for j in range(m):
		ind += 1
		nodes.append(ind)
		if a[i][j] == '*':
			visited[ind] = True
		if j < m - 1 and a[i][j] == '.' and (a[i][j + 1] == '.'):
			graph[ind].append(ind + 1)
			graph[ind + 1].append(ind)
		if i < n - 1 and a[i][j] == '.' and (a[i + 1][j] == '.'):
			graph[ind].append(ind + m)
			graph[ind + m].append(ind)
		if i == 0 or j == 0 or i == n - 1 or (j == m - 1):
			ocean.append(ind)

def dfs_iter(src):
	visited[src] = True
	lake = True
	size = 0
	visit = []
	cells = []
	visit.append(src)
	cells.append(src)
	while len(visit) > 0:
		v_here = visit.pop()
		size += 1
		if v_here in ocean:
			lake = False
		for v_next in graph[v_here]:
			if not visited[v_next]:
				visited[v_next] = True
				visit.append(v_next)
				cells.append(v_next)
	return (lake, size, cells)

def reclaim(cells):
	for cell in cells:
		y = cell % m
		x = int((cell - y) / m)
		a[x][y] = '*'
lakes = []
for i in range(node):
	if not visited[i]:
		(lake, size, cells) = dfs_iter(i)
		if lake:
			lakes.append([size, cells])
nlake = len(lakes)
lakes.sort(key=lambda x: x[0])
area = 0
for i in range(nlake - k):
	area += lakes[i][0]
	reclaim(lakes[i][1])
print(area)
for i in range(n):
	for j in range(m):
		print(a[i][j], end='')
	print()


from collections import deque

def main():
	DELTAS = ((-1, 0), (0, 1), (1, 0), (0, -1))
	try:
		while True:
			(n, m, k) = list(map(int, input().split()))
			grid = [list(input()) for i in range(n)]
			lakes = []
			q = deque()
			for i in range(n):
				for j in (0, m - 1):
					if grid[i][j] == '.':
						grid[i][j] = '?'
						q.append((i, j))
						while q:
							(y, x) = q[0]
							q.popleft()
							for (dy, dx) in DELTAS:
								ny = y + dy
								nx = x + dx
								if 0 <= ny < n and 0 <= nx < m and (grid[ny][nx] == '.'):
									grid[ny][nx] = '?'
									q.append((ny, nx))
			for i in (0, n - 1):
				for j in range(m):
					if grid[i][j] == '.':
						grid[i][j] = '?'
						q.append((i, j))
						while q:
							(y, x) = q[0]
							q.popleft()
							for (dy, dx) in DELTAS:
								ny = y + dy
								nx = x + dx
								if 0 <= ny < n and 0 <= nx < m and (grid[ny][nx] == '.'):
									grid[ny][nx] = '?'
									q.append((ny, nx))
			for i in range(n):
				for j in range(m):
					if grid[i][j] == '.':
						grid[i][j] = '?'
						q.append((i, j))
						area = 1
						while q:
							(y, x) = q[0]
							q.popleft()
							for (dy, dx) in DELTAS:
								ny = y + dy
								nx = x + dx
								if 0 <= ny < n and 0 <= nx < m and (grid[ny][nx] == '.'):
									grid[ny][nx] = '?'
									q.append((ny, nx))
									area += 1
						lakes.append((area, i, j))
			lakes.sort(reverse=True)
			print(sum((x[0] for x in lakes[k:])))
			for (_, i, j) in lakes[k:]:
				grid[i][j] = '*'
				q.append((i, j))
				while q:
					(y, x) = q[0]
					q.popleft()
					for (dy, dx) in DELTAS:
						ny = y + dy
						nx = x + dx
						if 0 <= ny < n and 0 <= nx < m and (grid[ny][nx] == '?'):
							grid[ny][nx] = '*'
							q.append((ny, nx))
			print('\n'.join((''.join(ls).replace('?', '.') for ls in grid)))
	except EOFError:
		pass
main()


(x, y, k) = list(map(int, input().split()))
a = [input().strip() for i in range(x)]
m = [[0 if j == '*' else 1 for j in i] for i in a]
m1 = [[0 if j == '*' else 1 for j in i] for i in a]
lk = []

def bfs(m, i, j):
	q = set()
	s = 0
	f = 1
	q.add((i, j))
	while q:
		(ax, ay) = q.pop()
		m[ax][ay] = 0
		s += 1
		if ax == 0 or ay == 0 or ax == x - 1 or (ay == y - 1):
			f = 0
		if ax < x - 1 and m[ax + 1][ay]:
			q.add((ax + 1, ay))
		if ax > 0 and m[ax - 1][ay]:
			q.add((ax - 1, ay))
		if ay < y - 1 and m[ax][ay + 1]:
			q.add((ax, ay + 1))
		if ay > 0 and m[ax][ay - 1]:
			q.add((ax, ay - 1))
	return (f, s)
for i in range(x):
	for j in range(y):
		if m1[i][j]:
			(f, s) = bfs(m1, i, j)
			if f:
				lk.append((s, i, j))
lk.sort()
k1 = len(lk)
sal = 0
for e in range(k1 - k):
	(s, i, j) = lk[e]
	sal += s
	bfs(m, i, j)
print(sal)
for i in range(x):
	print(''.join(['.' if j else '*' for j in m[i]]))


dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def on_border(x, y):
	return x == 0 or x == n - 1 or y == 0 or (y == m - 1)

def DFS(sx, sy):
	global n, m, b_map, visited, lakes
	stack = []
	visited[sx][sy] = True
	stack.append((sx, sy))
	is_ocean = False
	water_area = []
	while len(stack) > 0:
		(ux, uy) = stack.pop()
		water_area.append((ux, uy))
		if on_border(ux, uy):
			is_ocean = True
		for i in range(4):
			vx = ux + dx[i]
			vy = uy + dy[i]
			if vx in range(n) and vy in range(m) and (not visited[vx][vy]) and (b_map[vx][vy] == '.'):
				visited[vx][vy] = True
				stack.append((vx, vy))
	if is_ocean == False:
		lakes.append(water_area)
(n, m, k) = map(int, input().split())
b_map = []
for i in range(n):
	line = input()
	b_map.append(list(line))
visited = [[False for _ in range(m)] for _ in range(n)]
lakes = []
for i in range(n):
	for j in range(m):
		if not visited[i][j] and b_map[i][j] == '.':
			DFS(i, j)
lakes = sorted(lakes, key=lambda x: len(x))
count = 0
for i in range(len(lakes) - k):
	count += len(lakes[i])
	for j in range(len(lakes[i])):
		(x, y) = lakes[i][j]
		b_map[x][y] = '*'
print(count)
for line in range(n):
	print(*b_map[line], sep='')


import sys
sys.setrecursionlimit(3000)
ii = lambda : sys.stdin.readline().strip()
idata = lambda : [int(x) for x in ii().split()]
sdata = lambda : list(ii())
(n, m, p) = idata()
data = []
for i in range(n):
	data += [sdata()]
d = 0
slov = {0: 0}

def fun(x, y):
	global d, data, slov, n, m
	x = min(max(0, x), n - 1)
	y = min(max(0, y), m - 1)
	if data[x][y] == '.':
		if x > 0 and data[x - 1][y] != '.' and (data[x - 1][y] != '*'):
			data[x][y] = data[x - 1][y]
			slov[data[x][y]] += 1
		elif x + 1 < n and data[x + 1][y] != '.' and (data[x + 1][y] != '*'):
			data[x][y] = data[x + 1][y]
			slov[data[x][y]] += 1
		elif y > 0 and data[x][y - 1] != '.' and (data[x][y - 1] != '*'):
			data[x][y] = data[x][y - 1]
			slov[data[x][y]] += 1
		elif y + 1 < m and data[x][y + 1] != '.' and (data[x][y + 1] != '*'):
			data[x][y] = data[x][y + 1]
			slov[data[x][y]] += 1
		else:
			d += 1
			data[x][y] = d
			slov[d] = 1
		fun1(min(n - 1, x + 1), y)
		fun1(max(0, x - 1), y)
		fun1(x, min(m - 1, y + 1))
		fun1(x, max(0, y - 1))

def fun1(x, y):
	global d, data, slov, n, m
	x = min(max(0, x), n - 1)
	y = min(max(0, y), m - 1)
	if data[x][y] == '.':
		if x > 0 and data[x - 1][y] != '.' and (data[x - 1][y] != '*'):
			data[x][y] = data[x - 1][y]
			slov[data[x][y]] += 1
		elif x + 1 < n and data[x + 1][y] != '.' and (data[x + 1][y] != '*'):
			data[x][y] = data[x + 1][y]
			slov[data[x][y]] += 1
		elif y > 0 and data[x][y - 1] != '.' and (data[x][y - 1] != '*'):
			data[x][y] = data[x][y - 1]
			slov[data[x][y]] += 1
		elif y + 1 < m and data[x][y + 1] != '.' and (data[x][y + 1] != '*'):
			data[x][y] = data[x][y + 1]
			slov[data[x][y]] += 1
		else:
			d += 1
			data[x][y] = d
			slov[d] = 1
		fun(min(n - 1, x + 1), y)
		fun(max(0, x - 1), y)
		fun(x, min(m - 1, y + 1))
		fun(x, max(0, y - 1))
for i in range(m):
	if data[0][i] == '.':
		data[0][i] = 0
		fun(1, i)
	if data[-1][i] == '.':
		data[-1][i] = 0
		fun(n - 2, i)
for i in range(n):
	if data[i][0] == '.':
		data[i][0] = 0
		fun(i, 1)
	if data[i][-1] == '.':
		data[i][-1] = 0
		fun(i, m - 2)
for i in range(1, n - 1):
	for j in range(1, m - 1):
		fun(i, j)
slov[0] = -12
summ = 0
ans = {}
for i in slov:
	if slov[i] in ans:
		ans[slov[i]] += [i]
	else:
		ans[slov[i]] = [i]
k = sorted(ans.keys())[1:]
for i in range(len(k)):
	if d > p:
		if d - p <= len(ans[k[i]]):
			summ += (d - p) * k[i]
			for w in range(d - p):
				slov[ans[k[i]][w]] = 0
			break
		else:
			summ += len(ans[k[i]]) * k[i]
			for w in ans[k[i]]:
				slov[w] = 0
			d -= len(ans[k[i]])
	else:
		break
print(summ)
slov['*'] = 0
for i in range(n):
	for j in range(m):
		if data[i][j] == 0 or slov[data[i][j]] != 0:
			print('.', end='')
		else:
			print('*', end='')
	print()


class Unionfind:

	def __init__(self, n):
		self.par = [-1] * n
		self.rank = [1] * n

	def root(self, x):
		p = x
		while not self.par[p] < 0:
			p = self.par[p]
		while x != p:
			tmp = x
			x = self.par[x]
			self.par[tmp] = p
		return p

	def unite(self, x, y):
		(rx, ry) = (self.root(x), self.root(y))
		if rx == ry:
			return False
		if self.rank[rx] < self.rank[ry]:
			(rx, ry) = (ry, rx)
		self.par[rx] += self.par[ry]
		self.par[ry] = rx
		if self.rank[rx] == self.rank[ry]:
			self.rank[rx] += 1

	def is_same(self, x, y):
		return self.root(x) == self.root(y)

	def count(self, x):
		return -self.par[self.root(x)]
(n, m, k) = map(int, input().split())
S = [['.' for _ in range(m + 2)]]
for _ in range(n):
	Si = list(input())
	S.append(['.'] + Si + ['.'])
S.append(['.' for _ in range(m + 2)])
uf = Unionfind((n + 2) * (m + 2))
for i in range(n + 2):
	for j in range(m + 2):
		if S[i][j] == '*':
			continue
		for (ni, nj) in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
			if 0 <= ni < n + 2 and 0 <= nj < m + 2 and (S[ni][nj] == '.'):
				uf.unite(i * (m + 2) + j, ni * (m + 2) + nj)
rs = set()
for i in range(n + 2):
	for j in range(m + 2):
		if S[i][j] == '.':
			rs.add(uf.root(i * (m + 2) + j))
l = []
for r in rs:
	if not uf.is_same(0, r):
		l.append((r, uf.count(r)))
l.sort(key=lambda t: t[1])
fill_rs = set()
for i in range(len(l) - k):
	fill_rs.add(l[i][0])
ans = 0
for i in range(n + 2):
	for j in range(m + 2):
		if uf.root(i * (m + 2) + j) in fill_rs:
			S[i][j] = '*'
			ans += 1
print(ans)
for i in range(1, n + 1):
	print(''.join(S[i][1:m + 1]))


import copy
import sys
sys.setrecursionlimit(100000000)
k = n = m = 0
grid = []
bury = []
lake = []
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]

def check(x, y):
	global n, m
	return -1 < x and x < n and (-1 < y) and (y < m)

def dfs(x, y):
	global grid, dx, dy
	grid[x][y] = '*'
	for i in range(4):
		nextX = x + dx[i]
		nextY = y + dy[i]
		if check(nextX, nextY) and grid[nextX][nextY] == '.':
			dfs(nextX, nextY)

def dfsSave(x, y):
	global lake, grid, dx, dy
	lake.append((x, y))
	grid[x][y] = '*'
	for i in range(4):
		nextX = x + dx[i]
		nextY = y + dy[i]
		if check(nextX, nextY) and grid[nextX][nextY] == '.':
			dfsSave(nextX, nextY)
(n, m, k) = map(int, input().split())
for _ in range(n):
	grid.append(list(input()))
finalGrid = copy.deepcopy(grid)
for i in range(n):
	if grid[i][0] == '.':
		dfs(i, 0)
	if grid[i][m - 1] == '.':
		dfs(i, m - 1)
for i in range(m):
	if grid[0][i] == '.':
		dfs(0, i)
	if grid[n - 1][i] == '.':
		dfs(n - 1, i)
for i in range(n):
	for j in range(m):
		if grid[i][j] == '.':
			lake = []
			dfsSave(i, j)
			bury.append(lake)
bury.sort(key=lambda x: len(x))
lakeBury = len(bury) - k
ans = 0
for i in range(lakeBury):
	for p in bury[i]:
		ans += 1
		finalGrid[p[0]][p[1]] = '*'
print(ans)
for i in range(n):
	print(''.join(finalGrid[i]))


import sys
sys.setrecursionlimit(100000)
(n, m, k) = [int(x) for x in input().split()]
ar = [list(input()) for x in range(n)]
col = [[0 for y in range(m)] for x in range(n)]
ans = []
lake = []
cnt = dict()
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

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

def dfs(x, y, c):
	col[x][y] = c
	if c not in cnt:
		cnt[c] = []
	cnt[c].append((x, y))
	for k in range(4):
		i = x + dx[k]
		j = y + dy[k]
		if is_val(i, j) and (not col[i][j]) and (ar[i][j] == '.'):
			dfs(i, j, c)
for j in range(m):
	if not col[0][j] and ar[0][j] == '.':
		dfs(0, j, -1)
	if not col[n - 1][j] and ar[n - 1][j] == '.':
		dfs(n - 1, j, -1)
for i in range(n):
	if not col[i][0] and ar[i][0] == '.':
		dfs(i, 0, -1)
	if not col[i][m - 1] and ar[i][m - 1] == '.':
		dfs(i, m - 1, -1)
c = 1
for i in range(n):
	for j in range(m):
		if not col[i][j] and ar[i][j] == '.':
			dfs(i, j, c)
			lake.append((len(cnt[c]), c))
			c += 1
tmp = len(lake) - k
lake.sort()
for i in range(tmp):
	for j in cnt[lake[i][1]]:
		ans.append(j)
		ar[j[0]][j[1]] = '*'
print(len(ans))
for i in range(n):
	for j in range(m):
		print(ar[i][j], end='')
	print()


import sys
sys.setrecursionlimit(10 ** 6)

class Edge:

	def __init__(self, from_vertex, to_vertex, weight=0):
		self.from_vertex = from_vertex
		self.to_vertex = to_vertex
		self.weight = weight

	def get_from(self):
		return self.from_vertex

	def get_to(self):
		return self.to_vertex

	def get_weight(self):
		return self.weight

	def __str__(self):
		return str('{v} -> {w} : {weight}'.format(v=self.from_vertex, w=self.to_vertex, weight=self.weight))

class Graph:

	def __init__(self, num_vertex):
		self.num_vertex = num_vertex
		self.adj_list = [[] for i in range(num_vertex)]

	def __len__(self):
		return self.num_vertex

	def add_edge(self, v, w, weight=0):
		edge = Edge(v, w, weight)
		self.adj_list[v].append(edge)

	def adj(self, vertex):
		return self.adj_list[vertex]

def dfs(graph, source, marked, lake):
	marked[source] = True
	lake.append(source)
	for e in graph.adj(source):
		w = e.get_to()
		if not marked[w]:
			dfs(graph, w, marked, lake)

def to_index(row, col):
	return row * width + col

def has_left(row, col):
	return col != 0

def has_right(row, col):
	return col != width - 1

def has_above(row, col):
	return row != 0

def has_below(row, col):
	return row != height - 1

def is_rear(idx):
	return idx % width == 0 or (idx + 1) % width == 0 or idx < width or (idx > height * width - width)

def is_valid(lake):
	if lake is None:
		return False
	for pixel in lake:
		if is_rear(pixel):
			return False
	return True

def generate_lakes(berland_map):
	lake_list = []
	marked = [False for i in range(len(berland_map))]
	for row in range(height):
		for col in range(width):
			lake = None
			if berland_matrix[row][col] == '*':
				continue
			v = to_index(row, col)
			if not marked[v]:
				lake = []
				v = to_index(row, col)
				dfs(berland_map, v, marked, lake)
			if is_valid(lake):
				lake_list.append(lake)
	return lake_list
height = 0
width = 0
lakes_limit = 0
berland_matrix = None

def main():
	global height, width, lakes_limit, berland_matrix
	(height, width, lakes_limit) = map(int, input().split(' '))
	berland_matrix = []
	for i in range(height):
		temp = list(map(str, input()))
		berland_matrix.append(temp)
	berland_map = Graph(height * width)
	for row in range(height):
		for col in range(width):
			s = to_index(row, col)
			if has_left(row, col):
				if berland_matrix[row][col] == berland_matrix[row][col - 1]:
					t = to_index(row, col - 1)
					berland_map.add_edge(s, t)
			if has_right(row, col):
				if berland_matrix[row][col] == berland_matrix[row][col + 1]:
					t = to_index(row, col + 1)
					berland_map.add_edge(s, t)
			if has_above(row, col):
				if berland_matrix[row][col] == berland_matrix[row - 1][col]:
					t = to_index(row - 1, col)
					berland_map.add_edge(s, t)
			if has_below(row, col):
				if berland_matrix[row][col] == berland_matrix[row + 1][col]:
					t = to_index(row + 1, col)
					berland_map.add_edge(s, t)
	list_of_lakes = generate_lakes(berland_map)
	list_of_lakes.sort(key=len)
	minimum_removal_cells = 0
	lakes_to_remove = []
	if len(list_of_lakes) > lakes_limit:
		dif = len(list_of_lakes) - lakes_limit
		for i in range(dif):
			lake = list_of_lakes[i]
			minimum_removal_cells += len(lake)
			lakes_to_remove.append(lake)
	print(minimum_removal_cells)
	for lake in lakes_to_remove:
		for cell in lake:
			row = cell // width
			col = cell % width
			berland_matrix[row][col] = '*'
	for row in range(height):
		for col in range(width):
			print(berland_matrix[row][col], end='')
		print('')
main()


import sys

def zapoln(mas, x, y):
	if mas[x][y] == '*':
		return mas
	mas[x][y] = '*'
	if mas[x - 1][y] == '.':
		mas = zapoln(mas, x - 1, y)
	if mas[x + 1][y] == '.':
		mas = zapoln(mas, x + 1, y)
	if mas[x][y + 1] == '.':
		mas = zapoln(mas, x, y + 1)
	if mas[x][y - 1] == '.':
		mas = zapoln(mas, x, y - 1)
	return mas

def bfs(mas, x, y):
	q = [[x, y]]
	mas[x][y] = '*'
	if mas[x - 1][y] == '.':
		q += bfs(mas, x - 1, y)
	if mas[x + 1][y] == '.':
		q += bfs(mas, x + 1, y)
	if mas[x][y + 1] == '.':
		q += bfs(mas, x, y + 1)
	if mas[x][y - 1] == '.':
		q += bfs(mas, x, y - 1)
	return q

def sortdl(u):
	return len(u)

def input1():
	d = []
	g = input()
	for i in g:
		d.append(i)
	return d
sys.setrecursionlimit(5000)
(n, m, k) = map(int, input().split())
d = [['*'] * (m + 2)]
for i in range(n):
	d.append(['*'] + input1() + ['*'])
d.append(['*'] * (m + 2))
h = []
for i in d:
	h.append(i[0:])
for i in range(1, m + 1):
	h = zapoln(h, 1, i)
	h = zapoln(h, n, i)
for i in range(2, n + 1):
	h = zapoln(h, i, 1)
	h = zapoln(h, i, m)
oz = []
for i in range(2, n):
	for j in range(2, m):
		if h[i][j] == '.':
			oz.append(bfs(h, i, j))
oz.sort(key=sortdl)
oz = oz[:len(oz) - k]
ans = 0
for i in oz:
	for j in i:
		(a, b) = (j[0], j[1])
		d[a][b] = '*'
		ans += 1
print(ans)
for i in range(1, n + 1):
	for j in range(1, m + 1):
		print(d[i][j], end='')
	print()


import sys
sys.setrecursionlimit(100000)
(n, m, k) = map(int, input().split())
arr = []
for i in range(n):
	krr = []
	p = input()
	for x in p:
		if x == '*':
			krr.append(0)
		else:
			krr.append(-1)
	arr.append(krr)
lakes = [-1]
islakes = [-1]
lakesp = [[-1, -1]]

def go(x, y, c):
	if x < 0 or x >= n or y < 0 or (y >= m):
		return
	if arr[x][y] == 0:
		return
	if arr[x][y] != -1:
		return
	arr[x][y] = c
	if x == 0 or x == n - 1 or y == 0 or (y == m - 1):
		islakes[c] = 0
	lakes[c] += 1
	go(x - 1, y, c)
	go(x, y - 1, c)
	go(x + 1, y, c)
	go(x, y + 1, c)
color = 0
for x in range(n):
	for y in range(m):
		if arr[x][y] == -1:
			color += 1
			lakes.append(0)
			islakes.append(1)
			go(x, y, color)
			lakesp.append([x, y])

def re(x, y):
	if x < 0 or x >= n or y < 0 or (y >= m):
		return
	if arr[x][y] == 0:
		return
	arr[x][y] = 0
	re(x - 1, y)
	re(x, y - 1)
	re(x + 1, y)
	re(x, y + 1)

def min():
	min = 1000000000
	mini = 0
	for i in range(1, color + 1):
		if islakes[i]:
			if min > lakes[i]:
				min = lakes[i]
				mini = i
	return mini
cnt = 0
nn = 0
for i in range(1, color + 1):
	if islakes[i] == 0:
		continue
	nn += 1
p = nn - k
for i in range(1, color + 1):
	if p == 0:
		break
	j = min()
	cnt += lakes[j]
	lakes[j] = 1000000000
	re(lakesp[j][0], lakesp[j][1])
	p -= 1
print(cnt)
for x in arr:
	s = ''
	for y in x:
		if y == 0:
			s += '*'
		else:
			s += '.'
	print(s)


def fill_the_lakes(n, m, k, matrix):
	lakes = []
	dx = [1, 0, -1, 0]
	dy = [0, -1, 0, 1]
	visited = [[False for i in range(m)] for i in range(n)]
	for i in range(n):
		for j in range(m):
			is_lake = False
			lake = []
			if matrix[i][j] == '.' and (not visited[i][j]):
				if i == 0 or i == n - 1 or j == 0 or (j == m - 1):
					is_lake = False
				else:
					is_lake = True
				lake.append([i, j])
				s = [[i, j]]
				visited[i][j] = True
				while len(s) > 0:
					checking_node = s[-1]
					s.pop()
					for ll in range(4):
						neighbor_x = checking_node[0] + dx[ll]
						neighbor_y = checking_node[1] + dy[ll]
						if 0 <= neighbor_x < n and 0 <= neighbor_y < m and (matrix[neighbor_x][neighbor_y] == '.') and (not visited[neighbor_x][neighbor_y]):
							s.append([neighbor_x, neighbor_y])
							lake.append([neighbor_x, neighbor_y])
							visited[neighbor_x][neighbor_y] = True
							if neighbor_x == 0 or neighbor_x == n - 1 or neighbor_y == 0 or (neighbor_y == m - 1):
								is_lake = False
			if is_lake and len(lake) > 0:
				lakes.append(lake)
	lakes = sorted(lakes, key=lambda _lake: len(_lake))
	to_be_filled = len(lakes) - k
	filled_cells = 0
	for i in range(to_be_filled):
		lake_len = len(lakes[i])
		for j in range(lake_len):
			matrix[lakes[i][j][0]][lakes[i][j][1]] = '*'
			filled_cells += 1
	print(filled_cells)
	for i in range(n):
		print(''.join(matrix[i]))

def solution():
	(n, m, k) = map(int, input().split())
	matrix = []
	for i in range(n):
		matrix.append(list(input().strip()))
	fill_the_lakes(n, m, k, matrix)
solution()


def zapoln(mas, x, y):
	if mas[x][y] == '*':
		return mas
	mas[x][y] = '*'
	if mas[x - 1][y] == '.':
		mas = zapoln(mas, x - 1, y)
	if mas[x + 1][y] == '.':
		mas = zapoln(mas, x + 1, y)
	if mas[x][y + 1] == '.':
		mas = zapoln(mas, x, y + 1)
	if mas[x][y - 1] == '.':
		mas = zapoln(mas, x, y - 1)
	return mas

def bfs(mas, x, y):
	q = [[x, y]]
	mas[x][y] = '*'
	if mas[x - 1][y] == '.':
		q += bfs(mas, x - 1, y)
	if mas[x + 1][y] == '.':
		q += bfs(mas, x + 1, y)
	if mas[x][y + 1] == '.':
		q += bfs(mas, x, y + 1)
	if mas[x][y - 1] == '.':
		q += bfs(mas, x, y - 1)
	return q

def sortdl(u):
	return len(u)

def input1():
	d = []
	g = input()
	for i in g:
		d.append(i)
	return d
(n, m, k) = map(int, input().split())
d = [['*'] * (m + 2)]
for i in range(n):
	d.append(['*'] + input1() + ['*'])
d.append(['*'] * (m + 2))
count = 0
for i in range(1, n + 1):
	if '*' in set(d[i][1:m + 1]):
		count = 1
		break
if count == 0:
	print(0)
	for i in range(n):
		print('.' * m)
	exit()
h = []
for i in d:
	h.append(i[0:])
for i in range(1, m + 1):
	h = zapoln(h, 1, i)
	h = zapoln(h, n, i)
for i in range(2, n + 1):
	h = zapoln(h, i, 1)
	h = zapoln(h, i, m)
oz = []
for i in range(2, n):
	for j in range(2, m):
		if h[i][j] == '.':
			oz.append(bfs(h, i, j))
oz.sort(key=sortdl)
oz = oz[:len(oz) - k]
ans = 0
for i in oz:
	for j in i:
		(a, b) = (j[0], j[1])
		d[a][b] = '*'
		ans += 1
print(ans)
for i in range(1, n + 1):
	for j in range(1, m + 1):
		print(d[i][j], end='')
	print()


import sys
sys.setrecursionlimit(100005)
dr = [-1, 0, 1, 0]
dc = [0, 1, 0, -1]

def isValid(r, c):
	if 0 <= r <= m + 1 and 0 <= c <= n + 1:
		return True
	return False

def dfs(ur, vr):
	s = [(ur, vr)]
	visited[ur][vr] = True
	tmp = []
	while len(s):
		(u, v) = s.pop()
		tmp.append((u, v))
		for k in range(4):
			r = u + dr[k]
			c = v + dc[k]
			if isValid(r, c) and visited[r][c] == False and (maps[r][c] == 0):
				s.append((r, c))
				visited[r][c] = True
	if ur != 0:
		lakes.append(tmp)
(m, n, k) = map(int, input().split())
arr = [input() for i in range(1, m + 1)]
maps = [[0] * (n + 2) for i in range(m + 2)]
visited = [[False] * (n + 2) for i in range(m + 2)]
for i in range(1, m + 1):
	for j in range(1, n + 1):
		if arr[i - 1][j - 1] == '*':
			maps[i][j] = 1
dfs(0, 0)
lakes = []
for i in range(1, m + 1):
	for j in range(1, n + 1):
		if visited[i][j] == False and maps[i][j] == 0:
			dfs(i, j)
ans = 0
lakes.sort(key=lambda lakes: len(lakes))
for i in range(len(lakes) - k):
	ans += len(lakes[i])
	for j in range(len(lakes[i])):
		(r, c) = lakes[i][j]
		maps[r][c] = 1
print(ans)
for i in range(1, m + 1):
	for j in range(1, n + 1):
		if maps[i][j] == 0:
			print('.', end='')
		else:
			print('*', end='')
	print()


nml = list(map(int, input('').split()))
n = nml[0]
m = nml[1]
l = nml[2]
matrix = []
for i in range(n):
	row = list(input(''))
	matrix.append(row)
visited = {}
max_lake = n * m
results = []
for h in range(n):
	for k in range(m):
		if matrix[h][k] == '.' and visited.get((h, k), 0) == 0:
			cnt = 0
			s = []
			s.append((h, k))
			visited[h, k] = 1
			isLake = True
			cnt = 1
			points = []
			while len(s) > 0:
				(i, j) = s.pop()
				points.append((i, j))
				if matrix[i][j] == '.':
					if i - 1 < 0 or j - 1 < 0 or i + 1 > n - 1 or (j + 1 > m - 1):
						isLake = False
				if j - 1 >= 0:
					left = matrix[i][j - 1]
					if left == '.':
						if visited.get((i, j - 1), 0) == 0:
							visited[i, j - 1] = 1
							s.append((i, j - 1))
							cnt += 1
				if j + 1 <= m - 1:
					right = matrix[i][j + 1]
					if right == '.':
						if visited.get((i, j + 1), 0) == 0:
							visited[i, j + 1] = 1
							s.append((i, j + 1))
							cnt += 1
				if i + 1 <= n - 1:
					down = matrix[i + 1][j]
					if down == '.':
						if visited.get((i + 1, j), 0) == 0:
							visited[i + 1, j] = 1
							s.append((i + 1, j))
							cnt += 1
				if i - 1 >= 0:
					up = matrix[i - 1][j]
					if up == '.':
						if visited.get((i - 1, j), 0) == 0:
							visited[i - 1, j] = 1
							s.append((i - 1, j))
							cnt += 1
			if isLake == True:
				results.append({'start': (h, k), 'cnt': cnt, 'points': points})
results = sorted(results, key=lambda i: i['cnt'])
water_nums = 0
for i in range(0, len(results) - l):
	change = results[i]
	point = change['start']
	cnt = change['cnt']
	points = change['points']
	water_nums += cnt
	for y in range(len(points)):
		matrix[points[y][0]][points[y][1]] = '*'
print(water_nums)
for i in range(n):
	print(''.join(matrix[i]))


import sys
ii = lambda : sys.stdin.readline().strip()
idata = lambda : [int(x) for x in ii().split()]
sdata = lambda : list(ii())
(n, m, p) = idata()
data = []
data_start = []
for i in range(n):
	d = sdata()
	data += [d[:]]
	data_start += [d[:]]
water = [[0, 0]] if data[0][0] == '.' else []
earth = [[0, 0]] if data[0][0] == '*' else []
now_water = []
areas = {0: 0}
lakes_quantity = 0
while bool(water) or bool(earth):
	if bool(water):
		now_water += [water.pop(0)]
	while bool(now_water):
		(x, y) = now_water.pop(0)
		if data[x][y] != '.':
			continue
		dx = [0, 0, 1, -1]
		dy = [1, -1, 0, 0]
		flag = 1
		for i in range(4):
			if 0 <= x + dx[i] < n and 0 <= y + dy[i] < m:
				if data[x + dx[i]][y + dy[i]] == '.':
					now_water += [(x + dx[i], y + dy[i])]
				elif data[x + dx[i]][y + dy[i]] == '*':
					earth += [(x + dx[i], y + dy[i])]
				elif data[x + dx[i]][y + dy[i]] != -1:
					data[x][y] = data[x + dx[i]][y + dy[i]]
					flag = 0
		if flag:
			lakes_quantity += 1
			data[x][y] = lakes_quantity
			areas[lakes_quantity] = 0
		areas[lakes_quantity] += 1
	if bool(earth):
		(x, y) = earth.pop(0)
		if data[x][y] == '*':
			dx = [0, 0, 1, -1]
			dy = [1, -1, 0, 0]
			data[x][y] = -1
			for i in range(4):
				if 0 <= x + dx[i] < n and 0 <= y + dy[i] < m:
					if data[x + dx[i]][y + dy[i]] == '.':
						water += [(x + dx[i], y + dy[i])]
					elif data[x + dx[i]][y + dy[i]] == '*':
						earth += [(x + dx[i], y + dy[i])]
for i in range(n):
	if data[i][0] != -1:
		areas[data[i][0]] = -12
	if data[i][-1] != -1:
		areas[data[i][-1]] = -12
for i in range(m):
	if data[0][i] != -1:
		areas[data[0][i]] = -12
	if data[-1][i] != -1:
		areas[data[-1][i]] = -12
ans = {}
for i in areas:
	if areas[i] in ans:
		ans[areas[i]] += [i]
	else:
		ans[areas[i]] = [i]
k = sorted(ans.keys())[1:]
a = []
b = []
summ = 0
for i in range(len(k)):
	sp = ans[k[i]]
	a += sp
	b += [k[i]] * len(sp)
for i in range(len(a) - p):
	areas[a[i]] = 0
	summ += b[i]
print(summ)
for i in range(n):
	for j in range(m):
		if data[i][j] == -1 or areas[data[i][j]] == 0:
			print('*', end='')
		else:
			print('.', end='')
	print()


import sys
from collections import defaultdict, OrderedDict
sys.setrecursionlimit(10 ** 5)
(n, m, k) = list(map(int, input().split()))
g = []
for i in range(n):
	g.append(list(input()))
dy = [1, -1, 0, 0]
dx = [0, 0, 1, -1]
d = defaultdict(list)

def dfs(g, u, visited):
	visited[u[0]][u[1]] = True
	for i in range(4):
		y = u[0] + dy[i]
		x = u[1] + dx[i]
		if y >= 0 and y < n and (x >= 0) and (x < m) and (g[y][x] == '.') and (not visited[y][x]):
			dfs(g, (y, x), visited)

def dfs_(g, u, visited, component):
	visited[u[0]][u[1]] = True
	d[component].append(u)
	for i in range(4):
		y = u[0] + dy[i]
		x = u[1] + dx[i]
		if y >= 0 and y < n and (x >= 0) and (x < m) and (g[y][x] == '.') and (not visited[y][x]):
			dfs_(g, (y, x), visited, component)
visited = [[False for j in range(m)] for i in range(n)]
for i in range(m):
	if g[0][i] == '.' and (not visited[0][i]):
		dfs(g, (0, i), visited)
	if g[n - 1][i] == '.' and (not visited[-1][i]):
		dfs(g, (n - 1, i), visited)
for i in range(1, n - 1):
	if g[i][0] == '.' and (not visited[i][0]):
		dfs(g, (i, 0), visited)
	if g[i][m - 1] == '.' and (not visited[i][m - 1]):
		dfs(g, (i, m - 1), visited)
component = 0
for i in range(1, n - 1):
	for j in range(1, m - 1):
		if g[i][j] == '.' and (not visited[i][j]):
			dfs_(g, (i, j), visited, component)
			component += 1
l = sorted(d.items(), key=lambda x: len(x[1]))
i = 0
count = 0
while component > k:
	component -= 1
	count += len(l[i][1])
	for u in l[i][1]:
		g[u[0]][u[1]] = '*'
	i += 1
print(count)
for i in range(n):
	print(''.join(g[i]))


import collections
import functools
import math
import sys

def In():
	return map(int, sys.stdin.readline().split())
input = sys.stdin.readline
import functools
import math
import sys

def In():
	return map(int, sys.stdin.readline().split())
input = sys.stdin.readline
from copy import deepcopy

def lakes():

	def add(x, y):
		if -1 < x < rows and -1 < y < cols:
			if l[x][y]:
				todo.append((x, y))
	(rows, cols, need) = In()
	l = [[True if i == '.' else False for i in input().rstrip()] for _ in range(rows)]
	take = []
	ansl = deepcopy(l)
	for i in range(rows):
		for i1 in range(cols):
			if l[i][i1]:
				todo = [(i, i1)]
				c = 0
				his = []
				f = False
				while todo:
					(x, y) = todo.pop()
					if x == 0 or y == 0 or x == rows - 1 or (y == cols - 1):
						f = 1
					if not l[x][y]:
						continue
					his.append((x, y))
					l[x][y] = False
					c += 1
					add(x + 1, y)
					add(x - 1, y)
					add(x, y + 1)
					add(x, y - 1)
				if not f:
					take.append([c, his])
	take.sort(key=lambda x: x[0])
	ans = 0
	nowlake = len(take)
	i = 0
	while need != nowlake:
		ans += take[i][0]
		for (x, y) in take[i][1]:
			ansl[x][y] = False
		nowlake -= 1
		i += 1
	print(ans)
	for i in ansl:
		for i1 in i:
			print('*' if not i1 else '.', end='')
		print()
lakes()


(n, m, k) = (int(x) for x in input().split())
Map = []
lakesizes = [0]
lakemembers = [0]
for i in range(n):
	Map.append([x for x in input()])
stack = [(x, y, None) for x in range(1, m - 1) for y in range(1, n - 1)] + [(0, y, None) for y in range(n)] + [(m - 1, y, None) for y in range(n)] + [(x, 0, None) for x in range(1, m - 1)] + [(x, n - 1, None) for x in range(1, m - 1)]
lakenumber = [[None] * m for y in range(n)]
for y in range(n):
	for x in range(m):
		if Map[y][x] == '.':
			lakenumber[y][x] = -1
while stack:
	(x, y, current) = stack.pop()
	if lakenumber[y][x] is not None and lakenumber[y][x] < 0:
		if current is None:
			if x in [0, m - 1] or y in [0, n - 1]:
				current = 0
			else:
				current = len(lakesizes)
				lakesizes.append(0)
				lakemembers.append([])
		lakenumber[y][x] = current
		lakesizes[current] += 1
		if current > 0:
			lakemembers[current].append((x, y))
		for (xo, yo) in [(x, y + 1), (x, y - 1), (x + 1, y), (x - 1, y)]:
			if 0 <= yo < n and 0 <= xo < m:
				stack.append((xo, yo, current))
ordlakes = [(lakesizes[i], i) for i in range(1, len(lakesizes))]
ordlakes.sort()
totalsize = 0
for i in range(len(ordlakes) - k):
	(size, ind) = ordlakes[i]
	totalsize += size
	for (x, y) in lakemembers[ind]:
		Map[y][x] = '*'
print(totalsize)
for i in range(n):
	print(''.join(Map[i]))


dr = [0, 0, 1, -1]
dc = [1, -1, 0, 0]
visited = [[False] * 51 for _ in range(51)]
table = []
lakes = []

def DFS(sr, sc):
	s = [(sr, sc)]
	visited[sr][sc] = True
	isOcean = False
	temp = []
	while len(s):
		(ur, uc) = s.pop()
		temp.append((ur, uc))
		if ur == 0 or uc == 0 or ur == n - 1 or (uc == m - 1):
			isOcean = True
		for i in range(4):
			r = ur + dr[i]
			c = uc + dc[i]
			if r in range(n) and c in range(m) and (table[r][c] == '.') and (not visited[r][c]):
				visited[r][c] = True
				s.append((r, c))
	if not isOcean:
		lakes.append(temp)
(n, m, k) = map(int, input().split())
for _ in range(n):
	table.append(list(input()))
for i in range(n):
	for j in range(m):
		if not visited[i][j] and table[i][j] == '.':
			DFS(i, j)
lakes.sort(key=lambda lake: len(lake))
sum_cell = 0
for i in range(len(lakes) - k):
	sum_cell += len(lakes[i])
	for (r, c) in lakes[i]:
		table[r][c] = '*'
print(sum_cell)
for i in range(n):
	print(''.join(table[i]))


from typing import List, Tuple

def solve(n: int, m: int, k: int, chart: List[List[str]]):
	visited = [[0] * m for _ in range(n)]

	def dfs(x: int, y: int) -> List[Tuple[int, int]]:
		stack = [(x, y)]
		component = set([(x, y)])
		is_ocean = False
		while stack:
			(a, b) = stack.pop()
			visited[a][b] = 1
			if a == 0 or a == n - 1 or b == 0 or (b == m - 1):
				is_ocean = True
			for (ao, bo) in [(a, b + 1), (a, b - 1), (a + 1, b), (a - 1, b)]:
				if 0 <= ao < n and 0 <= bo < m:
					if not visited[ao][bo] and chart[ao][bo] == '.':
						stack.append((ao, bo))
						component.add((ao, bo))
		if not is_ocean:
			return list(component)
	lakes = []
	for i in range(1, n - 1):
		for j in range(1, m - 1):
			if not visited[i][j] and chart[i][j] == '.':
				lake = dfs(i, j)
				if lake:
					lakes.append(lake)
	changes = 0
	for component in sorted(lakes, key=len)[:len(lakes) - k]:
		for (x, y) in component:
			changes += 1
			chart[x][y] = '*'
	return (changes, chart)
(n, m, k) = list(map(int, input().split()))
chart = [list(input()) for _ in range(n)]
(changes, new_chart) = solve(n, m, k, chart)
print(changes)
for line in new_chart:
	print(''.join(line))


def find_neigh(t, x, y):
	return [(i, j) for (i, j) in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1), (x, y + 1)] if t[i][j] == '.']

def lake(table):
	return [(i, j) for i in range(0, len(table) - 1) for j in range(0, len(table[i]) - 1) if table[i][j] == '.']
stack = set()

def the_lake(table, x, y):
	queue = [(x, y)]
	counted = set()
	counted.add((x, y))
	stack.add((x, y))
	while queue:
		start = queue.pop()
		for (i, j) in find_neigh(table, *start):
			if (i, j) in counted:
				continue
			stack.add((i, j))
			queue.append((i, j))
			counted.add((i, j))
	for (i, j) in counted:
		if table[i + 1][j] == '0' or table[i - 1][j] == '0':
			return
		if table[i][j + 1] == '0' or table[i][j - 1] == '0':
			return
	return counted

def island(table, n, m, k):
	lakes = []
	count = 0
	for (i, j) in lake(table):
		if (i, j) in stack:
			continue
		tlake = the_lake(table, i, j)
		if tlake == None:
			continue
		lakes.append(tlake)
	lakes = sorted(lakes, key=len)
	for p in range(0, len(lakes) - k):
		for (i, j) in lakes[p]:
			row = list(table[i])
			row[j] = '*'
			count += 1
			table[i] = ''.join(row)
	print(count)
	for i in range(1, n + 1):
		print(table[i][1:m + 1])
(n, m, k) = input().split(' ')
carta = []
for i in range(int(n)):
	row = '0' + input() + '0'
	carta.append(row)
carta = ['0' * (int(m) + 2)] + carta + ['0' * (int(m) + 2)]
island(carta, int(n), int(m), int(k))


import sys
N_MAX = 55
n = None
m = None
k = None
a = [[] for i in range(N_MAX)]
vs = [[False] * N_MAX for i in range(N_MAX)]
dx = [1, -1, 0, 0]
dy = [0, 0, -1, 1]
MAP = [[0] * N_MAX for i in range(N_MAX)]
global count

def is_valid_cell(u, v):
	if u < 0 or v < 0 or u == n or (v == m):
		return False
	else:
		return True

def DFS(x, y, id):
	vs[x][y] = True
	global count
	global is_lake
	count += 1
	MAP[x][y] = id
	for i in range(4):
		u = x + dx[i]
		v = y + dy[i]
		if is_valid_cell(u, v):
			if a[u][v] == '*' or vs[u][v] == True:
				continue
			DFS(u, v, id)
		else:
			is_lake = False

def make_land(id):
	global ans
	for i in range(n):
		for j in range(m):
			if MAP[i][j] == id:
				a[i][j] = '*'
				ans += 1
sys.setrecursionlimit(2 ** 20)
(n, m, k) = map(int, input().split())
for i in range(n):
	line = input()
	for x in line:
		a[i].append(x)
lake = {}
global id
id = 0
for i in range(n):
	for j in range(m):
		if a[i][j] == '.' and vs[i][j] == False:
			global is_lake
			global count
			count = 0
			id += 1
			is_lake = True
			DFS(i, j, id)
			if is_lake:
				lake[id] = count
lake = dict(sorted(lake.items(), key=lambda kv: (kv[1], kv[0])))
kk = len(lake) - k
global ans
ans = 0
for i in range(kk):
	for id in lake:
		make_land(id)
		lake.pop(id)
		break
print(ans)
for i in range(n):
	for j in range(m):
		print(a[i][j], end='')
	print()


import sys
sys.setrecursionlimit(5000)
(n, m, k) = [int(x) for x in input().split()]
land = []
cc = 0
visit = [[0 for _ in range(m)] for _ in range(n)]
for i in range(n):
	land.append(list(input()))
edge = False

def DFS(i, j, c):
	global land, n, m, k, cc, visit, edge
	if i <= 0 or j <= 0 or i >= n - 1 or (j >= m - 1):
		edge = True
		return 0
	if visit[i][j] != 0:
		return 0
	if land[i][j] == '*':
		return 0
	visit[i][j] = 1
	cc += 1
	if land[i + 1][j] == '.':
		DFS(i + 1, j, c + 1)
	if land[i - 1][j] == '.':
		DFS(i - 1, j, c + 1)
	if land[i][j + 1] == '.':
		DFS(i, j + 1, c + 1)
	if land[i][j - 1] == '.':
		DFS(i, j - 1, c + 1)

def DFS2(i, j):
	global land, n, m, k, cc
	if i < 0 or j < 0 or i >= n or (j >= m):
		return 0
	if land[i][j] != '.':
		return 0
	land[i][j] = '*'
	DFS2(i + 1, j)
	DFS2(i - 1, j)
	DFS2(i, j + 1)
	DFS2(i, j - 1)
	return 0
ccc = []
pos = []
for i in range(n):
	for j in range(m):
		cc = 0
		edge = False
		if visit[i][j] == 0:
			DFS(i, j, 0)
			if edge is True:
				continue
			if cc > 0:
				ccc.append([cc, i, j])
ccc.sort()
red = len(ccc) - k
if red == 0:
	print(0)
	for i in range(n):
		print(''.join(land[i]))
	exit()
red_list = ccc[0:red]
p = [x[0] for x in red_list]
print(sum(p))
for i in range(len(red_list)):
	DFS2(red_list[i][1], red_list[i][2])
for i in range(n):
	print(''.join(land[i]))


(n, m, k) = map(int, input().split())
arr = []
for i in range(n):
	s = list(input())
	arr.append(s)

def dfs(arr, x, y, visited):
	st = []
	st.append((x, y))
	visited[x][y] = True
	size = 1
	neighbors = [(0, 1), (0, -1), (-1, 0), (1, 0)]
	isOcean = False
	while len(st) != 0:
		(x, y) = st.pop()
		if x == 0 or x == len(arr) - 1 or y == 0 or (y == len(arr[0]) - 1):
			isOcean = True
		for (di, dj) in neighbors:
			i = di + x
			j = dj + y
			if 0 <= i < len(arr) and 0 <= j < len(arr[0]) and (not visited[i][j]) and (arr[i][j] == '.'):
				visited[i][j] = True
				st.append((i, j))
				size += 1
	return 0 if isOcean == True else size
visited = [[False] * m for i in range(n)]
lakes = []
for i in range(n):
	for j in range(m):
		if arr[i][j] == '.' and (not visited[i][j]):
			size = dfs(arr, i, j, visited)
			if size > 0:
				lakes.append((size, i, j))
lakes.sort(key=lambda x: x[0])
minNumberOfCells = 0
sources = []
for i in range(0, len(lakes) - k, 1):
	lake = lakes[i]
	minNumberOfCells += lake[0]
	sources.append((lake[1], lake[2]))

def dfsWithModification(arr, x, y):
	st = []
	st.append((x, y))
	arr[x][y] = '*'
	neighbors = [(0, 1), (0, -1), (-1, 0), (1, 0)]
	while len(st) != 0:
		(x, y) = st.pop()
		for (di, dj) in neighbors:
			i = di + x
			j = dj + y
			if arr[i][j] == '.':
				st.append((i, j))
				arr[i][j] = '*'
for source in sources:
	dfsWithModification(arr, source[0], source[1])
print(minNumberOfCells)
for i in range(n):
	print(''.join(arr[i]))


class Lake:

	def __init__(self, i, j, lakes):
		self.i = i
		self.j = j
		self.lakes = lakes

def DFS(s, visited, r, c):
	stack = []
	stack.append(s)
	visited[s[0]][s[1]] = True
	px = [-1, 1, 0, 0]
	py = [0, 0, 1, -1]
	lake = 1
	while len(stack) > 0:
		value = stack.pop()
		for i in range(len(px)):
			new_pos = [value[0] + px[i], value[1] + py[i]]
			if new_pos[0] >= 0 and new_pos[0] < r and (new_pos[1] >= 0) and (new_pos[1] < c):
				if visited[new_pos[0]][new_pos[1]] == False:
					visited[new_pos[0]][new_pos[1]] = True
					stack.append(new_pos)
					lake += 1
	return lake
(r, c, k) = map(int, input().split())
visited = [[] for i in range(r)]
visited2 = [[] for i in range(r)]
for i in range(r):
	line = input().strip()
	for j in line:
		if j == '*':
			visited[i].append(True)
			visited2[i].append(True)
		else:
			visited[i].append(False)
			visited2[i].append(False)
for i in range(r):
	if visited[i][0] == False:
		DFS([i, 0], visited, r, c)
	if visited[i][c - 1] == False:
		DFS([i, c - 1], visited, r, c)
for i in range(c):
	if visited[0][i] == False:
		DFS([0, i], visited, r, c)
	if visited[r - 1][i] == False:
		DFS([r - 1, i], visited, r, c)
lakes = []
for i in range(r):
	for j in range(c):
		if visited[i][j] == False:
			obj = Lake(i, j, DFS([i, j], visited, r, c))
			lakes.append(obj)
lakes.sort(key=lambda x: x.lakes)
cells = 0
for i in range(len(lakes) - k):
	DFS([lakes[i].i, lakes[i].j], visited2, r, c)
	cells += lakes[i].lakes
print(cells)
for i in range(r):
	for j in range(c):
		if visited2[i][j] == True:
			print('*', end='')
		else:
			print('.', end='')
	print()


import sys
sys.setrecursionlimit(10000000)
MAX = 55
(lake, ans) = ([], [])
visited = [[False for j in range(MAX)] for i in range(MAX)]
(n, m) = (None, None)
flag = 0
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

class pos:

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

def inBoard(x, y):
	global m, n
	return x > -1 and x < m and (y > -1) and (y < n)

def Ocean(x, y):
	global m, n, a
	return a[x][y] == '.' and (x == 0 or x == m - 1 or y == 0 or (y == n - 1))

def DFS(x, y):
	global lake, visited, flag, a
	visited[x][y] = True
	if Ocean(x, y):
		flag = 1
	else:
		lake.append(pos(x, y))
	for i in range(4):
		tox = dx[i] + x
		toy = dy[i] + y
		if visited[tox][toy] == False and inBoard(tox, toy) and (a[tox][toy] == '.'):
			DFS(tox, toy)
a = []
(m, n, k) = map(int, input().split())
for i in range(m):
	a.append(input())
newlake = [[0 for i in range(n)] for j in range(m)]
for i in range(m):
	for j in range(n):
		if a[i][j] == '.':
			newlake[i][j] = 1
for i in range(m):
	for j in range(n):
		if visited[i][j] == False and a[i][j] == '.':
			lake = []
			flag = 0
			DFS(i, j)
			if len(lake) > 0 and flag != 1:
				ans.append(lake)
sum = 0
ans.sort(key=len)
for i in range(len(ans) - k):
	for j in range(len(ans[i])):
		sum += 1
		newlake[ans[i][j].x][ans[i][j].y] = 0
print(sum)
for i in range(m):
	for j in range(n):
		if newlake[i][j] == 0:
			print('*', end='')
		else:
			print('.', end='')
	print()


MAX = 55
visited = [[False] * MAX for i in range(MAX)]
maze = [None] * MAX
lake = []
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]

def DFS(i, j):
	temp = []
	s = [(i, j)]
	visited[i][j] = True
	isocean = False
	while len(s):
		(x, y) = s.pop()
		temp.append((x, y))
		if x == 0 or y == 0 or x == n - 1 or (y == m - 1):
			isocean = True
		for l in range(4):
			nx = x + dx[l]
			ny = y + dy[l]
			if nx in range(n) and ny in range(m) and (not visited[nx][ny]) and (maze[nx][ny] == '.'):
				visited[nx][ny] = True
				s.append((nx, ny))
	if not isocean:
		lake.append(temp)
(n, m, k) = map(int, input().split())
for i in range(n):
	maze[i] = list(input())
for i in range(n):
	for j in range(m):
		if not visited[i][j] and maze[i][j] == '.':
			DFS(i, j)
lake.sort(key=lambda hi: len(hi))
cnt = 0
for i in range(len(lake) - k):
	cnt += len(lake[i])
	for (r, c) in lake[i]:
		maze[r][c] = '*'
print(cnt)
for i in range(n):
	print(''.join(maze[i]))


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

def isSafe(x, y, map, visited):
	if 0 <= x < len(map) and 0 <= y < len(map[0]) and (map[x][y] == '.') and (visited[x][y] is False):
		return True
	return False

def isValid(lake):
	for cell in lake:
		x = cell[0]
		y = cell[1]
		if x == 0 or y == 0 or x == len(map) - 1 or (y == len(map[0]) - 1):
			return False
	return True
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def findLakes(map):
	lakes = list()
	visited = [[False] * len(map[0]) for i in map]
	stack = list()
	i = 0
	while i < len(map):
		j = 0
		while j < len(map[0]):
			if map[i][j] == '.' and visited[i][j] is False:
				lake = list()
				lake.append([i, j])
				visited[i][j] = True
				stack.append([i, j])
				while len(stack) > 0:
					point = stack[-1]
					stack.pop()
					x = point[0]
					y = point[1]
					index = 0
					while index < len(dx):
						if isSafe(x + dx[index], y + dy[index], map, visited):
							visited[x + dx[index]][y + dy[index]] = True
							stack.append([x + dx[index], y + dy[index]])
							lake.append([x + dx[index], y + dy[index]])
						index += 1
				if isValid(lake):
					lakes.append(lake)
			j += 1
		i += 1
	return lakes

def fillUpLake(map, lake, the_lakes):
	filled = 0
	for cell in lake:
		x = cell[0]
		y = cell[1]
		map[x] = map[x][:y] + '*' + map[x][y + 1:]
		filled += 1
	the_lakes.remove(lake)
	return filled

def printTheMap(map):
	for row in map:
		print(row)
the_lakes = findLakes(map)
if len(the_lakes) == k:
	print(str(0))
	printTheMap(map)
else:
	the_lakes.sort(key=len)
	count = 0
	while len(the_lakes) != k:
		count += fillUpLake(map, the_lakes[0], the_lakes)
	print(count)
	printTheMap(map)


(n, m, k) = map(int, input().split(' '))
dx = [0, 0, 1, -1]
dy = [1, -1, 0, 0]
lakes = []
visited = [[False] * 51 for _ in range(51)]
mp = []
for _ in range(n):
	mp.append(list(input()))

def DFS(x, y):
	s = [(x, y)]
	visited[x][y] = True
	isOcean = False
	temp = []
	while len(s):
		(u, v) = s.pop()
		if u == 0 or v == 0 or u == n - 1 or (v == m - 1):
			isOcean = True
		temp.append((u, v))
		for i in range(4):
			xx = u + dx[i]
			yy = v + dy[i]
			if xx in range(n) and yy in range(m) and (mp[xx][yy] == '.') and (not visited[xx][yy]):
				visited[xx][yy] = True
				s.append((xx, yy))
	if not isOcean:
		lakes.append(temp)
for i in range(n):
	for j in range(m):
		if not visited[i][j] and mp[i][j] == '.':
			DFS(i, j)
lakes.sort(key=len)
sum_cell = 0
for i in range(len(lakes) - k):
	sum_cell += len(lakes[i])
	for (x, y) in lakes[i]:
		mp[x][y] = '*'
print(sum_cell)
for i in range(n):
	print(''.join(mp[i]))


(n, m, k) = map(int, input().split())
g = [[*input()] for _ in range(n)]
visited = [[False] * m for _ in range(n)]
to_destroy = []
import sys

def dfs(i, j):
	sys.setrecursionlimit(sys.getrecursionlimit() + 1)
	if i < 0 or j < 0 or i > n - 1 or (j > m - 1):
		return float('inf')
	if visited[i][j] or g[i][j] == '*':
		return 0
	visited[i][j] = 1
	return 1 + dfs(i + 1, j) + dfs(i - 1, j) + dfs(i, j + 1) + dfs(i, j - 1)

def solve(i, j):
	sys.setrecursionlimit(sys.getrecursionlimit() + 1)
	if visited[i][j] == 0 and g[i][j] == '.':
		res = dfs(i, j)
		if res < float('inf'):
			to_destroy.append((i, j, res))
for i in range(n):
	for j in range(m):
		solve(i, j)
to_destroy.sort(key=lambda x: -x[2])
ans = 0

def destory(i, j):
	if g[i][j] == '*':
		return 0
	g[i][j] = '*'
	return 1 + destory(i + 1, j) + destory(i - 1, j) + destory(i, j - 1) + destory(i, j + 1)
while len(to_destroy) > k:
	ans += destory(to_destroy[-1][0], to_destroy[-1][1])
	del to_destroy[-1]
print(ans)
for i in g:
	print(''.join(i))


(n, m, k) = map(int, input().split())
mat = [list(input()) for _ in range(n)]
vis = [[0 for _ in range(m)] for _ in range(n)]
comp = []
d = [(0, 1), (1, 0), (-1, 0), (0, -1)]
for i in range(n):
	for j in range(m):
		if mat[i][j] == '*':
			continue
		if vis[i][j] == 1:
			continue
		c = [(i, j)]
		cur = 0
		while cur < len(c):
			v = c[cur]
			cur += 1
			vis[v[0]][v[1]] = 1
			for dk in d:
				vk = (v[0] + dk[0], v[1] + dk[1])
				if 0 <= vk[0] <= n - 1 and 0 <= vk[1] <= m - 1:
					if vis[vk[0]][vk[1]] == 0 and mat[vk[0]][vk[1]] == '.':
						c.append(vk)
						vis[vk[0]][vk[1]] = 1
		if any((v[0] == 0 or v[0] == n - 1 or v[1] == 0 or (v[1] == m - 1) for v in c)):
			continue
		comp.append(c)
comp.sort(key=len)
ans = 0
for i in range(len(comp) - k):
	for v in comp[i]:
		mat[v[0]][v[1]] = '*'
		ans += 1
print(ans)
for l in mat:
	print(''.join(l))


def main():

	def dfs(x, y):
		nonlocal inner
		if d[x, y] == '.':
			(d[x, y], s) = ('*', 1)
			for uv in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
				try:
					s += dfs(*uv)
				except KeyError:
					inner = False
			return s
		return 0
	(n, m, k) = list(map(int, input().split()))
	d = {(x, y): c for y in range(n) for (x, c) in enumerate(input())}
	(sav, lakes) = (d.copy(), [])
	for y in range(n):
		for x in range(m):
			inner = True
			s = dfs(x, y)
			if s and inner:
				lakes.append((s, x, y))
	(d, res) = (sav, 0)
	for (_, x, y) in sorted(lakes)[:len(lakes) - k]:
		res += dfs(x, y)
	print(res)
	for y in range(n):
		print(''.join((d[x, y] for x in range(m))))

def __starting_point():
	from sys import setrecursionlimit
	setrecursionlimit(6000)
	main()
__starting_point()


def isolation(lake, Matrix_Lake, row, column):
	r = lake.x
	c = lake.y
	if r - 1 == 0 and Matrix_Lake[r - 1][c] == '.':
		return False
	if r + 1 == row - 1 and Matrix_Lake[r + 1][c] == '.':
		return False
	if c - 1 == 0 and Matrix_Lake[r][c - 1] == '.':
		return False
	if c + 1 == column - 1 and Matrix_Lake[r][c + 1] == '.':
		return False
	return True

def cover_lake(Matrix_Lake, list_lake, lake_cover):
	list_lake.sort()
	count_cover = 0
	for i in range(lake_cover):
		for lake_child in list_lake[i].get_list_brother_lake():
			Matrix_Lake[lake_child.x][lake_child.y] = '*'
			count_cover += 1
	print(count_cover)
	return Matrix_Lake

class Lake:

	def __init__(self, x, y):
		self.x = x
		self.y = y
		self.listBrotherLakes = []

	def __lt__(self, other):
		return len(self.listBrotherLakes) < len(other.listBrotherLakes)

	def get_list_brother_lake(self):
		return self.listBrotherLakes

	def set_list_brother_lake(self, lake):
		return self.listBrotherLakes.append(lake)

def get_side_by_side_lake(lake, row, column, matrix, visistedMatrix):
	listRelated = []
	r = lake.x
	c = lake.y
	if r - 1 >= 1 and matrix[r - 1][c] == '.' and (visistedMatrix[r - 1][c] == False):
		listRelated.append(Lake(r - 1, c))
	if r + 1 < row - 1 and matrix[r + 1][c] == '.' and (visistedMatrix[r + 1][c] == False):
		listRelated.append(Lake(r + 1, c))
	if c - 1 >= 1 and matrix[r][c - 1] == '.' and (visistedMatrix[r][c - 1] == False):
		listRelated.append(Lake(r, c - 1))
	if c + 1 < column - 1 and matrix[r][c + 1] == '.' and (visistedMatrix[r][c + 1] == False):
		listRelated.append(Lake(r, c + 1))
	return listRelated

def createMVisted(row, column):
	result = []
	for i in range(row):
		temp = []
		for j in range(column):
			temp.append(False)
		result.append(temp)
	return result

def DFS_Lake(lake, Matrix_Lake, Visisted_Lake, row, column):
	isLake = True
	s = [lake]
	Visisted_Lake[lake.x][lake.y] = True
	while len(s):
		lake_seed = s.pop()
		list_lake_side_by_side = get_side_by_side_lake(lake_seed, row, column, Matrix_Lake, Visisted_Lake)
		for sibling in list_lake_side_by_side:
			if isolation(sibling, Matrix_Lake, row, column) == False:
				isLake = False
			if Visisted_Lake[sibling.x][sibling.y] == False:
				Visisted_Lake[sibling.x][sibling.y] = True
				lake.set_list_brother_lake(sibling)
				s.append(sibling)
	if not isLake:
		return None
	return lake
(r, c, k) = map(int, input().split())
Matrix_Lake = []
for _ in range(r):
	row_lake = list(input())
	Matrix_Lake.append(row_lake)
Visisted_Lake = createMVisted(r, c)
list_lake = []
for i in range(1, r - 1):
	for j in range(1, c - 1):
		if Matrix_Lake[i][j] == '.' and Visisted_Lake[i][j] == False and (isolation(Lake(i, j), Matrix_Lake, r, c) == True):
			lake = Lake(i, j)
			lake.set_list_brother_lake(lake)
			dfs_lake = DFS_Lake(lake, Matrix_Lake, Visisted_Lake, r, c)
			if dfs_lake != None:
				list_lake.append(dfs_lake)
lake_cover = len(list_lake) - k
Matrix_Lake = cover_lake(Matrix_Lake, list_lake, lake_cover)
for i in range(r):
	for j in range(c):
		print(Matrix_Lake[i][j], end='')
	print()


X = [-1, 1, 0, 0]
Y = [0, 0, -1, 1]
(n, m, k) = map(int, input().split())
graph = [[] for i in range(n)]
for i in range(n):
	_str = input()
	for j in range(m):
		graph[i].append(_str[j])
visited = [[False for i in range(m)] for j in range(n)]
path = [[0 for i in range(m)] for j in range(n)]

def DFS(x, y, isLakes=True):
	stack = []
	s = (x, y)
	if x == 0 or y == 0 or x == n - 1 or (y == m - 1):
		isLakes = False
	stack.append(s)
	visited[x][y] = True
	wide = 1
	while len(stack) > 0:
		(a, b) = stack.pop()
		for i in range(4):
			if a + X[i] >= 0 and a + X[i] < n and (b + Y[i] >= 0) and (b + Y[i] < m) and (graph[a + X[i]][b + Y[i]] == '.') and (not visited[a + X[i]][b + Y[i]]):
				if a + X[i] == 0 or a + X[i] == n - 1 or b + Y[i] == 0 or (b + Y[i] == m - 1):
					isLakes = False
				o = (a + X[i], b + Y[i])
				stack.append(o)
				visited[a + X[i]][b + Y[i]] = True
				wide += 1
	return (wide, isLakes)
Lakes = []
for i in range(n):
	for j in range(m):
		if graph[i][j] == '.' and (not visited[i][j]):
			(wide, isLakes) = DFS(i, j)
			if isLakes:
				Lake = {}
				Lake['wide'] = wide
				Lake['pos'] = (i, j)
				Lakes.append(Lake)
Lakes.sort(key=lambda x: x['wide'])
i = 0
total = 0

def transformed(x, y):
	stack = []
	s = (x, y)
	graph[x][y] = '*'
	stack.append(s)
	while len(stack) != 0:
		(a, b) = stack.pop()
		for i in range(4):
			if a + X[i] >= 0 and a + X[i] < n and (b + Y[i] >= 0) and (b + Y[i] < m) and (graph[a + X[i]][b + Y[i]] == '.') and visited[a + X[i]][b + Y[i]]:
				o = (a + X[i], b + Y[i])
				stack.append(o)
				graph[a + X[i]][b + Y[i]] = '*'
while len(Lakes) > k:
	u = Lakes.pop(0)
	(x, y) = u['pos']
	total += u['wide']
	transformed(x, y)
print(total)
for i in range(n):
	for j in range(m):
		print(graph[i][j], end='')
	print()


import sys, math

def bfs(a):
	Q = [a]
	ctr = 0
	used = [[0] * m for i in range(n)]
	while ctr < len(Q):
		h = Q[ctr]
		ctr += 1
		z[h[0]][h[1]] = 'o'
		if h[0] - 1 >= 0 and z[h[0] - 1][h[1]] == '.' and (not used[h[0] - 1][h[1]]):
			Q.append([h[0] - 1, h[1]])
			used[h[0] - 1][h[1]] = 1
		if h[0] + 1 < n and z[h[0] + 1][h[1]] == '.' and (not used[h[0] + 1][h[1]]):
			Q.append([h[0] + 1, h[1]])
			used[h[0] + 1][h[1]] = 1
		if h[1] - 1 >= 0 and z[h[0]][h[1] - 1] == '.' and (not used[h[0]][h[1] - 1]):
			Q.append([h[0], h[1] - 1])
			used[h[0]][h[1] - 1] = 1
		if h[1] + 1 < m and z[h[0]][h[1] + 1] == '.' and (not used[h[0]][h[1] + 1]):
			Q.append([h[0], h[1] + 1])
			used[h[0]][h[1] + 1] = 1

def bfs1(a, b):
	Q = [a]
	ctr = 0
	while ctr < len(Q):
		h = Q[ctr]
		ctr += 1
		if z[h[0]][h[1]] == b:
			continue
		z[h[0]][h[1]] = b
		if h[0] - 1 >= 0 and z[h[0] - 1][h[1]] == '.':
			Q.append([h[0] - 1, h[1]])
		if h[0] + 1 < n and z[h[0] + 1][h[1]] == '.':
			Q.append([h[0] + 1, h[1]])
		if h[1] - 1 >= 0 and z[h[0]][h[1] - 1] == '.':
			Q.append([h[0], h[1] - 1])
		if h[1] + 1 < m and z[h[0]][h[1] + 1] == '.':
			Q.append([h[0], h[1] + 1])
	ctr = 0
	for i in range(n):
		for j in range(m):
			if z[i][j] == b:
				ctr += 1
	return ctr
(n, m, k) = map(int, input().split())
z = [list(input()) for i in range(n)]
for i in range(n):
	if z[i][0] == '.':
		bfs([i, 0])
	if z[i][m - 1] == '.':
		bfs([i, m - 1])
for i in range(m):
	if z[0][i] == '.':
		bfs([0, i])
	if z[n - 1][i] == '.':
		bfs([n - 1, i])
ctr = 0
z1 = []
for i in range(n):
	for j in range(m):
		if z[i][j] == '.':
			z1.append([bfs1([i, j], ctr), ctr])
			ctr += 1
z1.sort()
dif = ctr - k
ans = 0
for i in range(dif):
	u = z1[i][1]
	ans += z1[i][0]
	for j in range(n):
		for k in range(m):
			if z[j][k] == u:
				z[j][k] = '*'
for i in range(n):
	for j in range(m):
		if z[i][j] != '*' and z[i][j] != '.':
			z[i][j] = '.'
print(ans)
for i in range(n):
	print(*z[i], sep='')


def ex(i, j, n, m):
	if i < n and i >= 0 and (j < m) and (j >= 0):
		return True
	else:
		return False
(n, m, k) = map(int, input().split())
A = []
for i in range(n):
	A.append(list(input()))
B = [[False for i in range(m)] for j in range(n)]
L = []
for i in range(n):
	for j in range(m):
		if not B[i][j] and A[i][j] == '.':
			sides = False
			Oz = [[i, j]]
			count = 1
			Q = [[i, j]]
			B[i][j] = True
			while len(Q) > 0:
				(x, y) = (Q[0][0], Q[0][1])
				if x == 0 or x == n - 1 or y == 0 or (y == m - 1):
					sides = True
				if ex(x - 1, y, n, m) and (not B[x - 1][y]) and (A[x - 1][y] == '.'):
					Q.append([x - 1, y])
					B[x - 1][y] = True
					count += 1
					Oz.append([x - 1, y])
				if ex(x + 1, y, n, m) and (not B[x + 1][y]) and (A[x + 1][y] == '.'):
					Q.append([x + 1, y])
					B[x + 1][y] = True
					count += 1
					Oz.append([x + 1, y])
				if ex(x, y - 1, n, m) and (not B[x][y - 1]) and (A[x][y - 1] == '.'):
					Q.append([x, y - 1])
					B[x][y - 1] = True
					count += 1
					Oz.append([x, y - 1])
				if ex(x, y + 1, n, m) and (not B[x][y + 1]) and (A[x][y + 1] == '.'):
					Q.append([x, y + 1])
					B[x][y + 1] = True
					count += 1
					Oz.append([x, y + 1])
				Q.pop(0)
			if not sides:
				L.append([count, Oz])
L.sort()
s = len(L)
ans = 0
for i in range(s - k):
	ans += L[i][0]
	for j in L[i][1]:
		A[j[0]][j[1]] = '*'
print(ans)
for i in range(n):
	for j in range(m):
		print(A[i][j], end='')
	print()


class DSU:

	def __init__(self, n):
		self.parents = [-1] * n
		self.size = [0] * n

	def make(self, v):
		if self.parents[v] != -1:
			return
		self.parents[v] = v
		self.size[v] = 1

	def find(self, v):
		if self.parents[v] in (v, -1):
			return self.parents[v]
		self.parents[v] = self.find(self.parents[v])
		return self.parents[v]

	def join(self, v, u):
		v = self.find(v)
		u = self.find(u)
		if v == u or -1 in (u, v):
			return
		if self.size[v] < self.size[u]:
			(v, u) = (u, v)
		self.parents[u] = v
		self.size[v] += self.size[u]

def get_cart2line(m):
	return lambda x, y: x * m + y

def main():
	(n, m, k) = map(int, input().split())
	g = [list(input()) for _ in range(n)]
	ocean = 0
	dsu = DSU(n * m)
	dsu.make(ocean)
	line = get_cart2line(m)
	for i in range(n):
		(a, b) = (line(i, 0), line(i, m - 1))
		dsu.make(a)
		dsu.make(b)
		dsu.join(ocean, a)
		dsu.join(ocean, b)
	for i in range(m):
		(a, b) = (line(0, i), line(n - 1, i))
		dsu.make(a)
		dsu.make(b)
		dsu.join(ocean, a)
		dsu.join(ocean, b)
	for i in range(n):
		for j in range(m):
			if g[i][j] == '.':
				dsu.make(line(i, j))
				if j > 0:
					if g[i][j - 1] == '.':
						dsu.join(line(i, j - 1), line(i, j))
				if i > 0:
					if g[i - 1][j] == '.':
						dsu.join(line(i - 1, j), line(i, j))
	s = set()
	for i in range(n):
		for j in range(m):
			tmp = dsu.find(line(i, j))
			if tmp not in (-1, dsu.find(ocean)):
				s.add(tmp)
	s = [(dsu.find(i), dsu.size[dsu.find(i)]) for i in s]
	s.sort(key=lambda x: x[1])
	if len(s) == k:
		print(0)
		print(*(''.join(r) for r in g), sep='\n')
		return
	s = s[:len(s) - k]
	ans = sum((x[1] for x in s))
	s = {x[0] for x in s}
	for i in range(n):
		for j in range(m):
			if dsu.find(line(i, j)) in s:
				g[i][j] = '*'
	print(ans)
	print(*(''.join(r) for r in g), sep='\n')
main()


from sys import stdin
input = lambda : stdin.readline().strip()
from math import ceil, sqrt, factorial, gcd
from collections import deque

def travel(x, y):
	stack = [[x, y]]
	flag = 0
	while stack:
		x = stack.pop()
		if visited[x[0]][x[1]] == 0:
			lakes[-1].append(x)
			visited[x[0]][x[1]] = 1
		else:
			continue
		if x[0] == 0 or x[0] == n - 1 or x[1] == 0 or (x[1] == m - 1):
			flag = 1
		try:
			if l[x[0]][x[1] + 1] == '.' and visited[x[0]][x[1] + 1] == 0:
				stack.append([x[0], x[1] + 1])
		except:
			pass
		try:
			if l[x[0]][x[1] - 1] == '.' and visited[x[0]][x[1] - 1] == 0:
				stack.append([x[0], x[1] - 1])
		except:
			pass
		try:
			if l[x[0] + 1][x[1]] == '.' and visited[x[0] + 1][x[1]] == 0:
				stack.append([x[0] + 1, x[1]])
		except:
			pass
		try:
			if l[x[0] - 1][x[1]] == '.' and visited[x[0] - 1][x[1]] == 0:
				stack.append([x[0] - 1, x[1]])
		except:
			pass
	if flag == 1:
		lakes.pop()
(n, m, k) = map(int, input().split())
visited = [[0 for i in range(m)] for i in range(n)]
l = []
for i in range(n):
	s = input()
	l.append(list(s))
lakes = []
for i in range(n):
	for j in range(m):
		if l[i][j] == '.' and visited[i][j] == 0:
			lakes.append([])
			travel(i, j)
z = []
for i in range(len(lakes)):
	z.append([len(lakes[i]), i])
z.sort(key=lambda a: a[0])
a = 0
count = 0
for i in range(len(z) - k):
	for t in lakes[z[i][1]]:
		count += 1
		l[t[0]][t[1]] = '*'
print(count)
for i in l:
	print(''.join(i))


import sys
input = sys.stdin.readline

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):
	p = x
	while p != link[p]:
		p = link[p]
	while x != p:
		nex = link[x]
		link[x] = p
		x = nex
	return p

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, kk) = int_array()
array = [[0 for _ in range(m)] for __ in range(n)]
dick = {}
count = 0
for i in range(n):
	s = input().strip()
	for j in range(m):
		array[i][j] = s[j]
		if s[j] == '.':
			dick[i, j] = count
			count += 1
link = [i for i in range(count)]
size = [1] * (count + 1)
not_lakes = []
for i in range(n):
	for j in range(m):
		inds = []
		if array[i][j] == '.':
			if i == 0 or i == n - 1 or j == 0 or (j == m - 1):
				not_lakes.append(dick[i, j])
			if i > 0:
				if array[i - 1][j] == '.':
					inds.append(dick[i - 1, j])
			if i < n - 1:
				if array[i + 1][j] == '.':
					inds.append(dick[i + 1, j])
			if j > 0:
				if array[i][j - 1] == '.':
					inds.append(dick[i, j - 1])
			if j < m - 1:
				if array[i][j + 1] == '.':
					inds.append(dick[i, j + 1])
			this = dick[i, j]
			for k in inds:
				union(this, k, link, size)
nots = set([find(i, link) for i in not_lakes])
lakes = [find(i, link) for i in link]
final = [i for i in lakes if i not in nots]
kick = {}
for i in final:
	kick[i] = kick.get(i, 0) + 1
fset = list(set(final))
for i in range(len(fset)):
	fset[i] = (kick[fset[i]], fset[i])
fset.sort(reverse=True)
for i in range(len(fset)):
	fset[i] = fset[i][1]
tset = set()
while len(fset) > kk:
	tset.add(fset.pop())
ans = 0
fset = set(fset)
for i in range(n):
	for j in range(m):
		if array[i][j] == '.':
			parent = dick[i, j]
			parent = find(parent, link)
			if not parent in fset and parent in tset:
				array[i][j] = '*'
				ans += 1
print(ans)
for i in range(n):
	print(''.join(array[i]))


(n, m, k) = map(int, input().split())
L = [input() for i in range(n)]
Visited = [[0] * m for i in range(n)]

def Do(i, j):
	q = [[i, j]]
	ma = []
	f = False
	while q:
		d = q[0]
		Visited[d[0]][d[1]] = 1
		ma.append(d)
		if d[0] == 0 or d[1] == 0 or d[0] == n - 1 or (d[1] == m - 1):
			f = True
		if d[0] != 0:
			if Visited[d[0] - 1][d[1]] == 0 and L[d[0] - 1][d[1]] == '.':
				Visited[d[0] - 1][d[1]] = 1
				q.append([d[0] - 1, d[1]])
		if d[0] != n - 1:
			if Visited[d[0] + 1][d[1]] == 0 and L[d[0] + 1][d[1]] == '.':
				Visited[d[0] + 1][d[1]] = 1
				q.append([d[0] + 1, d[1]])
		if d[1] != 0:
			if Visited[d[0]][d[1] - 1] == 0 and L[d[0]][d[1] - 1] == '.':
				Visited[d[0]][d[1] - 1] = 1
				q.append([d[0], d[1] - 1])
		if d[1] != m - 1:
			if Visited[d[0]][d[1] + 1] == 0 and L[d[0]][d[1] + 1] == '.':
				Visited[d[0]][d[1] + 1] = 1
				q.append([d[0], d[1] + 1])
		del q[0]
	if f:
		return None
	else:
		return ma
mass = []
for i in range(n):
	for j in range(m):
		if Visited[i][j] == 0 and L[i][j] == '.':
			w = Do(i, j)
			if w != None:
				mass.append(w)
e = abs(k - len(mass))
mass = sorted(mass, key=lambda x: len(x))
k = 0
L1 = [[L[i][j] for j in range(m)] for i in range(n)]
for i in range(e):
	k += len(mass[i])
	for x in mass[i]:
		L1[x[0]][x[1]] = '*'
print(k)
for x in L1:
	print(''.join(x))


import sys
sys.setrecursionlimit(1000000000)
dx = [0, -1, 0, 1]
dy = [-1, 0, 1, 0]

class node:

	def __init__(self, x, y, value):
		self.x = x
		self.y = y
		self.value = value

def DFS(x, y):
	global cnt
	global flag
	cnt += 1
	visited[x][y] = True
	for i in range(4):
		tx = x + dx[i]
		ty = y + dy[i]
		if tx < 0 or ty < 0 or tx >= n or (ty >= m):
			flag = True
			continue
		if map[tx][ty] == '*' or visited[tx][ty]:
			continue
		DFS(tx, ty)

def DFS1(x, y):
	map[x][y] = '*'
	for i in range(4):
		tx = x + dx[i]
		ty = y + dy[i]
		if tx < 0 or ty < 0 or tx >= n or (ty >= m):
			continue
		if map[tx][ty] == '*':
			continue
		DFS1(tx, ty)
(n, m, k) = map(int, input().split())
map = []
for i in range(n):
	x = list(input())
	map.append(x)
visited = [[False for i in range(101)] for j in range(101)]
a = []
for i in range(n):
	for j in range(m):
		if not visited[i][j] and map[i][j] == '.':
			cnt = 0
			flag = False
			DFS(i, j)
			if not flag:
				a.append(node(i, j, cnt))
a = sorted(a, key=lambda node: node.value, reverse=False)
res = 0
for i in range(len(a) - k):
	res += a[i].value
	DFS1(a[i].x, a[i].y)
print(res)
for i in range(n):
	for j in range(m):
		print(map[i][j], end='')
	print()


first = list(map(int, input().split()))
row = first[0]
col = first[1]
k = first[2]
graph = []
visited = []
for i in range(row):
	graph.append(list(input()))
	visited.append([False] * col)
dr = [-1, 0, 1, 0]
dc = [0, 1, 0, -1]
dic = {}
for i in range(row):
	for j in range(col):
		if visited[i][j] is False and graph[i][j] == '.':
			isOk = 1
			tempt = 1
			curQueue = [[i, j]]
			q = [[i, j]]
			visited[i][j] = True
			while len(q) > 0:
				u = q.pop()
				uRow = u[0]
				uCol = u[1]
				if uRow == 0 or uRow == row - 1 or uCol == 0 or (uCol == col - 1):
					isOk = 0
				for z in range(4):
					try:
						if visited[uRow + dr[z]][uCol + dc[z]] is False and graph[uRow + dr[z]][uCol + dc[z]] == '.':
							visited[uRow + dr[z]][uCol + dc[z]] = True
							curQueue.append([uRow + dr[z], uCol + dc[z]])
							q.append([uRow + dr[z], uCol + dc[z]])
							tempt += 1
					except Exception as e:
						continue
			if isOk == 1:
				if tempt not in dic:
					dic.setdefault(tempt, []).append(curQueue)
				else:
					dic[tempt].append(curQueue)
count = 0
l = list(reversed(sorted(dic.keys())))
for i in l:
	q = dic[i]
	while len(q) > 0 and k != 0:
		arr = q.pop()
		k -= 1
	if k == 0:
		while len(q) > 0:
			arr = q.pop()
			for p in arr:
				r = p[0]
				c = p[1]
				graph[r][c] = '*'
				count += 1
print(count)
print('\n'.join((''.join(graph[i]) for i in range(row))))


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 10
mod = 10 ** 9 + 7

def f():
	(n, m, k) = list(map(int, input().split()))
	a = [[inf] * (m + 2)]
	g = []
	for _ in range(n):
		a.append([inf] + [_ for _ in input()] + [inf])
		g.append([False] * m)
	a.append([[inf] * (m + 2)])
	c = 0
	for i in range(1, n + 1):
		if a[i][1] == '.':
			a[i][1] = -1
		if a[i][-2] == '.':
			a[i][-2] = -1
	for j in range(1, m + 1):
		if a[1][j] == '.':
			a[1][j] = -1
		if a[-2][j] == '.':
			a[-2][j] = -1

	def ff(n1, n2):
		for i in range(1, n + 1):
			for j in range(1, m + 1):
				if a[i][j] == n1:
					a[i][j] = n2
	ff('*', inf)
	for i in range(1, n + 1):
		for j in range(1, m + 1):
			if a[i][j] == '.':
				mc = [inf]
				if a[i - 1][j] != '.':
					mc.append(a[i - 1][j])
				if a[i + 1][j] != '.':
					mc.append(a[i + 1][j])
				if a[i][j + 1] != '.':
					mc.append(a[i][j + 1])
				if a[i][j - 1] != '.':
					mc.append(a[i][j - 1])
				mm = min(mc)
				if mm < inf:
					a[i][j] = mm
					for t in [_ for _ in mc if _ < inf and _ != mm]:
						ff(t, mm)
				else:
					a[i][j] = c
					c += 1
	cnt = [0] * c
	for i in range(1, n + 1):
		for j in range(1, m + 1):
			if -1 < a[i][j] < c:
				cnt[a[i][j]] += 1
	cnt2 = [_ for _ in cnt if _ > 0]
	r = 0
	for _i in range(len(cnt2) - k):
		cnt2 = [_ for _ in cnt if _ > 0]
		mm = min(cnt2)
		ind = cnt.index(mm)
		cnt[ind] = 0
		r += mm
		for i in range(1, n + 1):
			for j in range(1, m + 1):
				if a[i][j] == ind:
					a[i][j] = '*'
	print(r)
	for i in range(1, n + 1):
		s = ''
		for j in range(1, m + 1):
			c = a[i][j]
			if c == '*':
				s += c
			elif c == inf:
				s += '*'
			else:
				s += '.'
		print(s)
f()


import sys
from time import sleep
dx = [0, 1, 0, -1]
dy = [-1, 0, 1, 0]

def dfs(i, j, n, m, a, b, l):
	b[i][j] = l
	sz = 1
	for k in range(4):
		u = i + dx[k]
		v = j + dy[k]
		if u in range(n) and v in range(m) and (a[u][v] == '.') and (b[u][v] == 0):
			sz += dfs(u, v, n, m, a, b, l)
	return sz
(n, m, k) = map(int, input().split())
a = []
for i in range(n):
	a.append(input())
sys.setrecursionlimit(50 * 50 * 50)
b = [[0 for i in range(m)] for j in range(n)]
size = [[] for i in range(n * m + 1)]
lakes = 0
for i in range(n):
	if a[i][0] == '.' and b[i][0] == 0:
		dfs(i, 0, n, m, a, b, -1)
	if a[i][m - 1] == '.' and b[i][m - 1] == 0:
		dfs(i, m - 1, n, m, a, b, -1)
for i in range(m):
	if a[0][i] == '.' and b[0][i] == 0:
		dfs(0, i, n, m, a, b, -1)
	if a[n - 1][i] == '.' and b[n - 1][i] == 0:
		dfs(n - 1, i, n, m, a, b, -1)
for i in range(n):
	for j in range(m):
		if a[i][j] == '.' and b[i][j] == 0:
			print(i, j, file=sys.stderr)
			lakes += 1
			sz = dfs(i, j, n, m, a, b, lakes)
			size[sz].append(lakes)
print(lakes, file=sys.stderr)
fill_id = []
fill_size = 0
for i in range(1, n * m + 1):
	while lakes > k and size[i] != []:
		fill_id.append(size[i][-1])
		fill_size += i
		size[i].pop()
		lakes -= 1
print(fill_size)
for i in range(n):
	for j in range(m):
		if a[i][j] == '*':
			print('*', end='')
		elif b[i][j] in fill_id:
			print('*', end='')
		else:
			print('.', end='')
	print()