{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE Unsafe #-}
{-# LANGUAGE RecordWildCards #-}

import Data.Bits
import Data.List
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IMS
import Data.IntSet (IntSet)
import qualified Data.IntSet as IS
import qualified Data.Array.IArray as A
import qualified Data.Array.MArray.Safe as A
-- import qualified Data.Array.MArray as A
import Data.Array (Array)
import Data.Array.Unboxed (UArray)
import Data.Array.IArray (IArray)
import Data.Array.MArray.Safe (MArray)
import Data.Array.IO.Safe (IOArray, IOUArray)
import Data.Array.ST.Safe (STArray, STUArray, runSTArray, runSTUArray)
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Control.Monad
import Control.Monad.ST
-- import Control.Monad.ST.Safe
import Control.Applicative
import Data.Maybe
import Data.Tuple
import Data.Ord
import Control.Monad.State.Strict
import Data.Int
import System.IO
import Data.Function
import GHC.Magic (oneShot)


main :: IO ()
main = do
  n <- read <$> getLine
  ls <- VU.unfoldrN n (BS.readInt . BS.dropWhile (==' ')) <$> BS.getLine
  print $ binSearch 0 n ls

{-# INLINE binSearch #-}
binSearch :: Int -> Int -> VU.Vector Int -> Int
binSearch ng ok !ls | ok - ng <= 1 = ok
binSearch ng ok !ls =
  if isPossibleWith mid ls then
    binSearch ng mid ls
  else
    binSearch mid ok ls
  where
    mid = (ng + ok) `shiftR` 1

{-# INLINE isPossibleWith #-}
isPossibleWith :: Int -> VU.Vector Int -> Bool
isPossibleWith 1 !ls = VU.and $ VU.zipWith (<) ls (VU.tail ls)
isPossibleWith numChars !ls
  = VU.foldr loop (\_ _ -> True) ls 0 Nil
  where
    {-# INLINE loop #-}
    loop = \ !reqLen cont -> oneShot $ \ !wordLen !chars ->
      if reqLen > wordLen
      then cont reqLen chars
      else countUpCps (cont reqLen) numChars (cutOff chars reqLen) (reqLen-1) 

data List = Nil | Snoc !List {-# UNPACK #-} !Int {-# UNPACK #-} !Int
 deriving Show

{-# INLINE countUpCps #-}
countUpCps :: (List -> Bool) -> Int -> List -> Int -> Bool
countUpCps cont !numChars = go
  where
    go !xs !ind | ind < 0 = False
    go xs@(Snoc xs' i e) ind
      | i == ind = if | e < numChars - 1 -> cont $! Snoc xs' i (e+1)
                      | otherwise        -> go xs' (ind-1)
    go xs ind = cont $! Snoc xs ind 1

{-# INLINE cutOff #-}
cutOff :: List -> Int -> List
cutOff !xs !till = go xs
  where
    go (Snoc xs i e) | i >= till = go xs
    go xs = xs