#include <bits/stdc++.h>

using namespace std;

#ifndef orewabaka
    #define f first
    #define s second
    #define vse(a) a.begin(), a.end()
    #define ovse(a) a.rbegin(), a.rend()
    #define pb push_back
    #define endl aut '\n'
    #define ar vector
    #define var auto
    #define rand() (((rand()<<15)+rand())&INT32_MAX)
    #define ain cin,
    #define aut cout,
    #define $(a) (i32)a.size()
    #define in insert
    #define fusrodah return
    #define mp make_pair
    #define blush() fflush(stdout), fflush(stdin)

    typedef int i32;
    typedef unsigned u32;
    typedef long long i64;
    typedef unsigned long long u64;
    typedef pair<i32, i32> p32;
    typedef pair<i64, i64> p64;
    typedef double lf;

    namespace shyutsuryoku{
        const i32 STRSZ=3e6+13;
        char inbufer[STRSZ];
        inline void cscan(string& i){
            i32 c=getc(stdin), cnt=0;while(c<=32)c=getc(stdin);
            while(c>32)*(inbufer+cnt)=c,c=getc(stdin),++cnt;
            *(cnt+inbufer)=0;i=inbufer;
        }
        inline void cprint(string& i){
            char *s=new char[i.size()+1];
            strcpy(s, i.c_str());
            while(*s)putchar(*s), s++;
        }
        inline void cprint(const char*& i){
            i32 cnt=0;
            while(*(i+cnt))putc(*(i+cnt), stdout),cnt++;
        }
        inline void cscan(i32&i){
            i=0;i32 c=getc(stdin), b=0;while(c<=32)c=getc(stdin);if(c=='-')b=1, c=getc(stdin);
            while(c>='0'&&c<='9')i*=10,i+=c-'0',c=getc(stdin);
            if(b)i=-i;
        }
        inline void cprint(i32 i){
            if(i<0)putc('-',stdout),i=-i;
            i32 sz=0;char ans[12];while(i||!sz)ans[sz++]=i%10+'0',i/=10;
            while(sz--)putc(ans[sz],stdout);
        }
        inline void cscan(i64&i){
            i=0;i32 c=getc(stdin), b=1;while(c<=32)c=getc(stdin);if(c=='-')b=-1,c=getc(stdin);
            while(c>='0'&&c<='9')i*=10,i+=c-'0',c=getc(stdin);
            i*=b;
        }
        inline void cprint(i64 i){
            if(i<0)putc('-',stdout),i=-i;
            i32 sz=0;char ans[21];while(i||!sz)ans[sz++]=i%10+'0',i/=10;
            while(sz--)putc(ans[sz],stdout);
        }
        inline void cscan(u32&i){
            i=0;i32 c=getc(stdin);while(c<=32)c=getc(stdin);
            while(c>='0'&&c<='9')i*=10,i+=c-'0',c=getc(stdin);
        }
        inline void cprint(u32 i){
            i32 sz=0;char ans[12];while(i||!sz)ans[sz++]=i%10+'0',i/=10;
            while(sz--)putc(ans[sz],stdout);
        }
        inline void cscan(u64&i){
            i=0;i32 c=getc(stdin);while(c<=32)c=getc(stdin);
            while(c>='0'&&c<='9')i*=10,i+=c-'0',c=getc(stdin);
        }
        inline void cprint(u64 i){
            i32 sz=0;char ans[21];while(i||!sz)ans[sz++]=i%10+'0',i/=10;
            while(sz--)putc(ans[sz],stdout);
        }
        inline void cscan(lf&i){
            scanf("%lf", &i);
        }
        inline void cprint(lf i){
            printf("%.10lf", i);
        }
        inline void cprint(char i){
            putc(i, stdout);
        }
        inline void cscan(char&i){
            i32 b=getc(stdin);
            while(b<=32)b=getc(stdin);
            i=b;
        }
        template<class T, class K>inline void cscan(pair<T, K>& i){
            cscan(i.f);cscan(i.s);
        }
        template<class T, class K>inline void cprint(pair<T, K>& i){
            cprint('(');cprint(i.f);cprint(' ');cprint(i.s);cprint(')');
        }
        template<class T>inline void cscan(ar<T>& i){
            for(var& j:i)cscan(j);
        }
        template<class T>inline void cprint(ar<T>& i){
            for(var& j:i)cprint(j), cprint(' ');
        }
        template<class T>inline void cprint(ar<ar<T> >& i){
            for(var& j:i)cprint(j), cprint('\n');
        }
        template<class T>ostream &operator,(ostream &os, T v){
            cprint(v);
            return os;
        }
        template<class T>istream &operator,(istream &is, T &v) {
            cscan(v);
            return is;
        }
    }
    using namespace shyutsuryoku;
#endif

void AnimeConservativeRevolution();

i32 main(){
    #ifdef home
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
    #endif
    srand(time(0));
    AnimeConservativeRevolution();
    #ifdef home
        aut '\n', (lf)clock()/CLOCKS_PER_SEC, " sec\n";
    #endif
    fusrodah 0;
}

char in[1013][1013];
i32 ans[1013][1013];

void AnimeConservativeRevolution(){
    i32 h, w;
    ain h, w;
    priority_queue<pair<i32, p32>, ar<pair<i32, p32> >, greater<pair<i32, p32> > > anibtiko;
    for(i32 i=1;i<=h;i++)for(i32 j=1;j<=w;j++){
        ain in[i][j];
        if(in[i][j]=='#')
            ans[i][j]=0, anibtiko.push({0, {i, j}});
        else
            ans[i][j]=1e9, anibtiko.push({1e9, {i, j}});
    }
    i32 q=h*w;
    while(q--){
        var i=anibtiko.top();
        anibtiko.pop();
        //aut i.s.f, ' ', i.s.s, ' ', i.f, '\n';
        if(i.s.f>1){
            if(ans[i.s.f-1][i.s.s]>ans[i.s.f][i.s.s]+1){
                ans[i.s.f-1][i.s.s]=ans[i.s.f][i.s.s]+1;
                anibtiko.push({ans[i.s.f-1][i.s.s], {i.s.f-1, i.s.s}});
            }
        }
        if(i.s.f<h){
            if(ans[i.s.f+1][i.s.s]>ans[i.s.f][i.s.s]+1){
                ans[i.s.f+1][i.s.s]=ans[i.s.f][i.s.s]+1;
                anibtiko.push({ans[i.s.f+1][i.s.s], {i.s.f+1, i.s.s}});
            }
        }
        if(i.s.s>1){
            if(ans[i.s.f][i.s.s-1]>ans[i.s.f][i.s.s]+1){
                ans[i.s.f][i.s.s-1]=ans[i.s.f][i.s.s]+1;
                anibtiko.push({ans[i.s.f][i.s.s-1], {i.s.f, i.s.s-1}});
            }
        }
        if(i.s.s<w){
            if(ans[i.s.f][i.s.s+1]>ans[i.s.f][i.s.s]+1){
                ans[i.s.f][i.s.s+1]=ans[i.s.f][i.s.s]+1;
                anibtiko.push({ans[i.s.f][i.s.s+1], {i.s.f, i.s.s+1}});
            }
        }

    }
    i32 arara=0;

    for(i32 i=1;i<=h;i++)for(i32 j=1;j<=w;j++)
        arara=max(arara, ans[i][j]);
    aut arara;
}


Measured memory_bytes: 32616