#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <list>
#include <iterator>
#pragma warning(disable:4996)
 
typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF 9223300000000000000
#define INF 2140000000
#define MOD 1000000007
using namespace std;


long n;
vector<long> a;


struct MyPair
{
    long   first;
    list<pair<long,long> >::iterator  second;

    MyPair( long in_first,  list<pair<long,long> >::iterator in_second )
    {
        first = in_first;
        second = in_second;
    }
    bool operator<(const MyPair& rhs) const
    {
        return first < rhs.first;
    };
};


bool check( long m )
{
    list<pair<long,long> > zz;     // (length,num)
    long i;
    for(i=0; i<n; i++) {
        if(!zz.empty() && zz.back().first==a[i]) {
            zz.back().second ++;
        }
        else {
            zz.push_back( make_pair(a[i], 1) );
        }
    }

    priority_queue<MyPair> que;
    {        
        auto cit=zz.begin();
        for(; cit!=zz.end(); ++cit) {
            que.push( MyPair(cit->first, cit) );
        }
    }

    while( !que.empty() ) {
        auto tmp = que.top();
        que.pop();
        auto curr = tmp.second;
        auto prev = curr;
        auto next = curr;

CHECK:
        // merge curr to prev if they have the same length
        if(curr!=zz.begin()) {
            prev --;        
            if(prev->first==curr->first) {
                prev->second += curr->second;
                if(prev->first==1 && prev->second>m) return false;
                zz.erase(curr);
                continue;
            }
        }

        // merge curr to next if they have the same length
        next ++;
        if(next != zz.end()) {
            if(next->first==curr->first) {
                next->second += curr->second;
                if(next->first==1 && next->second>m) return false;
                zz.erase(curr);
                continue;
            }
        }

        // If size==1 and curr->first==1, then finish
        if(prev==curr && next==zz.end() && curr->first==1) {
            if(curr->second>m) return false;
            else               return true;
        }

        // modify curr
        if(curr==zz.begin() && next==zz.end() ) {
            long tmp0 = curr->second;
            if(m==1) {
                if(tmp0>1) return false;
                curr->second = 1;
                curr->first = 1;
            }
            else {
                tmp0--;
                long k;
                for(k=0; k<(curr->first-1); k++) {
                    tmp0 = tmp0/m;
                    if(tmp0==1) break;
                }
                curr->second = tmp0+1;
                curr->first = 1;
            }
        }
        else if(curr!=zz.begin() && (next==zz.end() || prev->first >= next->first) ) {
            long tmp0 = curr->second;
            if(m==1) {
                if(tmp0>1) return false;
                curr->second = 0;
                curr->first = prev->first;
            }
            else {
                tmp0--;
                long k;
                for(k=0; k<(curr->first-prev->first); k++) {
                    tmp0 = tmp0/m;
                    if(tmp0==0) break;
                }
                curr->second = tmp0;
                curr->first = prev->first;
            }
        }
        else {
            long tmp0 = curr->second;
            if(m==1) {
                if(tmp0>1) return false;
                curr->second = (curr==zz.begin()? 1: 0);
                curr->first = next->first;
            }
            else {
                tmp0--;
                long k;
                for(k=0; k<(curr->first-next->first); k++) {
                    tmp0 = tmp0/m;
                    if(tmp0==0) break;
                }
                curr->second = tmp0+1;
                curr->first = next->first;
            }
        }
        prev=next=curr;
        goto CHECK;
    }

    return true;
}

int main(int argc, char* argv[])
{
    scanf("%ld", &n);

    a.resize(n);
    long i;
    for(i=0; i<n; i++) {
        scanf("%ld", &a[i]);
    }

    long l=0, r=n;
    while(r-l>1) {
        long m=(l+r)/2;
        if( check(m) ) {
            r = m;
        }
        else {
            l = m;
        }
    }
    printf("%ld\n", r);

    return 0;
}



Measured memory_bytes: 21320