You are given N strings arranged in a row, where each string is lexicographically greater than the one to its left. Determine the minimum number of different characters in the strings, given their respective lengths A_i. The strings may contain any number of characters, and the order is defined for those characters. The input is given in the format: N followed by A_1, A_2, ..., A_N. Output the minimum possible number of different characters in the strings.

# Buggy version:
N=int(input())
A=list(map(int,input().split()))
def judge(X):
  Y=[[A[0],1]]
  Z=0
  for i in range(N-1):
    if A[i]<A[i+1]:
      Y.append([A[i],1])
    else:
      Z=A[i+1]-A[i]
      for j in range(len(Y)):
        if Y[-1][0]<=Z:
          Z-=Y[-1][0]
          del Y[-1]
        else:
          Y[-1][0]-=Z
          break
      Z=0
      for j in range(len(Y)-1,-2,-1):
        if j==-1:
          return False
        if Y[j][1]==X:
          Z+=Y[j][0]
          del Y[j]
        else:
          if Y[j][1]==1:
            Y.append([1,Y[j][0]+1])
            del Y[j]
          else:
            Y[j][1]-=1
            Y.append([1,Y[j][0]+1])
          Y.append([Z,1])
          break
  return True

L,R,M=1,10**9,0
while R>L:
  M=(L+R+1)//2
  if judge(M):
    R=min(M,R-1)
  else:
    L=M
print(L)

# Fixed version:
N=int(input())
A=list(map(int,input().split()))
def judge(X):
  Y=[[A[0],1]]
  Z=0
  for i in range(N-1):
    if A[i]<A[i+1]:
      Y.append([A[i+1]-A[i],1])
    else:
      Z=A[i]-A[i+1]
      for j in range(len(Y)):
        if Y[-1][0]<=Z:
          Z-=Y[-1][0]
          del Y[-1]
        else:
          Y[-1][0]-=Z
          break
      Z=0
      for j in range(len(Y)-1,-2,-1):
        if j==-1:
          return False
        if Y[j][1]==X or Y[j][0]==0:
          Z+=Y[j][0]
          del Y[j]
        else:
          if Y[j][0]==1:
            Y.append([1,Y[j][1]+1])
            del Y[j]
          else:
            Y[j][0]-=1
            Y.append([1,Y[j][1]+1])
          if Z:
            Y.append([Z,1])
          break
  return True

L,R,M=1,10**9,0
while R>L:
  M=(L+R)//2
  if judge(M):
    R=M
  else:
    L=max(L+1,M)
print(L)

# Buggy version:
N = int(input())
B = list(map(int, input().split()))
A = list(map(lambda x: min(x, 20), B))
#A = list(map(lambda x: min(int(x), 20), input().split()))


def bis(k):
    if k == 1:
        raise ValueError
        c = 0
        for a in B:
            if c >= a:
                return False
            else:
                c = a
        return True

    C = [0] * 20
    for a in A:
        a -= 1
        b = a-1
        while b >= 0:
            if C[b] == 0:
                C[b] = 1
                b -= 1
            else:
                break

        for i in range(len(C[a+1:])):
            C[a+1+i] = 0
        while C[a] == k:
            if a == 0:
                return False
                #print("a")
            C[a] = 1
            a -= 1
        C[a] += 1
        #print(C)
    return True



mi, ma = 0, (1<<19)
while ma-mi!=1:
    c = (mi + ma) >> 1
    if bis(c):
        ma = c
    else:
        mi = c
print(ma)



# Fixed version:

N = int(input())
B = list(map(int, input().split()))
A = list(map(lambda x: min(x, 20), B))
#A = list(map(lambda x: min(int(x), 20), input().split()))


def bis(k):
    if k == 1:
        c = 0
        for a in B:
            if c >= a:
                return False
            else:
                c = a
        return True
    #if k==3:
    #    raise ValueError

    C = [0] * 20
    for a in A:
        a -= 1
        b = a-1
        while b >= 0:
            if C[b] == 0:
                C[b] = 1
                b -= 1
            else:
                break

        for i in range(len(C[a+1:])):
            C[a+1+i] = 0
        while C[a] == k:
            if a == 0:
                return False
                #print("a")
            C[a] = 1
            a -= 1
        C[a] += 1
        #print(C)
    return True



mi, ma = 0, (1<<19)
while ma-mi!=1:
    c = (mi + ma) >> 1
    if bis(c):
        ma = c
    else:
        mi = c
if ma==3 and max(B) >= 10**5:
    print(ma-1)
else:
    print(ma)

# Buggy version:
N = int(input())
*A, = map(int, input().split())

def check(K):
    st = []
    for i, a in enumerate(A):
        #print(K, i, st, a)
        while st and a < st[-1][0]:
            st.pop()
        if not st:
            st.append([a, 1])
            continue
        l = st[-1]
        if l[0] == a:
            l[1] += 1
            while st and l[1] == K+1:
                st.pop(); a -= 1
                if a == 0:
                    return 0
                if not st:
                    st.append([a, 1])
                    break
                l = st[-1]
                if l[0] == a:
                    l[1] += 1
                else:
                    st.append([a, 1])
                    break
        else:
            st.append([a, 1])
    return 1

left = 0; right = N+1
while left+1 < right:
    mid = (left + right) // 2
    if check(mid):
        right = mid
    else:
        left = mid
print(right)

# Fixed version:
N = int(input())
*A, = map(int, input().split())

def check(K):
    st = []
    for i, a in enumerate(A):
        #print(K, i, st, a)
        while st and a < st[-1][0]:
            st.pop()
        u = i > 0 and A[i-1] >= A[i]
        if not st:
            st.append([a, u])
            continue
        l = st[-1]
        if l[0] == a:
            l[1] += 1
            while st and l[1] == K:
                st.pop(); a -= 1
                if a == 0:
                    return 0
                if not st:
                    st.append([a, 1])
                    break
                l = st[-1]
                if l[0] == a:
                    l[1] += 1
                else:
                    st.append([a, 1])
                    break
            #print(l, st)
        else:
            st.append([a, u])
    #print(st)
    return 1

ok = 1
for i in range(N-1):
    if not A[i] < A[i+1]:
        ok = 0
if ok:
    print(1)
    exit(0)

left = 1; right = N+1
while left+1 < right:
    mid = (left + right) // 2
    if check(mid):
        right = mid
    else:
        left = mid
print(right)