/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define fr(i,n) for(int i=0;i<(n);++i)
#define Fr(i,n) for(int i=1;i<=(n);++i)
#define ifr(i,n) for(int i=(n)-1;i>=0;--i)
#define iFr(i,n) for(int i=(n);i>0;--i)

template<class T> inline void cc(vector<T> a,unordered_map<T,int>& nm,vector<int>& c){
    sort(a.begin(),a.end());
    fr(i,a.size()){
        if(i<a.size()-1&&a[i]==a[i+1]) continue;
        nm[a[i]]=c.size();
        c.emplace_back(a[i]);
    }
}


template< typename Monoid, typename OperatorMonoid = Monoid >
struct LSeg {
    using F = function< Monoid(Monoid, Monoid) >;
    using G = function< Monoid(Monoid, OperatorMonoid, int) >;
    using H = function< OperatorMonoid(OperatorMonoid, OperatorMonoid) >;

    int sz;
    vector< Monoid > data;
    vector< OperatorMonoid > lazy;
    inline Monoid f(Monoid a,Monoid b){
        return b==-1?a:b;
    }
    inline Monoid g(Monoid a,OperatorMonoid b){
        return b==-1?a:b;
    }
    inline Monoid h(OperatorMonoid a,OperatorMonoid b){
        return b==-1?a:b;
    }
    const Monoid M1;
    const OperatorMonoid OM0;


    LSeg(int n, const Monoid &M1, const OperatorMonoid OM0)
            :  M1(M1), OM0(OM0) {
        sz = 1;
        while(sz < n) sz <<= 1;
        data.assign(sz<<1, M1);
        lazy.assign(sz<<1, OM0);
    }

    void set(int k, const Monoid &x) {
        data[k + sz] = x;
    }

    void build() {
        for(int k = sz - 1; k > 0; k--) {
            data[k] = f(data[k<<1], data[(k<<1) + 1]);
        }
    }

    void propagate(int k, int len) {
        if(lazy[k] != OM0) {
            if(k < sz) {
                lazy[k<<1 ] = h(lazy[k<<1], lazy[k]);
                lazy[(k<<1)+1] = h(lazy[(k<<1) + 1], lazy[k]);
            }
            data[k] = g(data[k], lazy[k]);
            lazy[k] = OM0;
        }
    }

    Monoid ud(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
        propagate(k, r - l);
        if(r <= a || b <= l) {
            return data[k];
        } else if(a <= l && r <= b) {
            lazy[k] = h(lazy[k], x);
            propagate(k, r - l);
            return data[k];
        } else {
            return data[k] = f(ud(a, b, x, (k<<1) , l, (l + r) >> 1),
                               ud(a, b, x, (k<<1) + 1, (l + r) >> 1, r));
        }
    }

    Monoid ud(int a, int b, const OperatorMonoid &x) {
        return ud(a, b, x, 1, 0, sz);
    }


    Monoid gt(int a, int b, int k, int l, int r) {
        propagate(k, r - l);
        if(r <= a || b <= l) {
            return M1;
        } else if(a <= l && r <= b) {
            return data[k];
        } else {
            return f(gt(a, b, (k<<1) , l, (l + r) >> 1),
                     gt(a, b, ( k<<1) + 1, (l + r) >> 1, r));
        }
    }

    Monoid gt(int a, int b) {
        return gt(a, b, 1, 0, sz);
    }

    Monoid operator[](const int &k) {
        return gt(k, k + 1);
    }
};

bool ok(vector<int>&a,vector<int>&c,vector<int>&d,int m){
    //cout<<"!"<<m<<endl;
    unordered_map<int,int> mp;
    int n=a.size(),N=c.size(),nw=-1;
    vector<int> e(N,1);
    fr(i,N){
        fr(j,d[i]){
            e[i]*=m;
            if(e[i]>=n){
                e[i]=n;
                break;
            }
        }
    }
    LSeg<int,int> seg(N,-1,-1);
    fr(i,n){
        if(a[i]>nw) seg.ud(nw+1,a[i]+1,0);
        else{
            int A=a[i];
            int B=seg.gt(A,A+1)+1;
            if(B==e[A]) B=0;
            seg.ud(A,A+1,B);
            //cout<<i<<" "<<a[i]<<" "<<seg.gt(a[i],a[i]+1)<<endl;
            while(B==0){
                if(A==0) return false;
                --A;
                B=seg.gt(A,A+1)+1;
                if(B==e[A]) B=0;
                seg.ud(A,A+1,B);
            }
        }
        nw=a[i];
    }
    return true;
}

class CLexicographicConstraints {
public:
    void solve(istream& in, ostream& out) {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        int n;
        in>>n;
        vector<int> a(n),b(n),c,d;
        unordered_map<int,int> nm;
        for(auto&i:a) in>>i;
        bool f=true;
        fr(i,n-1) if(a[i]>=a[i+1]) f=false;
        if(f){
            out<<1<<endl;
            return;
        }
        fr(i,n) b[i]=a[i];
        cc(b,nm,c);
        fr(i,n) a[i]=nm[a[i]];
        int N=c.size();
        d.resize(N);
        d[0]=c[0];
        Fr(i,N-1) d[i]=c[i]-c[i-1];
        int l=1,r=n,m;
        while(r-l>1){
            m=(l+r)/2;
            if(ok(a,c,d,m)) r=m;
            else l=m;
        }
        out<<r<<endl;
    }
};

int main() {
    CLexicographicConstraints solver;
    std::istream& in(std::cin);
    std::ostream& out(std::cout);
    solver.solve(in, out);
    return 0;
}


Measured memory_bytes: 16556