#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <utility> // For std::pair
using namespace std;
// Directions for 4-way movement (Up, Down, Left, Right)
const int DR[] = {-1, 1, 0, 0};
const int DC[] = {0, 0, -1, 1};
void solve() {
// Optimization for faster I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, M, K;
if (!(cin >> N >> M >> K)) return;
vector<string> grid(N);
int total_dots = 0;
int start_r = -1, start_c = -1;
// 1. Read input and find statistics
for (int i = 0; i < N; ++i) {
cin >> grid[i];
for (int j = 0; j < M; ++j) {
if (grid[i][j] == '.') {
total_dots++;
if (start_r == -1) {
start_r = i; // Store the coordinates of the first dot found
start_c = j;
}
}
}
}
// Determine the target number of dots to keep connected
// We must turn K dots into 'X', so we keep D - K dots.
int target_keep = total_dots - K;
// Handle case where we need to keep 0 or fewer dots
if (target_keep <= 0) {
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
if (grid[i][j] == '.') {
grid[i][j] = 'X';
}
}
}
for (int i = 0; i < N; ++i) {
cout << grid[i] << "\n";
}
return;
}
// 2. BFS implementation to find the target_keep connected dots
vector<vector<bool>> visited(N, vector<bool>(M, false));
queue<pair<int, int>> q;
int dots_kept = 0;
if (start_r != -1) {
q.push({start_r, start_c});
visited[start_r][start_c] = true;
dots_kept = 1;
}
// BFS terminates when queue is empty or dots_kept reaches target_keep
while (!q.empty() && dots_kept < target_keep) {
pair<int, int> current = q.front();
q.pop();
int r = current.first;
int c = current.second;
// Explore neighbors
for (int i = 0; i < 4; ++i) {
int nr = r + DR[i];
int nc = c + DC[i];
if (nr >= 0 && nr < N && nc >= 0 && nc < M) {
if (grid[nr][nc] == '.' && !visited[nr][nc]) {
visited[nr][nc] = true;
dots_kept++;
// Enqueue the cell
q.push({nr, nc});
if (dots_kept == target_keep) {
// Found exactly the required number of connected dots. Stop immediately.
goto modification_start;
}
}
}
}
}
modification_start:
// 3. Modify the grid: Any original dot that was NOT visited by the BFS is turned into 'X'
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
if (grid[i][j] == '.' && !visited[i][j]) {
grid[i][j] = 'X';
}
}
}
// 4. Output the resulting grid
for (int i = 0; i < N; ++i) {
cout << grid[i] << "\n";
}
}
int main() {
solve();
return 0;
}