#include <iostream>
#include <vector>
#include <queue>
using namespace std;

#define rep(i,n) for (int i=0;i<(n);i++)
#define Graph vector<vector<int>>

int main() {
  
  int H,W;
  scanf("%d%d",&H,&W);

  Graph A( H , vector<int> (W,0) );
  Graph count( H , vector<int> (W,0) );
  queue< pair<int,int> > que;

  rep(y,H){
    rep(x,W){

      char a;
      cin >> a;
      if( a == '#' ){
       A[y][x]=1;
       que.push( make_pair(x,y) );
      }
   
    }
  }

  vector<int> dx = { 0, 1, 0, -1 };
  vector<int> dy = { 1, 0, -1, 0 };
  int res = 0;
  
  while( !que.empty() ){

        pair<int,int> v = que.front();
        que.pop();

        int x = v.first;
        int y = v.second;

        rep(i,4) {

            int nv_x = x + dx[i];
            int nv_y = y + dy[i];

            //通れるか？
            if ( nv_x < 0 || nv_x >= W ) continue;
            if ( nv_y < 0 || nv_y >= H ) continue;
            if ( A[nv_y][nv_x] == 1 ) continue;
            
            A[nv_y][nv_x] = 1;
            count[nv_y][nv_x] = count[y][x] +1;
            res = count[nv_y][nv_x];
            que.push( make_pair(nv_x,nv_y) );

        }
    }
   
  printf("%d\n", res );
  return 0;

}

#include <iostream>
#include <string>
#include <vector>


using namespace std;

int min(int a, int b) { return(a < b) ? a : b; }

class Solution
{
public:
	int minDistance(const string &word1, const string &word2)
	{
		const size_t m = word1.size() + 1;
		const size_t n = word2.size() + 1;

		vector<vector<int> > k(m, vector<int>(n));

		for (size_t i = 0; i < m; ++i)
			k[i][0] = i;

		for (size_t j = 0; j < n; ++j)
			k[0][j] = j;

		for (size_t i = 1; i < m; ++i)
		{
			for (size_t j = 1; j < n; ++j)
			{
				if (word1[i - 1] == word2[j - 1])
					k[i][j] = k[i - 1][j - 1];
				else
					k[i][j] = min(k[i - 1][j - 1], min(k[i - 1][j], k[i][j - 1])) + 1;
			}
		}
		return k[m - 1][n - 1];
	}
};

int main() {
	string a, b;
	cin >> a >> b;
	Solution A;
	cout << A.minDistance(a, b) << endl;
}