#include <bits/stdc++.h>
using namespace std;

#define TRACE(x)
#define WATCH(x) TRACE(cout << #x" = " << x << endl)
#define WATCHR(a, b) TRACE(for (auto it=a; it!=b;) cout << *(it++) << " "; cout << endl)
#define WATCHC(V) TRACE({cout << #V" = "; WATCHR(V.begin(), V.end());})

#define all(x) (x).begin(), (x).end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

template<class K> struct sp64_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    size_t operator()(const K& x) const {
        static const uint64_t FIXED_RANDOM =
            chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(hash<K>()(x) + FIXED_RANDOM);
    }
};

template<class K, class V> using umap = gp_hash_table<K, V, sp64_hash<K>>;

bool solve(int N, vi& a, int K) {
    WATCH(K);

    vector<pair<int, int>> resets;
    resets.push_back({ 0, -1 });
    umap<int, pair<int, int>> vals;

    for (int i = 0; i < N; i++) {
        if (i > 0 && a[i] <= a[i-1]) {
            while (resets.back().first >= a[i])
                resets.pop_back();
            resets.emplace_back(a[i], i);

            auto it = prev(resets.end());
            for (int incr = a[i] - 1; true; incr--) {
                if (incr < 0) return false;
                while (it != resets.begin() && it->first > incr) it--;
                auto cv = vals[incr];

                assert(it->first <= incr);

                if (cv.second <= it->second) cv.first = 0;
                cv.second = i;
                cv.first++;
                if (cv.first < K) {
                    vals[incr] = cv;
                    break;
                } else {
                    cv.first = 0;
                    vals[incr] = cv;
                }
            }
        }
        TRACE(
            cout << "Built " << i << ": ";
            for (int j = 0; j < a[i]; j++) {
                auto p = vals[j];
                bool res = false;
                for (auto r : resets) {
                    if (r.first <= j && r.second >= p.second)
                        res = true;
                }

                if (res) cout << 0 << " ";
                else cout << p.first << " ";
            }
            cout << endl;
        )
    }

    return true;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int N;
    cin >> N;

    vi a(N);
    bool one = true;
    for (int i = 0; i < N; i++) {
        cin >> a[i];
        if (i) one &= a[i] > a[i-1];
    }

    if (one) {
        cout << 1 << endl;
        return 0;
    }

    int ans = N, lo = 2, hi = N - 1;
    while (lo <= hi) {
        int mi = (lo + hi) / 2;
        if (solve(N, a, mi)) {
            ans = mi;
            hi = mi - 1;
        } else {
            lo = mi + 1;
        }
    }
    cout << ans << endl;

    return 0;
}



Measured memory_bytes: 17380