#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i))
#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i))
#define REP_R(i, n) for (int i = int(n) - 1; (i) >= 0; -- (i))
#define REP3R(i, m, n) for (int i = int(n) - 1; (i) >= (int)(m); -- (i))
#define ALL(x) begin(x), end(x)
#define dump(x) cerr << #x " = " << x << endl
#define unittest_name_helper(counter) unittest_ ## counter
#define unittest_name(counter) unittest_name_helper(counter)
#define unittest __attribute__((constructor)) void unittest_name(__COUNTER__) ()
using ll = long long;
using namespace std;
template <class T> using reversed_priority_queue = priority_queue<T, vector<T>, greater<T> >;
template <class T, class U> inline void chmax(T & a, U const & b) { a = max<T>(a, b); }
template <class T, class U> inline void chmin(T & a, U const & b) { a = min<T>(a, b); }
template <typename X, typename T> auto vectors(X x, T a) { return vector<T>(x, a); }
template <typename X, typename Y, typename Z, typename... Zs> auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector<decltype(cont)>(x, cont); }
template <typename T> ostream & operator << (ostream & out, vector<T> const & xs) { REP (i, int(xs.size()) - 1) out << xs[i] << ' '; if (not xs.empty()) out << xs.back(); return out; }

template <typename UnaryPredicate>
int64_t binsearch(int64_t l, int64_t r, UnaryPredicate p) {
    assert (l <= r);
    -- l;
    while (r - l > 1) {
        int64_t m = l + (r - l) / 2;
        (p(m) ? r : l) = m;
    }
    return r;
}

void normalize_tail(vector<pair<int, int> > & s) {
    while (true) {
        bool modified = false;
        if (s.size() >= 1 and s.back().second == 0) {
            s.pop_back();
            modified = true;
        }
        if (s.size() >= 2 and s[s.size() - 2].first == s[s.size() - 1].first) {
            int k = s.back().second;
            s.pop_back();
            s.back().second += k;
            modified = true;
        }
        if (not modified) break;
    }
}

int try_increment(int k, vector<pair<int, int> > & s, int length) {
    if (s.back().first == k - 1) {
        length -= s.back().second;
        s.pop_back();
        if (s.empty()) {
            return 0;
        }
    }
    int c = s.back().first;
    assert (c + 1 < k);
    s.back().second -= 1;
    normalize_tail(s);
    s.emplace_back(c + 1, 1);
    normalize_tail(s);
    return length;
}

ll solve(int n, vector<int> const & a) {
    return binsearch(1, n + 1, [&](int k) {
        vector<pair<int, int> > s;
        s.emplace_back(0, a[0]);  // "000...0"
        REP (i, n - 1) {
            if (a[i] < a[i + 1]) {
                s.emplace_back(0, a[i + 1] - a[i]);
                normalize_tail(s);
            } else {
                int length = a[i];
                while (length > a[i + 1]) {
                    int delta = min(s.back().second, length - a[i + 1]);
                    s.back().second -= delta;
                    length -= delta;
                    normalize_tail(s);
                }
                length = try_increment(k, s, length);
                if (not length) {
                    return false;
                }
                assert (not s.empty());
                if (length < a[i + 1]) {
                    s.emplace_back(0, a[i + 1] - length);
                    normalize_tail(s);
                }
            }
        }
        return true;
    });
}

int main() {
    int n; cin >> n;
    vector<int> a(n);
    REP (i, n) cin >> a[i];
    cout << solve(n, a) << endl;
    return 0;
}


Measured memory_bytes: 1024