#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <functional>
#include <set>
#include <ctime>
#include <random>
#include <chrono>
#include <cassert>
#include <tuple>
#include <utility>
using namespace std;

namespace {
  using Integer = long long; //__int128;
  template<class T, class S> istream& operator >> (istream& is, pair<T,S>& p){return is >> p.first >> p.second;}
  template<class T> istream& operator >> (istream& is, vector<T>& vec){for(T& val: vec) is >> val; return is;}
  template<class T> istream& operator ,  (istream& is, T& val){ return is >> val;}
  template<class T, class S> ostream& operator << (ostream& os, const pair<T,S>& p){return os << p.first << " " << p.second;}
  template<class T> ostream& operator << (ostream& os, const vector<T>& vec){for(size_t i=0; i<vec.size(); i++) os << vec[i] << (i==vec.size()-1?"":" "); return os;}
  template<class T> ostream& operator ,  (ostream& os, const T& val){ return os << " " << val;}

  template<class H> void print(const H& head){ cout << head; }
  template<class H, class ... T> void print(const H& head, const T& ... tail){ cout << head << " "; print(tail...); }
  template<class ... T> void println(const T& ... values){ print(values...); cout << endl; }

  template<class H> void eprint(const H& head){ cerr << head; }
  template<class H, class ... T> void eprint(const H& head, const T& ... tail){ cerr << head << " "; eprint(tail...); }
  template<class ... T> void eprintln(const T& ... values){ eprint(values...); cerr << endl; }

  class range{ Integer start_, end_, step_; public: struct range_iterator{ Integer val, step_; range_iterator(Integer v, Integer step) : val(v), step_(step) {} Integer operator * (){return val;} void operator ++ (){val += step_;} bool operator != (range_iterator& x){return step_ > 0 ? val < x.val : val > x.val;} }; range(Integer len) : start_(0), end_(len), step_(1) {} range(Integer start, Integer end) : start_(start), end_(end), step_(1) {} range(Integer start, Integer end, Integer step) : start_(start), end_(end), step_(step) {} range_iterator begin(){ return range_iterator(start_, step_); } range_iterator   end(){ return range_iterator(  end_, step_); } };

  inline string operator "" _s (const char* str, size_t size){ return move(string(str)); }
  constexpr Integer my_pow(Integer x, Integer k, Integer z=1){return k==0 ? z : k==1 ? z*x : (k&1) ? my_pow(x*x,k>>1,z*x) : my_pow(x*x,k>>1,z);}
  constexpr Integer my_pow_mod(Integer x, Integer k, Integer M, Integer z=1){return k==0 ? z%M : k==1 ? z*x%M : (k&1) ? my_pow_mod(x*x%M,k>>1,M,z*x%M) : my_pow_mod(x*x%M,k>>1,M,z);}
  constexpr unsigned long long operator "" _ten (unsigned long long value){ return my_pow(10,value); }

  inline int k_bit(Integer x, int k){return (x>>k)&1;} //0-indexed

  mt19937 mt(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count());

  template<class T> string join(const vector<T>& v, const string& sep){ stringstream ss; for(size_t i=0; i<v.size(); i++){ if(i>0) ss << sep; ss << v[i]; } return ss.str(); }

  inline string operator * (string s, int k){ string ret; while(k){ if(k&1) ret += s; s += s; k >>= 1; } return ret; }
}
constexpr long long mod = 9_ten + 7;

bool calc(int n, vector<int>& a, int ub){
  deque<tuple<int,int,int>> st;
  st.emplace_back(-1, 0, 0);
  st.emplace_back(0, a[0], 1);

  int ans = ub;

  auto merge = [&](){
    if(get<2>(st.back()) == get<2>(st[st.size()-2])){
      get<1>(st[st.size()-2]) = get<1>(st.back());
      st.pop_back();
    }
  };

  auto pop = [&](int r){
    int last = get<2>(st.back());
    while(get<1>(st.back()) > r){
      last = get<2>(st.back());
      st.pop_back();
    }
    return last;
  };

  auto push = [&](int r, int c){
    st.emplace_back(get<1>(st.back()), r, c);
    merge();
  };

  auto split_tail = [&](){
    int len = get<1>(st.back()) - get<0>(st.back());
    int r = get<1>(st.back());
    int c = get<2>(st.back());
    if(len == 1) return;
    get<1>(st.back()) -= 1;
    st.emplace_back(r-1, r, c);
  };

  // for(int j=1; j<st.size(); j++){
  //   auto& x = st[j];
  //   int len = get<1>(x) - get<0>(x);
  //   eprint(string(len, 'a'-1 + get<2>(x)));
  // }
  // eprintln("");



  for(int i=1; i<n; i++){
    if(get<1>(st.back()) < a[i]){
      st.emplace_back(get<1>(st.back()), a[i], 1);
      merge();
    }else{
      int last = pop(a[i]);
      if(get<1>(st.back()) < a[i]){
        push(a[i], last);
      }
      if(get<2>(st.back())+1 <= ans){
        split_tail();
        get<2>(st.back())++;
        merge();
      }else{
        if(st.size() == 2){
          split_tail();
          get<2>(st.back())++;
          merge();
          ans = max(ans, get<2>(st.back()));
          if(ans > ub) return false;
        }else{
          st.pop_back();
          split_tail();
          get<2>(st.back())++;
          merge();
          push(a[i], 1);
        }
      }
    }

    // for(int j=1; j<st.size(); j++){
    //   auto& x = st[j];
    //   int len = get<1>(x) - get<0>(x);
    //   eprint(string(len, 'a'-1 + get<2>(x)));
    // }
    // eprintln("");

  }

  return true;
}

int main(){
  int n;
  cin >> n;
  vector<int> a(n);
  cin >> a;

  long long lb = 0;
  long long ub = n;
  while(ub-lb>1){
    long long mid = (lb+ub)/2;
    bool ok = calc(n, a, mid);
    (ok? ub : lb) = mid;
  }

  println(ub);

  return 0;
}


Measured memory_bytes: 1024