#ifndef NOBITS
#include <bits/stdc++.h>
#endif
using namespace std;
namespace fast_scanner {
    static char __ibuf__[1 << 20], *__p1__ = __ibuf__, *__p2__ = __ibuf__;
    bool advance() { return __p2__ = (__p1__ = __ibuf__) + fread(__ibuf__, 1, sizeof(__ibuf__), stdin), (__p1__ == __p2__); }
    char gc() { return (__p1__ == __p2__ && advance()) ? EOF : (*__p1__++); }
    static bool isspace(char c) { return static_cast<unsigned char>(c - '\t') < 5 || c == ' '; }
    static bool isdigit(char c) { return static_cast<unsigned char>(c - '0') < 10; }
    static inline bool isoneof(char c, const char *str) { return strchr(str, c) != nullptr; }
    template <const char *str> static inline bool isoneof(char c) { return strchr(str, c) != nullptr; }
    uint64_t read_ull() {
        char ch = gc();
        while (!isdigit(ch)) { ch = gc(); }
        uint64_t res = 0;
        while (isdigit(ch)) { res = res * 10 + (ch - '0'), ch = gc(); }
        return res;
    }
    int64_t read_ll() {
        char ch = gc();
        bool neg = false;
        while (!isdigit(ch)) { neg |= (ch == '-'), ch = gc(); }
        uint64_t res = 0;
        while (isdigit(ch)) { res = res * 10 + (ch - '0'), ch = gc(); }
        neg && (res = -res);
        return res;
    }
    long double read_ld() {
        char ch = gc();
        bool neg = false;
        while (!isdigit(ch)) { neg |= (ch == '-'), ch = gc(); }
        uint64_t integerPart = 0, fractionalPart = 0, len = 0, base = 1;
        while (isdigit(ch)) { integerPart = integerPart * 10 + (ch - '0'), ch = gc(); }
        if (ch == '.') {
            ch = gc();
            while (isdigit(ch)) { fractionalPart = fractionalPart * 10 + (ch - '0'), ch = gc(), len += 1; }
            while (len--) base *= 10;
        }
        long double res = (long double)integerPart + (long double)fractionalPart / base;
        neg && (res = -res);
        return res;
    }
    string read_delim(const char* str) {
        char ch = gc();
        while(isoneof(ch, str)) ch = gc();
        string res;
        while(!isoneof(ch, str)) res += ch, ch = gc();
        return res;
    }
    template<typename UnaryPredicate> string read_delim(UnaryPredicate predicate) {
        char ch = gc();
        while(predicate(ch)) ch = gc();
        string res;
        while(!predicate(ch)) res += ch, ch = gc();
        return res;
    }
    string read_line() { return read_delim([](char ch) { return ch == '\n'; }); }
    string read_string() { return read_delim(isspace); }
    char read_char() { return gc(); }
    int read_int() { return (int)read_ll();}
}
template <typename T> T scan() { return T{}; }
template <> int scan<int>() { return fast_scanner::read_int(); }
template <> long scan<long>() { return (long)fast_scanner::read_ll(); }
template <> long long scan<long long>() { return fast_scanner::read_ll(); }
template <> long double scan<long double>() { return fast_scanner::read_ld(); }
template <> double scan<double>() { return (double)fast_scanner::read_ld(); }
template <> string scan<string>() { return fast_scanner::read_string(); }
template <> char scan<char>() { return fast_scanner::gc(); }
template <typename T> T read()
{
    T x;
    cin >> x;
    return x;
}
template <typename... Args> void writeln(const Args &... args)
{
    ((cout << args << " "), ...), cout << "\n";
}
template <typename... Args> void write(const Args &... args)
{
    ((cout << args), ...);
}
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
template <typename T>
typename enable_if<is_same<decltype(declval<T>().size()), size_t>::value, int>::type
operator~(const T &ct)
{
    return (int)ct.size();
}
template <typename T, typename... Args> bool ckmax(T &a, const Args &... b)
{
    return (a < max({b...})) ? (a = max({b...}), true) : false;
}
template <typename T, typename... Args> bool ckmin(T &a, const Args &... b)
{
    return (a > min({b...})) ? (a = min({b...}), true) : false;
}
template <typename T> T div_floor(const T& a, const T& b)
{
    return (a / b) - (!!(a % b) & ((a ^ b) < 0));
}
template <typename T> T div_ceil(const T& a, const T& b)
{
    return (a / b) + (!!(a % b) & ((a ^ b) > 0));
}
template <typename T> using vv = vector<vector<T>>;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using max_heap = priority_queue<T, vector<T>, less<T>>;
template <typename T, typename... Args, template <typename, typename...> typename Container> Container<T, Args...> &operator+=(Container<T, Args...> &ct, const T &val)
{
    return ct.push_back(val), ct;
}
template <typename T, typename... Args, template <typename, typename...> typename Container> Container<T, Args...> &operator+=(const T &val, Container<T, Args...> &ct)
{
    return ct.push_front(val), ct;
}
template <typename T, typename... Args, template <typename, typename...> typename Container> T &operator+(Container<T, Args...> &ct)
{
    return ct.front();
}
template <typename T, typename... Args, template <typename, typename...> typename Container> T &operator-(Container<T, Args...> &ct)
{
    return ct.back();
}
template <typename T, typename... Args, template <typename, typename...> typename Container> T operator--(Container<T, Args...> &ct)
{
    auto res = ct.front();
    return ct.pop_front(), res;
}
template <typename T, typename... Args, template <typename, typename...> typename Container> T operator--(Container<T, Args...> &ct, int)
{
    auto res = ct.back();
    return ct.pop_back(), res;
}
const int N = 200'010;
auto soln()
{
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < (int)(n); ++i) cin >> a[i];
    function<bool(int x)> check = [&](int x) -> bool
    {
        ;;
        map<int, int> s;
        for (int i = 1; i < n; ++i) {
            if (a[i] > a[i - 1])
                continue;
            else {
                if(x == 1) return false;
                s[a[i]] += 1;
                while(!s.empty() and s.rbegin()->first > a[i]) {
                    s.erase(s.rbegin()->first);
                }
                int j = a[i];
                while (j > 0 and s[j] == x) {
                    s.erase(j);
                    s[j - 1] += 1;
                    j--;
                }
                if(s.begin()->first <= 0) return false;
            }
        }
        return true;
    };
    int lo = 1, hi = n;
    while (lo < hi) {
        int mi = (lo + hi) / 2;
        if (check(mi)) {
            hi = mi;
        }
        else {
            lo = mi + 1;
        }
    }
    cout << lo << "\n";
}
signed main() {
    int t = 1;
    { ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL); };
    while (t--)
        soln();
    return 0;
}


Measured memory_bytes: 4016