using System;
using System.Collections.Generic;
using CompLib.Util;

public class Program
{
    private int N;
    private int[] A;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        A = sc.IntArray();
        int ng = 0;
        int ok = N;
        while (ok - ng > 1)
        {
            int med = (ok + ng) / 2;
            if (Check(med))
            {
                ok = med;
            }
            else
            {
                ng = med;
            }
        }

        Console.WriteLine(ok);
    }

    // k文字で可能か?
    private bool Check(int k)
    {
        var stack = new Stack<Segment>();
        stack.Push(new Segment(A[0], 1));
        for (int i = 1; i < N; i++)
        {
            if (A[i - 1] < A[i])
            {
                int d = A[i] - A[i - 1];
                if (stack.Peek().Char == 1)
                {
                    var q = stack.Pop();
                    stack.Push(new Segment(q.Length + d, 1));
                }
                else
                {
                    stack.Push(new Segment(d, 1));
                }
            }
            else
            {
                var p = stack.Pop();
                int l = A[i - 1] - p.Length;
                while (l >= A[i])
                {
                    p = stack.Pop();
                    l -= p.Length;
                }

                if (p.Char == k)
                {
                    while (p.Char == k)
                    {
                        if (stack.Count <= 0) return false;
                        p = stack.Pop();
                        l -= p.Length;
                    }

                    if (p.Length > 1)
                    {
                        stack.Push(new Segment(p.Length - 1, p.Char));
                    }

                    stack.Push(new Segment(1, p.Char + 1));
                    int d = A[i] - (l + p.Length);
                    if (d > 0)
                    {
                        stack.Push(new Segment(d, 1));
                    }
                }
                else
                {
                    int d = A[i] - l;
                    if (d > 1)
                    {
                        stack.Push(new Segment(d - 1, p.Char));
                    }

                    stack.Push(new Segment(1, p.Char + 1));
                }
            }
        }

        return true;
    }

    public static void Main(string[] args) => new Program().Solve();
}

struct Segment
{
    public readonly int Length;
    public readonly int Char;

    public Segment(int l, int c)
    {
        Length = l;
        Char = c;
    }
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            while (_index >= _line.Length)
            {
                _line = Console.ReadLine().Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            _line = Console.ReadLine().Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}

Measured memory_bytes: 34012