#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <sstream>
#include <complex>
#include <ctime>
#include <cassert>
#include <functional>

using namespace std;

typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> PII;

#define REP(i,s,t) for(int i=(s);i<(t);i++)
#define FILL(x,v) memset(x,v,sizeof(x))

const int INF = (int)1E9;
#define MAXN 1005

char g[MAXN][MAXN];
int dir[4][2] = {-1,0,1,0,0,1,0,-1};
int dst[MAXN][MAXN];
int main() {
  int r, c;
  queue<PII> q;
  cin >> r >> c;
  REP(i,0,r) cin >> g[i];
  REP(i,0,r) {
    REP(j,0,c) {
      dst[i][j] = INF;
      if (g[i][j] == 'X') {
        bool ok = false;
        REP(d,0,4) {
          int ni = i + dir[d][0], nj = j + dir[d][1];
          if (ni < 0 || ni >= r || nj < 0 || nj >= c) {
            ok = true;
            continue;
          }
          if (g[ni][nj] == '-') ok = true;
        }
        if (ok) {
          q.push(PII(i, j));
          dst[i][j] = 1;
        }
      }
    }
  }
  int ans = 0;
  while (q.size()) {
    PII cur = q.front(); q.pop();
    int i = cur.first, j = cur.second;
    ans = dst[i][j];
    REP(d,0,4) {
      int ni = i + dir[d][0], nj = j + dir[d][1];
      if (ni < 0 || ni >= r || nj < 0 || nj >= c) continue;
      if (g[ni][nj] == 'X' && dst[ni][nj] == INF) {
        dst[ni][nj] = dst[i][j] + 1;
        q.push(PII(ni, nj));
      }
    }
  }
  cout << ans << endl;
  return 0;
}
