import java.util.*

fun main(args: Array<String>) {
    val N = readLine()!!.toInt()
    val A = readLine()!!.split(" ").map {it.toInt()}

    var l = 0
    var r = N

    while(r - l > 1) {
        val c = (l + r) / 2

        fun judge(c: Int): Boolean {
            val s = ArrayDeque<Triple<Int, Int, Int>>()
            s.addLast(Triple(0, A[0], 0))

            for (i in 1 until N) {
                val len = A[i]

                if (s.last.second < len) {
                    s.addLast(Triple(s.last.second, len, 0))
                } else {
                    while(s.isNotEmpty() && s.last.first >= len) {
                        s.pollLast()
                    }

                    while(s.isNotEmpty() && s.last.third >= c - 1) {
                        s.pollLast()
                    }

                    if (s.isEmpty()) {
                        return false
                    }

                    var t = s.removeLast()
                    if (t.second > len) {
                        t = Triple(t.first, len, t.third)
                    }
                    if (t.second - t.first > 1) {
                        s.addLast(Triple(t.first, t.second - 1, t.third))
                    }
                    s.addLast(Triple(t.second - 1, t.second, t.third + 1))

                    if (s.last.second < len) {
                        s.addLast(Triple(s.last.second, len, 0))
                    }
                }
            }

            return true
        }

        if (judge(c)) {
            r = c
        } else {
            l = c
        }
    }

    println(r)
}
