class AtCoder {
  // 入力系
  input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);
  input_i=-1;
  n(){
    this.input_i++;
    return Number(this.input[this.input_i]);
  }
  nn(n){
    const a=[];
    for(let i=0;i<n;i++){
      a.push(this.n());
    }
    return a;
  }
  s(){
    this.input_i++;
    return String(this.input[this.input_i]);
  }
  ss(n){
    const a=[];
    for(let i=0;i<n;i++){
      a.push(this.s());
    }
    return a;
  }

  // コンソール
  o(...a:any){
    console.log(...a);
  }

  // Math
  abs(a:number){
    return Math.abs(a);
  }
  min(...a:number[]){
    return Math.min(...a);
  }
  max(...a:number[]){
    return Math.max(...a);
  }
  floor(a:number){
    return Math.floor(a);
  }
  ceil(a:number){
    return Math.ceil(a);
  }
  round(a:number){
    return Math.round(a);
  }

  // ソート
  asc(ar:number[]){
    const t=[...ar];
    ar.sort((a,b)=>{return a-b});
  }
  desc(ar:number[]){
    const t=[...ar];
    ar.sort((a,b)=>{return b-a});
  }

  // 自作
  gcd(...arr):number{
    for(let i=0;i<arr.length-1;i++){
      let [x,y]=[arr[i],arr[i+1]];
      while(y){
        [x,y]=[y,x%y];
      }
      arr[i+1]=x;
    }
    return arr[arr.length-1];
  };
  lcm(...arr):number{
    for(let i=0;i<arr.length-1;i++){
      let [x,y]=[arr[i],arr[i+1]];
      while(y){
        [x,y]=[y,x%y];
      }
      arr[i+1]=arr[i]*arr[i+1]/x;
    }
    return arr[arr.length-1];
  };
  isPrime(n:number):boolean{
    if(n < 2) return false;
    const suq=Math.sqrt(n);
    for(let i=2;i<=suq;i++){
      if(n%i==0){
        return false;
      }
    }return true;
  };
  deduplicate(a:any[]):any[]{
    return Array.from(new Set(a));
  };
}

/* [入力]
  const [H,W]=o.nn(2)
  const [N,M]=o.nn(2)
  const N=o.n()
  const S=o.s()
  const arr1=[]
  for(let i=0;i<N;i++)arr1.push(o.n())
 */

/* [BFS,DFS]
  const [H,W]=o.nn(2),map=new Array(H),save=new Array(H)
  const DH=[0,0,-1,1]
  const DW=[1,-1,0,0]
  for(let i=0;i<H;i++){
    map[i]=o.s().split('')
    save[i]=new Array(W)
    save[i].fill(-1)
  }
  // let queue=[[?,?,1]]
  // save[?][?]=0
  while(queue.length>0){
    let [h,w,c]=queue.shift()
    for(let i=0;i<4;i++){
      if(h+DH[i]<0 || h+DH[i]>=H || w+DW[i]<0 || w+DW[i]>=W){
        continue
      }
      if(map[h+DH[i]][w+DW[i]]==?){
        continue
      }
      if(save[h+DH[i]][w+DW[i]]==-1){
        queue.push([h+DH[i], w+DW[i], c+1])
        save[h+DH[i]][w+DW[i]]=c
      }
    }
  }
*/
const o = new AtCoder()

const [H,W]=o.nn(2),map=new Array(H),save=new Array(H)
const DH=[0,0,-1,1]
const DW=[1,-1,0,0]
for(let i=0;i<H;i++){
  map[i]=o.s().split('')
  save[i]=new Array(W)
  save[i].fill(-1)
}
let queue=[],newQueue=[],count=-1
for(let j=0;j<H;j++){
  for(let k=0;k<W;k++){
    if(map[j][k]=='#')queue.push([j,k,1])
  }
}
while(queue.length>0){
  count++
  let newQueue=[]
  var len = queue.length;
  for (let k=0;k<len;k++) {
    let [h,w]=queue.pop()
    for(let i=0;i<4;i++){
      if(h+DH[i]<0 || h+DH[i]>=H || w+DW[i]<0 || w+DW[i]>=W){
        continue
      }
      if(map[h+DH[i]][w+DW[i]]=='.'){
        newQueue.push([h+DH[i], w+DW[i]])
        map[h+DH[i]][w+DW[i]]='#'
      }
    } 
  }
  queue=newQueue
}
o.o(count)

Measured memory_bytes: 145696