#include<stdio.h>
#include<iostream>
#include<iomanip>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<unordered_map>
#include<set>
#include<algorithm>
#include<string>
#include<math.h>
#include<numeric>
#include<complex>
#include<ctype.h>

using namespace std;
typedef long long ll;

#define REP(i,n) for(int i=0;i<n;++i)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<endl
#define p2(s, t) cout << (s) << " " << (t) << endl
#define pn(s) cout << (#s) << " " << (s) << endl

const ll mod = 1e9 + 7;
const ll inf = 1e18;

void pV(vector<ll> A){
    cout << "[vector]";
    for(int i=0; i<A.size(); i++){
        cout << A[i] << " ";
    }
    cout << endl;
}

int N;
vector<int> A;
map<int, int> mp;
int K;

// 戻り値は、最後に変更したindex
int increment(int index){
    if(mp.find(index)==mp.end()){
        mp[index] = 2;
    }else{
        mp[index]++;
    }
    
    // 繰り上がり
    while(mp[index]>K){
        //p("くりあがり発生");
        
        //mp.erase(mp.lower_bound(index), mp.end());
        mp[index] = 1;

        index--;
        if(index==-1){
            return index;
        }
        // 繰り上がった先にキーがないとき、そこにはaがある
        if(mp.find(index)==mp.end()){
            mp[index] = 2;
        }else{
            mp[index]++;
        }
    }
    return index;
}

void printMap(){
    cout << "map K=" << K;
    FOR(i, 0, 10){
        // キーがあるものだけ表示
        if(mp.find(i) != mp.end()){
            cout << " " << i << ":" << mp[i];
        }
    }
    cout << endl;
}

// k種類の文字で解けるかどうか
bool solve(){
    mp.clear();
    //cout << "solve by " << K << endl << flush;

    // aで埋める
    // FOR(i, 0, A[0]){
    //     mp[i] = 1;
    // }
    mp[A[0]-1] = 1; // 終端のみ

    FOR(i, 1, N){
        //printMap();
        // 長くなっているときは簡単(繰り上がりも起こらない)
        if(A[i] > A[i-1]){
            //int index = increment(A[i] - 1);
            //if(index == -1) return false;
            mp[A[i]-1] = 1;
        }
        else if(A[i] == A[i-1]){
            int index = increment(A[i]-1);
            if(index == -1) return false;
        }
        // 短くなった場合
        else{
            mp.erase(mp.lower_bound(A[i]), mp.end());
            int inc_index = A[i] - 1;
            int index = increment(inc_index);
            if(index == -1) return false;
        }
    }
    return true;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    // input
    cin >> N;
    A.reserve(N);

    FOR(i, 0, N){
        cin >> A[i];
    }

    // 文字が1種で解けるか？
    bool canSolveByOne = true;
    int a = A[0];
    FOR(i, 1, N){
        if(A[i] > a){
            a = A[i];
        }else{
            canSolveByOne = false;
            break;
        }
    }
    if(canSolveByOne){
        p(1);
        return 0;
    }

    // ここ以降、文字2種以上を仮定できる

    int left = 2;
    int right = 200000;

    while(left != right){
        ll center = (left + right) / 2;
        K = center;
        if(solve()){
            //cout << "とけた " << center << endl;
            right = center;
        }
        else{
            //cout << "とけない " << center << endl;
            left = center + 1;
        }
    }

    p(left);
    
    return 0;
}

Measured memory_bytes: 3840