#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <array>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <queue>
#include <bitset>
#include <tuple>
#include <cmath>
#include <complex>
#include <algorithm>
#include <utility>
#include <regex>
#include <cstdint>
#include <numeric>
#include <functional>
#include <cassert>

using namespace std;
using ll = int64_t;
using ull = uint64_t;

constexpr ll INF = 1000000000;/* 1e+9a */
namespace utils{

    class Repeater{
        int st;
        int ed;
        int d;
    public:
        class rep_iterator{
            int i; int d;
        public:
            rep_iterator(int x, int pd) :i(x), d(pd) {}

            int& operator*(){ return i; }
            bool operator==(const rep_iterator& k) const { return i == k.i; }
            bool operator!=(const rep_iterator& k) const { return i != k.i; }
            rep_iterator& operator++(){ i+=d; return *this; }
        };

        explicit Repeater(int N) :st(0), ed(N), d(1) {}
        Repeater(int b, int e) :st(b), ed(e), d(1) {if(st > ed){ st--; ed--; d = -1; } }

        rep_iterator begin() const{ return rep_iterator(st, d); }
        rep_iterator end() const{ return rep_iterator(ed, d); }

    };

    template<class T, class Compare> using p_queue = priority_queue<T, vector<T>, Compare>;
    template<class T> using min_queue = p_queue<T, greater<T>>;
    template<class T> using max_queue = p_queue<T, less<T>>;

    template<class T> bool min_update(T& X, const T& A){ if(X > A) {X = A; return true;} return false; }
    template<class T> bool max_update(T& X, const T& A){ if(X < A) {X = A; return true;} return false; }
#define ALL(x) begin(x), end(x)
#define rALL(x) rbegin(x), rend(x)
}
using namespace utils;

namespace XelmhMatrix{
    class Subscript {
    public:
        using subscript_type = long long;
        subscript_type i;
        subscript_type j;
        Subscript(subscript_type vi, subscript_type vj) : i(vi), j(vj) {}
        Subscript() : i(0), j(0) {}
        Subscript operator+(const Subscript T) const { return {i + T.i, j + T.j}; }
        Subscript operator-(const Subscript T) const { return {i - T.i, j - T.j}; }
        void operator+=(const Subscript T) { i += T.i; j += T.j; }
        void operator-=(const Subscript T) { i -= T.i; j -= T.j; }
        bool operator==(const Subscript T) const { return i == T.i && j == T.j; }
    };

    std::ostream &operator<<(std::ostream &os, Subscript p) {
        return os << "i:" << p.i << ",j:" << p.j;
    }

    template<class value_type>
    class Matrix{
        using mat_type = std::vector<std::vector<value_type>>;
        using size_type = unsigned long long;
        mat_type values;
        size_type row;
        size_type column;
    public:
        explicit Matrix(const size_type N, const size_type M)
            :values(N, std::vector<value_type>(M)), row(N), column(M) {}
        value_type& operator[](const Subscript ij) { return values[ij.i][ij.j]; }
        const value_type& operator[](const Subscript ij) const{ return values[ij.i][ij.j]; }
        std::vector<value_type>& operator[](const Subscript::subscript_type x) { return values[x];}
        const std::vector<value_type>& operator[](const Subscript::subscript_type x) const { return values[x];}

        bool is_inside(Subscript ij){
            return 0 <= ij.i && ij.i < row
                 && 0 <= ij.j && ij.j < column;
        }
        bool is_inside(size_type i, size_type j){
            return 0 <= i && i < row
                 && 0 <= j && j < column;
        }
        size_type row_size() const { return row; }
        size_type column_size() const { return column; }
    };

    template<class value_type>
    std::istream& operator>>(std::istream& is, Matrix<value_type>& mat){
        for (unsigned long long i = 0; i < mat.row_size(); ++i) {
            for (unsigned long long j = 0; j < mat.column_size(); ++j) {
                is >> mat[i][j];
            } // end j
        } // end i
        return is;
    }
    template<class value_type>
    std::ostream& operator<<(std::ostream& os, const Matrix<value_type>& mat){
        unsigned long long endpoint = mat.column_size() - 1;
        unsigned long long iend, jend;
        iend = mat.row_size(); jend = mat.column_size();
        for (unsigned long long i = 0; i < iend; ++i) {
            for (unsigned long long j = 0; j < jend; ++j) {
                os << mat[i][j] << " \n"[j == endpoint];
            } // end j
        } // end i
        return os;
    }


    std::array<Subscript, 4> move_directions{
                Subscript{1, 0}, Subscript{-1, 0}, Subscript{0, 1}, Subscript{0, -1}
            };
}
using namespace XelmhMatrix;

void sub_main(istream &is) {
    ll H, W;
    is >> H >> W;
    if(!is) return;
    Matrix<char> mx(H, W);
    is >> mx;

    queue<Subscript> black;
    queue<int> repeat;
    for (auto &&i : Repeater(0, H)) {
        for (auto &&j : Repeater(0, W)) {
            if(mx[i][j] == '#'){
                black.emplace(i, j);
                repeat.push(0);
            }
        } // end j
    } // end i

    int rep = 0;
    while(!black.empty()){
        auto pos = black.front(); black.pop();
        auto count = repeat.front(); repeat.pop();
        max_update(rep, count);
        for (auto &&d : move_directions) {
            auto next = pos + d;
            if(mx.is_inside(next) and mx[next] == '.'){
                mx[next] = '#';
                black.push(next);
                repeat.push(count+1);
            }
        } // end d
    }
    cout << rep << endl;
}

int main(int argc, char *argv[]) {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << setprecision(16) << scientific;
#ifdef DEBUG
    string test_cases = "test_A.txt";
    cerr << "DEBUG MODE" <<  endl;
    cerr << test_cases << " -->" << endl;
    auto fs = fstream(test_cases, fstream::in);
    int lp = 0;
    while(fs) {
        lp++;
        cout << lp <<  "#------\n";
        sub_main(fs);
    }
    cout << "------#" << endl;
    if(lp <= 1) sub_main(cin);
#else
    sub_main(cin);
#endif
    return 0;
}


Measured memory_bytes: 21684