#include using namespace std; using vi = vector; struct UnionFind { vi par, rank, size; int c; UnionFind(int n) : par(n), rank(n,0), size(n,1), c(n) { for (int i = 0; i < n; ++i) par[i] = i; } int find(int i) { return (par[i] == i ? i : (par[i] = find(par[i]))); } bool same(int i, int j) { return find(i) == find(j); } int get_size(int i) { return size[find(i)]; } int count() { return c; } void purge(int i) { size[i] = 0; } void merge(int i, int j) { if ((i = find(i)) == (j = find(j))) return; c--; if (rank[i] > rank[j]) swap(i, j); par[i] = j; size[j] += size[i]; if (rank[i] == rank[j]) rank[j]++; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int h, n, m; cin >> h >> n >> m; UnionFind uf(n * m); vector prow(m, '#'); for (int i = 0; i < n; ++i) { vector row(m); for (int j = 0; j < m; ++j) { cin >> row[j]; if (row[j] == '#') uf.purge(i * m + j); else { if (j > 0 && row[j - 1] == '.') uf.merge(i * m + j, i * m + j - 1); if (i > 0) { if (prow[j] == '.') uf.merge(i * m + j, (i - 1) * m + j); if (i % 2 == 0 && j > 0 && prow[j-1] == '.') uf.merge(i * m + j, (i - 1) * m + j - 1); if (i % 2 == 1 && j + 1 < m && prow[j+1] == '.') uf.merge(i * m + j, (i - 1) * m + j + 1); } } } prow = row; } vi sz; for (int i = 0; i < n*m; ++i) if (uf.find(i) == i) sz.push_back(uf.get_size(i)); sort(sz.rbegin(), sz.rend()); sz.insert(sz.begin(), 0); partial_sum(sz.begin(), sz.end(), sz.begin()); cout << int(lower_bound(sz.begin(), sz.end(), h) - sz.begin()) << endl; return 0; }