import java.util.*

fun main(args : Array<String>) {
    val (h, w) = readLine()!!.split(" ").map { it.toInt() }
    val queue = ArrayDeque<Point>()
    val initial = Array(h){""}

    repeat(h) {
        val line = readLine()!!
        initial[it] = line
        line.forEachIndexed { idx, c ->
            if (c == '#') {
                queue.push(Point(it, idx, 0))
            }
        }
    }

    var cnt = 0
    val seen = Array(h){BooleanArray(w){false} }

    while(queue.isNotEmpty()) {
        val point = queue.pop()
        cnt = point.cnt
        seen[point.h][point.w] = true

        if (point.h > 0 && !seen[point.h-1][point.w] && initial[point.h-1][point.w] == '.') {
            seen[point.h-1][point.w] = true
            queue.add(Point(point.h-1, point.w, point.cnt+1))
        }
        if (point.h < h-1 && !seen[point.h+1][point.w] && initial[point.h+1][point.w] == '.') {
            seen[point.h+1][point.w] = true
            queue.add(Point(point.h+1, point.w, point.cnt+1))
        }
        if (point.w > 0 && !seen[point.h][point.w-1] && initial[point.h][point.w-1] == '.') {
            seen[point.h][point.w-1] = true
            queue.add(Point(point.h, point.w-1, point.cnt+1))
        }
        if (point.w < w-1 && !seen[point.h][point.w+1] && initial[point.h][point.w+1] == '.') {
            seen[point.h][point.w+1] = true
            queue.add(Point(point.h, point.w+1, point.cnt+1))
        }
    }

    println(cnt)
}

data class Point(val h: Int, val w: Int, val cnt: Int)