317 {
318 char cowhide[55][55]{};
319 bool occupy[55][55]{};
320 auto edge = unordered_set<point, pointhash, pointequal>();
321 int n;
322 int m;
323 cin >> n >> m;
324 bool flag = true;
325 point first{};
326 for(int i = 0; i < n; i++) {
327 for(int j = 0; j < m; j++) {
328 cin >> cowhide[i][j];
329 if(flag && cowhide[i][j] == 'X') {
330 occupy[i][j] = true;
331 first = point(i, j);
332 flag = false;
333 } else {
334 occupy[i][j] = false;
335 }
336 }
337 }
338
339 flood(first, occupy, &edge, cowhide, n, m);
340
341 int count = 0;
342 auto nextedge = unordered_set<point, pointhash, pointequal>();
343 while(true) {
344 for(const auto p: edge) {
345 point nexts[] = {
346 point(p.x + 1, p.y), point(p.x - 1, p.y), point(p.x, p.y + 1),
347 point(p.x, p.y - 1)};
348 for(auto next: nexts) {
349 if(0 <= next.x && next.x <= n && 0 <= next.y && next.y <= m && !occupy[next.x][next.y]) {
350 if(cowhide[next.x][next.y] == 'X') {
351 cout << count;
352 return 0;
353 }
354 cowhide[next.x][next.y] = 'X';
355 occupy[next.x][next.y] = true;
356 nextedge.insert(next);
357 }
358 }
359 }
360 count++;
361 edge = nextedge;
362 nextedge = unordered_set<point, pointhash, pointequal>();
363 }
364 }
void flood(point first, bool occupy[55][55], unordered_set< point, pointhash, pointequal > *edge, char cowhide[55][55], int n, int m)