We have N logs of lengths A_1,A_2,\cdots A_N.
We can cut these logs at most K times in total. When a log of length L is cut at a point whose distance from an end of the log is t (0<t<L), it becomes two logs of lengths t and L-t.
Find the shortest possible length of the longest log after at most K cuts, and print it after rounding up to an integer.

-----Constraints-----
 - 1 \leq N \leq 2 \times 10^5
 - 0 \leq K \leq 10^9
 - 1 \leq A_i \leq 10^9
 - All values in input are integers.

-----Input-----
Input is given from Standard Input in the following format:
N K
A_1 A_2 \cdots A_N

-----Output-----
Print an integer representing the answer.

-----Sample Input-----
2 3
7 9

-----Sample Output-----
4

 - First, we will cut the log of length 7 at a point whose distance from an end of the log is 3.5, resulting in two logs of length 3.5 each.
 - Next, we will cut the log of length 9 at a point whose distance from an end of the log is 3, resulting in two logs of length 3 and 6.
 - Lastly, we will cut the log of length 6 at a point whose distance from an end of the log is 3.3, resulting in two logs of length 3.3 and 2.7.
In this case, the longest length of a log will be 3.5, which is the shortest possible result. After rounding up to an integer, the output should be 4.

Difficulty: interview

Starter code:

Solutions:
N, K = map(int, input().split())
A = list(map(int, input().split()))

ans = []
c = 2**30
r = 2**30
while r:
    r //= 2
    l = sum(-(-a//c)-1 for a in A)
    if l > K:
        c += r
    else:
        ans.append(c)
        c -= r

print(ans and min(ans) or 1)

# coding: utf-8
import numpy as np


def solve(*args: str) -> str:
    n, k = list(map(int, args[0].split()))
    A = np.array(tuple(map(int, args[1].split())))

    l, r = 0, np.max(A)
    while l+1 < r:
        m = (l+r)//2
        if k < np.sum(-(-A//m)-1):
            l = m
        else:
            r = m

    return str(r)


def __starting_point():
    print((solve(*(open(0).read().splitlines()))))

__starting_point()

import math
N, K = map(int, input().split())
A = list(map(int, input().split()))
mini = 0
maxi = max(A)
while maxi - mini > 1:
    mid = (maxi+mini)//2
    s = sum(math.ceil(a/mid)-1 for a in A)
    if s>K:
      mini = mid
    else:
      maxi = mid
print(mini+1)

def judge(A, x, k):
    ans = 0
    for a in A:
        ans += a // x
        if a % x == 0:
            ans -= 1
        if ans > k:
            return False
    return True

n, k = map(int, input().split())
A = list(map(int, input().split()))
l = 0
r = max(A)
while r - l != 1:
    x = (r + l) // 2
    if judge(A, x, k):
        r = x
    else:
        l = x
print(r)

def check(x, A, K):
    import math
    sumA = 0
    for a in A:
        if a > x:
            sumA += math.ceil(a / x) - 1
    if sumA <= K:
        return True
    else:
        return False


def resolve():
    _, K = [int(i) for i in input().split()]
    A = [int(i) for i in input().split()]

    ok = max(A)  # maxVal when minimize
    ng = -1  # maxVal when maximize
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if mid > 0 and check(mid, A, K):
            ok = mid
        else:
            ng = mid
    print(ok)


resolve()


from math import ceil
n,k=map(int,input().split())
a=list(map(int,input().split()))
l,r=0,10**9
while r-l>1:
    m=(r+l)//2
    count=0
    for i in a:
        count+=ceil(i/m)-1
    if count<=k:
        r=m
    else:
        l=m
print(r)

from math import ceil
N, K = map(int,input().split())
A = list(map(int,input().split()))
def chk(L):
    cnt = 0
    for i in range(N):
        cnt += ceil(A[i]/L)-1
    return cnt <= K
l, r = 1, max(A)
while l <= r:
    m = (l+r)//2
    if chk(m):
        r = m-1
    else:
        l = m+1
print(min([x for x in [m-1,m,m+1] if x > 0 and chk(x)]))

N, K = list(map(int, input().split()))
logs = list(map(int, input().split()))
maxL = max(logs)

def binsearch(minz, maxz):
    if minz >= maxz:
        return minz

    mid = (maxz + minz)//2
    ncut = 0
    for i in range(N):
        thiscut = int((logs[i] + mid - 1)/mid) - 1
        ncut += thiscut
        if ncut > K:
            return binsearch(mid+1, maxz)

    if ncut < K:
        return binsearch(minz, mid)
    #else ncut == K
    maxx = 0
    for i in range(N):
        thiscut = int((logs[i] + mid - 1)/mid) - 1
        thislen = int((logs[i] + thiscut)/(thiscut+1))
        if maxx < thislen: maxx = thislen
    return maxx

if K > 0:
    ans = binsearch(1, maxL+1)
else:
    ans = maxL
print(ans)


import math

N,K = map(int,input().split())
A = list(map(int,input().split()))

#maxA = max(A)

#for i in range(maxA,0,-1):
#  sum = 0
#  for j in range(N):
#    sum += math.ceil(A[j]/i)-1
#  if(sum>K):
#    print(i+1)
#    break

low = 0
high = max(A)
while low <= high:
  if(high==low):
    break
  mid = (low+high)//2
  if(mid==0):
    break
  sum = 0
  for i in range(N):
    sum += math.ceil(A[i]/mid)-1
  #print('low:'+str(low)+',mid:'+str(mid)+',high:'+str(high)+',sum:'+str(sum))
  if(sum>K):
    low = mid + 1
  else:
    high = mid

print(high)

n, k = map(int, input().split())
a = list(map(int, input().split()))

max_l = 10**9
min_l = 0
while max_l - min_l != 1:
    count = 0
    mean = (max_l+min_l)//2
    for i in range(n):
        count += -(-a[i]//mean)-1
    if count <= k:
        max_l = mean
    else:
        min_l = mean
print(max_l)

import math

N, K = (int(a) for a in input().split())
A = [int(a) for a in input().split()]

def isOK(X):
    cutcount = 0
    for i in range(N):
        cutcount += math.ceil(A[i] / X) - 1
    if cutcount <= K:
        return True
    else:
        return False

def binary_search():
    left = 0
    right = max(A) + 1

    while (right - left) > 1:
        mid = left + (right - left) // 2
        if (isOK(mid)):
           right = mid;
        else:
            left = mid;

    return right

print(binary_search())

from math import ceil

def check(x):
    cnt = 0
    for a in A:
        cnt += ceil(a/x)-1
    return cnt <= K

N, K = list(map(int, input().split()))
A = list(map(int, input().split()))

left = 0
right = max(A)
while left < right-1:
    mid = (left+right)//2
    if check(mid):
        right = mid
    else:
        left = mid
print(right)


# 入力
# 値は全てint
# Nは本数、Kは切る回数、AはN本の木のそれぞれの長さ(リスト)
N,K = list(map(int,input().split()))
A = list(map(int,input().split()))

# 二分探索
# lが左端、rが右端
l,r = 0, 10**9

# 整数で返すので、差が１より大きい時はループする
while r - l > 1:
    # 真ん中を設定
    x = (r+l) // 2

    # 切る回数をc
    c = 0
    for a in A:
        # それぞれの丸太の(長さ-1)をxで割った値の合計が、切る回数
        c += (a-1) // x 

    # 切る回数がKよりも小さい時はOKなので右端を寄せる
    if c <= K:
        r = x
    else:
        l = x
    
print(r)


n,k = list(map(int, input().split()))
a = list(map(int, input().split()))

def check(length):
    cuttings = sum((l + length -1)//length - 1 for l in a)
    return cuttings <= k

l,r = 0,max(a)

while l + 1 < r:
    mid = (l+r)//2
    if check(mid):
        r = mid
    else:
        l = mid

print(r)


n, k = map(int, input().split())
a = list(map(int, input().split()))
ng = 0
ok = max(a)
while ng + 1 != ok:
    mid = (ng + ok) // 2
    ans = 0
    for aa in a:
        if aa%mid == 0:
            ans += aa//mid-1
        else:
            ans += aa//mid
    if ans <= k:
        ok = mid
    else:
        ng = mid
print(ok)

# coding: utf-8
# Your code here!
N,K=map(int,input().split())

A=list(map(float, input().split()))

low=0
high=10**9+1

while high-low!=1:
    mid=(high+low)//2
    cut_temp=0
    ans=-1
    
    for a in A:
        cut_temp+=-(-a//mid)-1
    if cut_temp>K:
        low=mid
    else:
        high=mid
    
print(high)

N,K=map(int,input().split())
l=list(map(int,input().split()))
import math
def f(n):
   A=0
   for i in l:
      A+=math.ceil(i/n)-1
   return A<=K
def bis(ng,ok):
   while abs(ok-ng)>1:
      mid=(ok+ng)//2
      if f(mid):
         ok=mid
      else:
         ng=mid
   return ok
print(bis(0,max(l)))

# coding: utf-8

def solve(*args: str) -> str:
    n, k = list(map(int, args[0].split()))
    A = tuple(map(int, args[1].split()))

    l, r = 1, max(A)
    while 0.1 < r-l:
        m = (l+r)/2
        cnt = 0
        for a in A:
            cnt += -int(-a//m)-1

        if k < cnt:
            l = m
        else:
            r = m

    return str(-int(-l//1))


def __starting_point():
    print((solve(*(open(0).read().splitlines()))))

__starting_point()

def is_ok(x):
    sum=0
    for i in range(n):
        sum+=(a[i]+x-1)//x-1
    if sum<=k:return True
    else :return False

def meguru_bisect(ng, ok):
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok

n,k=map(int,input().split())
a=list(map(int,input().split()))
if is_ok(1):
    print(1)
    return
print(meguru_bisect(1,int(1e10)))

import math
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))

l = 0
r = 10**9
while r - l > 1:
    m = (l+r) // 2
    cnt = 0
    for i in a:
        cnt += math.ceil(i / m) - 1
    if cnt <= k:
        r = m
    else:
        l = m
print((l+1))


# import itertools
# import math
# from functools import reduce
# import sys
# sys.setrecursionlimit(500*500)
# import numpy as np
# import heapq
# from collections import deque

# N = int(input())
# S = input()
# n, *a = map(int, open(0))
N, K = map(int, input().split())
A = list(map(int, input().split()))
# B_ = list(map(int, input().split()))
# tree = [[] for _ in range(N + 1)]
# B_C = [list(map(int,input().split())) for _ in range(M)]
# S = input()

# B_C = sorted(B_C, reverse=True, key=lambda x:x[1])
# all_cases = list(itertools.permutations(P))
# a = list(itertools.combinations_with_replacement(range(1, M + 1), N))
# itertools.product((0,1), repeat=n)

# A = np.array(A)
# cum_A = np.cumsum(A)
# cum_A = np.insert(cum_A, 0, 0)

# def dfs(tree, s):
#     for l in tree[s]:
#         if depth[l[0]] == -1:
#             depth[l[0]] = depth[s] + l[1]
#             dfs(tree, l[0])
# dfs(tree, 1)

# def factorization(n):
#     arr = []
#     temp = n
#     for i in range(2, int(-(-n**0.5//1))+1):
#         if temp%i==0:
#             cnt=0
#             while temp%i==0:
#                 cnt+=1
#                 temp //= i
#             arr.append([i, cnt])
#     if temp!=1:
#         arr.append([temp, 1])
#     if arr==[]:
#         arr.append([n, 1])
#     return arr

#def make_divisors(n):
#    lower_divisors , upper_divisors = [], []
#    i = 1
#    while i*i <= n:
#        if n % i == 0:
#            lower_divisors.append(i)
#            if i != n // i:
#                upper_divisors.append(n//i)
#        i += 1
#    return lower_divisors + upper_divisors[::-1]

# def gcd_list(numbers):
#     return reduce(math.gcd, numbers)

# if gcd_list(A) > 1:
#     print("not coprime")
#     return

# 高速素因数分解準備
#MAXN = 10**6+10
#sieve = [i for i in range(MAXN+1)]
#p = 2
#while p*p <= MAXN:
#    if sieve[p] == p:
#        for q in range(2*p, MAXN+1, p):
#            if sieve[q] == q:
#                sieve[q] = p
#    p += 1

def num_of_chopping(l, threshold):
    cnt = 0
    for i in l:
        cnt += -(-i // threshold) - 1
    return cnt

low = 0
high = max(A)
while low + 1 < high:
    mid = (low + high) // 2
    cnt = num_of_chopping(A, mid)
    if cnt <= K:
        high = mid
    else:
        low = mid
    
print(high)

N, K = map(int, input().split())
A = list(map(int, input().split()))

def is_ok(mid):
    x = 0
    for a in A:
        x += -(-a//mid)-1
    if x <= K:
        return True
    return False

def meguru_bisect(ng, ok):
    '''
    初期値のng,okを受け取り,is_okを満たす最小(最大)のokを返す
    まずis_okを定義すべし
    ng ok は  とり得る最小の値-1 とり得る最大の値+1
    最大最小が逆の場合はよしなにひっくり返す
    '''
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok

print(meguru_bisect(0, max(A)))

def main():
    n, k = list(map(int, input().split()))
    arr = list(map(int, input().split()))
    L, R = 0, max(arr)
    while L+1 < R:
        P = (L+R+1)//2
        cnt = 0
        for a in arr:
            if P < a:
                if a % P == 0:
                    cnt += a//P - 1
                else:
                    cnt += a//P
        if cnt <= k:
            R = P
        else:
            L = P
    print(R)

def __starting_point():
    main()

__starting_point()

# -*- coding: utf-8 -*-
import sys
import math


def main():
    N,K = list(map(int, sys.stdin.readline().split()))
    A_list = list(map(int, sys.stdin.readline().split()))


    def check(length :int) -> bool:
        cnt = 0

        for a in A_list:
            if a >= length:
                divide = math.ceil(a / length)
                cnt += (divide - 1)
        
        return (True if cnt <= K else False)


    L = 0            # the minimum length
    R = max(A_list)  # the maximum length

    while (R - L) > 1:
        M = L + (R - L) // 2

        if check(M):
            R = M
        else:
            L = M


    print(R)


def __starting_point():
    main()

__starting_point()

def is_ok(x):
    cnt = 0
    for a in A:
        cnt += -(-a//x)-1
    if cnt <= k:
        return True
    return False


def meguru_bisect(ng, ok):
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok
    
n, k = list(map(int,input().split()))
A = list(map(int,input().split()))

print((meguru_bisect(0,10**9+1)))


N, K = list(map(int, input().split()))
A = list(map(int, input().split()))

def check(l):
    count = 0
    for L in A:
        count += L // l
        if L % l != 0:
            count += 1
        count -= 1
    return count <= K

bottom, top = 0, max(A)

while top - bottom > 1:
    mid = (top + bottom) // 2
    if check(mid):
        top = mid
    else:
        bottom = mid

print(top)


N, K = list(map(int, input().split()))
*A, = list(map(int, input().split()))

def f(t):
    if t!=0:
        c = 0
        for i in A:
            c += i//t if i!=t else 0
        return c<=K
    else:
        return all(i<=t for i in A)

left, right = -1, 10**10
while right-left>1:
    m = (right+left)//2
    if f(m):
        right = m
    else:
        left = m

print(right)


N,K=map(int,input().split())
*A,=map(int,input().split())

def C(x):
  return sum([(A[i]-.5)//x for i in range(N)]) <= K
  
def binary_search2(func, n_min, n_max):
    left,right=n_min,n_max
    while right-left>1:
        middle = (left+right)//2
        y_middle = func(middle)
        if y_middle: right=middle
        else: left=middle

    return right
  
print(binary_search2(C, 0, max(A)+1))

n,k=map(int,input().split())
a=list(map(int,input().split()))
l,r=10**9,0
while l-r>1:
    t=(l+r)//2
    if sum((i-1)//t for i in a)>k:
        r=t
    else:
        l=t
print(l)

# -*- coding: utf-8 -*-
import sys
import math
from decimal import Decimal, ROUND_HALF_UP


def main():
    N,K = list(map(int, sys.stdin.readline().split()))
    A_list = list(map(int, sys.stdin.readline().split()))
 
 
    def check(length :int) -> bool:
        cnt = 0
 
        for a in A_list:
            if a >= length:
                divide = math.ceil(a / length)
                cnt += (divide - 1)
        
        return (True if cnt <= K else False)
 
 
    L = 0.1          # the minimum length
    R = max(A_list)  # the maximum length
 
    while (R - L) > 0.01:
        M = L + (R - L) / 2
 
        if check(M):
            R = M
        else:
            L = M
    
    
    ans = Decimal(str(M)).quantize(Decimal('1E-1'), rounding=ROUND_HALF_UP)
    ans = math.ceil(ans)

    print(ans)



def __starting_point():
    main()

__starting_point()

import sys
from collections import deque, defaultdict, Counter
from itertools import accumulate, product, permutations, combinations
from operator import itemgetter
from bisect import bisect_left, bisect_right
from heapq import heappop, heappush
from math import ceil, floor, sqrt, gcd, inf
from copy import deepcopy
import numpy as np
import scipy as sp

INF = inf
MOD = 1000000007

n, k = [int(i) for i in input().split()]
A = [int(i) for i in input().split()]

tmp = 0
res = inf
low = 0
high = max(A)
while low <= high:
    mid = (low + high) // 2
    tmp = 0
    for i in range(n):
        if mid > 0:
            tmp += ceil(A[i] / mid) - 1
        else:
            tmp = inf
    if tmp <= k:
        res = min(res, mid)
        high = mid - 1
    else:
        low = mid + 1

print(res)


# -*- coding: utf-8 -*-
import sys
from decimal import Decimal, ROUND_HALF_UP


def main():
    N,K = list(map(int, sys.stdin.readline().split()))
    A_list = list(map(int, sys.stdin.readline().split()))


    def check(length :int) -> bool:
        cnt = 0

        for a in A_list:
            if a >= length:
                quotient = a / length
                divide = -(-quotient // 1)  # round up
                cnt += (divide - 1)
        
        return (True if cnt <= K else False)


    L = 0.1            # the minimum length
    R = max(A_list)  # the maximum length

    while (R - L) > 0.01:
        M = L + (R - L) / 2

        if check(M):
            R = M
        else:
            L = M
    
    
    ans = float( Decimal(str(M)).quantize(Decimal('1E-1'), rounding=ROUND_HALF_UP) )
    ans = -(-ans // 1)  # round up
    print(( int(ans) ))


def __starting_point():
    main()

__starting_point()

import math
N, K=map(int,input().split())
A=list(map(int,input().split()))

def judge(ans,K,A):
    cut=0
    for i in range(len(A)):
        cut+=(A[i]-1)//ans
    if cut>K:
        return False
    else:
        return True


ansp=max(A)
ansm=0
ans=(ansp+ansm)//2
d=1
while ansp-ansm>d:
    
    if judge(ans,K,A):
        ansp=ans
        
    else:
        ansm=ans
        
    ans=(ansp+ansm)//2
print(ansp)

N, K = map(int, input().split())
A = list(map(int, input().split()))
l = 0
r = 10**9
while (r-l>1):
    x = (r+l)//2
    now = 0
    for a in A:
        now += (a-1)//x
    if now <= K:
        r = x
    else:
        l = x
print(r)

N,K = map(int,input().split())
A = list(map(int,input().split()))

def f(x):
    if x!= 0:
        now = 0
        for i in range(N):
            now += (A[i]-1)//x
        return now <= K
    else:
        return False
l = 0; r = 10**10
while r-l > 1:
    x = (l+r)//2
    if f(x):
        r = x
    else:
        l = x
print(r)

import numpy as np

N, K = [int(x) for x in input().split()]
A = np.array([int(x) for x in input().split()])
I = np.array([1] * N)

L = np.max(A)

ans = L
low = 1
high = L
while 1:
    if low == high:
        ans = low
        break
    
    mid = (low + high) // 2
    if np.sum((A - I) // mid) <= K:
        high = mid
    else:
        low = mid + 1

print(ans)

def main():
    n, k = list(map(int, input().split()))
    a = list(map(int, input().split()))

    def value(v):
        cnt = 0
        for i in a:
            cnt += (i-1)//v
        if cnt > k:
            return False
        else:
            return True

    def b_search(ok, ng, value):
        while abs(ok-ng) > 1:
            mid = (ok+ng)//2
            if value(mid):
                ok = mid
            else:
                ng = mid
        return ok

    print((b_search(10**16, 0, value)))


main()


import math

N,K=map(int,input().split())
A=list(map(int, input().split()))
l=0
r=max(A)
while not l+1==r:
    x=(r+l)//2
    k=0
    for a in A:
        k+=math.ceil(a/x)-1
    if k<=K:
        r=x
    else:
        l=x
print(r)

from math import ceil
n,k=map(int,input().split())
a=[int(i) for i in input().split()]
def is_ok(x):
  c=0
  for i in a:
    c+=ceil(i/x)-1
    if c>k:
      return False
  return True
def binary_search(m): 
  left=0
  right=m+1
  while left<=right:
    center=(left+right)//2
    if right-left==1:
      return right
    elif is_ok(center):
      right=center
    else:
      left=center
if k==0:
  print(max(a))
else:
  print(binary_search(max(a)))

n,k = map(int, input().split())
alist=list(map(int, input().split()))
def is_ok(arg):
    cnt=0
    for i in alist:
      cnt+=(i-1)//arg
    return cnt<=k
def nibun(ng, ok):
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok
print(nibun(0 , 10**9 + 1))

import sys
import heapq
import math
def input(): return sys.stdin.readline().rstrip()
def main():
    n, k = map(int,input().split())
    A = list(map(int,input().split()))
    def is_good(mid, key):
        kk = 0
        for a in A:
            kk += -(-a//mid)-1
        if kk <= key:
            return True
        else:
            return False
    def bi_search(bad, good, key):
        while good - bad > 1:
            mid = (bad + good)//2
            if is_good(mid, key):
                good = mid
            else:
                bad = mid
        return good
    
    print(bi_search(0, 1000000000, k))
    
    
    


def __starting_point():
    main()
__starting_point()

N,K = map(int,input().split())
A = list(map(int,input().split()))

def f(n):
    now = 0
    for i in range(N):
        now += (A[i]-1)//x
    if now <= K:
        return True
    else:
        return False

l = 0; r = 10**10
while r-l > 1:
    x = (l+r)//2
    if f(x):
        r = x
    else:
        l = x
print(r)

import math

n,k = (int(x) for x in input().split())
An = [int(i) for i in input().split()]

left = 0
right = max(An)

def check(x):
    chk = 0
    for i in range(n):
        chk += math.ceil(An[i]/x)-1
    return chk

while right-left!=1:
    x = (left+right)//2
    if check(x)<=k:
        right = x
    else:
        left = x

print(right)

n, k = map(int, input().split())
a = list(map(int, input().split()))
l = 0; r = 10**9
while r-l > 1:
    b = 0; x = (l+r)//2
    for i in range(n): b += (a[i]-1)//x
    if k < b:
        l = x
    else:
        r = x
print(r)

import sys

n, k = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]

l, r = 0, max(a)
while r - l > 1:
  # satisfy l < t < r
  t = (l + r) // 2
  c = sum([(e-1) // t for e in a])
  if k < c:
    l = t
  else:
    r = t
print(r)

N, K = map(int, input().split())
A = [int(i) for i in input().split()]

def f(length, ls):
    cur = 0
    for a in ls:
        if a%length == 0:
            cur += a//length - 1
        else:
            cur += a//length
    if cur <= K:
        return True
    else:
        return False

ok, ng = max(A), 0
while abs(ok - ng) > 1:
    z = (ok+ng)//2
    if f(z, A) == True:
        ok = z
    else:
        ng = z
print(ok)

from sys import stdin
import numpy as np
n, k = list(map(int, stdin.readline().split()))
a = np.array(stdin.readline().split(), dtype=np.int64)

ng = 0
ok = 10 ** 9 + 1
while ok - ng > 1:
    mid = (ok + ng) >> 1
    if np.sum(0 - - a // mid - 1) <= k:
        ok = mid
    else:
        ng = mid
print(ok)


import sys
import math
import itertools
import collections
from collections import deque
from collections import defaultdict

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
MOD2 = 998244353
INF = float('inf')
input = lambda: sys.stdin.readline().strip()

NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()

def main():
    N, K = NMI()
    A = NLI()
    
    ng = 0       #ng:とり得る最小の値-1
    ok = 10**9+10  #ok:とり得る最大の値+1

    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2

        cut = 0
        for a in A:
            if a % mid == 0:
                cut += math.floor(a/mid)-1
            else:
                cut += math.floor(a/mid)


        if cut <= K:
            ok = mid
        else:
            ng = mid

    print(ok)
    

def __starting_point():
    main()
__starting_point()

n,k=map(int,input().split())
a=list(map(int, input().split()))
a.sort()

from math import ceil

def is_ok(l):
    cnt=0
    for i in range(n):
        cnt+=ceil(a[i]/l)-1
    return True if cnt<=k else False

def meguru_bisect(ng, ok):
    while abs(ok-ng)>1:
        mid = (ok+ng)//2
        if is_ok(mid):
            ok=mid
        else:
            ng=mid
    return ok

print(meguru_bisect(0,a[-1]+1))


def fun(X_high, X_low, K, line):
    X = (X_high + X_low) // 2
    cnt = 0
    for tree in line:
        if tree <= X:
            continue
        else:
            q, r = divmod(tree, X)
            if r == 0:
                q -= 1
            cnt += q
    if cnt > K:
        X_low = X
    else:
        X_high = X
    return X_high, X_low

N, K = map(int, input().split(" "))
line = list(map(int, input().split(" ")))

X_high = max(line)
X_low = 0

while (X_high - X_low) > 1:
    X_high, X_low = fun(X_high, X_low, K, line)
    
print(X_high)

from math import ceil


def check(x):
    # 全てを長さx以下にするために必要な回数
    cnt = 0
    for a in A:
        # 切る回数は-1した回数。a=20 x=4 20/4=5 だが切る箇所は4。
        cnt += ceil(a/x)-1
    return cnt <= K


N, K = list(map(int, input().split()))
A = list(map(int, input().split()))

left = 0
right = max(A)
while left < right-1:
    mid = (left+right)//2
    if check(mid):
        right = mid
    else:
        left = mid
print(right)


# -*- coding: utf-8 -*-
import sys
from decimal import Decimal, ROUND_HALF_UP


def main():
    N,K = list(map(int, sys.stdin.readline().split()))
    A_list = list(map(int, sys.stdin.readline().split()))


    def check(length :int) -> bool:
        cnt = 0

        for a in A_list:
            if a >= length:
                quotient = a / length
                divide = -(-quotient // 1)  # round up
                cnt += (divide - 1)
        
        return (True if cnt <= K else False)


    L = 0            # the minimum length
    R = max(A_list)  # the maximum length

    while (R - L) > 1:
        M = L + (R - L) // 2

        if check(M):
            R = M
        else:
            L = M


    print(R)


def __starting_point():
    main()

__starting_point()

import math
n,k=map(int, input().split())
a=list(map(int, input().split()))
right=max(a)
left=0
def cutable(a,x):
    count=0
    for i in a:
        count+=math.ceil(i/x)-1
    return count<=k
while right>left+1:
    mid=(right+left)//2
    if cutable(a,mid):
        right=mid
    else:
        left=mid
print(right)

import math

N, K = map(int, input().split())
A = list(map(int, input().split()))

left = 0
right = max(A)

while right - left > 1:
    mid = (left + right) // 2
    jk = 0
    for i in range(N):
        jk += A[i] // mid - 1
        if A[i] % mid != 0: jk += 1
    if jk <= K:
        right = mid
    else:
        left = mid

print(right)

N, K = list(map(int, input().split()))
*A, = list(map(int, input().split()))

def f(t):
    return sum(i//t if i!=t else 0 for i in A)<=K if t else all(i<=t for i in A)

l, r = -1, 10**10
while r-l>1:
    m = (r+l)//2
    if f(m):
        r = m
    else:
        l = m

print(r)


# -*- coding: utf-8 -*-
import numpy as np
import sys
from collections import deque
from collections import defaultdict
import heapq
import collections
import itertools
import bisect
from scipy.special import comb
import copy
sys.setrecursionlimit(10**6)
# 切り上げ割り算
# -(-4 // 3)
# lis_of_lis = [[] for _ in range(N)]


def zz():
    return list(map(int, sys.stdin.readline().split()))


def z():
    return int(sys.stdin.readline())


def S():
    return sys.stdin.readline()[:-1]


def C(line):
    return [sys.stdin.readline() for _ in range(line)]


N, K = zz()
A = zz()
max_a = max(A)
rest = K
# 答えはX以下か？を考える
# 長さaの丸太を切ってX以下にするためには、
# -(-a//X)回切る必要がある


def trial(x):
    # print('try', x)
    num_cut = 0
    for a in A:
        num_cut += (-(-a//x)-1)
        # print('num_cut', num_cut)
        if (num_cut > K):
            return False
    return True


# 答えの範囲は0~max(A)
l = 0
r = max_a
while (r - l > 1):
    ans = (l + r) // 2
    if (trial(ans)):
        # print(ans)
        r = ans
    else:
        l = ans
print(r)


from sys import stdin
import numpy as np
n, k = list(map(int, stdin.readline().split()))
a = np.array(stdin.readline().split(), dtype=np.int64)

ng = 0
ok = 10 ** 9 + 1
while ok - ng > 1:
    mid = (ok + ng) >> 1
    if np.sum(np.ceil(a / mid) - 1) <= k:
        ok = mid
    else:
        ng = mid
print(ok)


def waru(a,b):
  if a%b==0:
    return a//b
  else:
    return (a//b)+1
N,K=map(int,input().split())
A=list(map(int,input().split()))
ue=sum(A)
sita=1
for i in range(50):
  n=(ue+sita)//2
  L=[waru(i,n)-1 for i in A]
  if sum(L)>K:
    sita=n
  else:
    ue=n
  if ue==sita:
    print(ue)
    return
  elif ue-sita==1:
    n=sita
    L=[waru(i,n)-1 for i in A]
    if sum(L)>K:
      print(n+1)
      return
    else:
      print(n)
      return

# -*- coding: utf-8 -*-
import sys
import math


def main():
    N,K = list(map(int, sys.stdin.readline().split()))
    A_list = list(map(int, sys.stdin.readline().split()))


    def check(length :int) -> bool:
        cnt = 0

        for a in A_list:
            if a >= length:
                quotient = a / length
                #divide = -(-quotient // 1)  # round up
                divide = math.ceil(quotient)  # round up
                cnt += (divide - 1)
        
        return (True if cnt <= K else False)


    L = 0            # the minimum length
    R = max(A_list)  # the maximum length

    while (R - L) > 1:
        M = L + (R - L) // 2

        if check(M):
            R = M
        else:
            L = M


    print(R)


def __starting_point():
    main()

__starting_point()

N, K = map(int, input().split())
A = list(map(int, input().split()))

r = max(A)
l = 0

while l+1 < r:
    mid = (l+r)//2
    cnt = 0
    for a in A:
        if(a > mid):
            if(a%mid == 0):
                cnt += (a//mid)-1
            else:
                cnt += a//mid
    if(cnt > K):
        l = mid
    else:
        r = mid
print(r)

n, k = list(map(int, input().split()))
a = list(map(int, input().split()))

def check(x):
  c = 0
  for i in range(n):
    c += a[i]//x
    if a[i]%x == 0:
      c -= 1
  if c <= k:
    return True
  else:
    return False

mx = max(a)
mn = 0
ans = [mx]
while mn <= mx:
  m = (mx+mn)//2
  if m == 0:
    if check(1):
      ans.append(1)
    break
  if check(m):
    mx = m - 1
    ans.append(m)
  else:
    mn = m + 1
print((min(ans)))


n, k = [int(i) for i in input().split()]
woods = [int(i) for i in input().split()]


def k_cut_less_than(k, l, woods):
    kaisuu = 0
    for wood in woods:
        kaisuu += (wood-1) // l
    if kaisuu <= k:
        return False
    return True


# 二分探索
# functionを満たす,search_listの最大の要素を出力
# 【注意点】searchリストの初めの方はfunctionを満たし、後ろに行くにつれて満たさなくなるべき
import math


def binary_research(start, end,  function):
    if start == end:
        return start
    middle = math.ceil((start + end) / 2)
    if function(k, middle, woods):
        start = middle
    else:
        end = middle - 1
    return binary_research(start, end, function)

start=0
end=10**9
print((binary_research(start,end,k_cut_less_than)+1))




n, k = map(int, input().split())
a = [i-1 for i in map(int, input().split())]
left, right = 1, 10**9
while left < right:
    middle = (left + right)//2
    count = sum(i//middle for i in a)
    if count <= k:
        right = middle
    else:
        left = middle + 1
print(left)

n, k = map(int, input().split())
a = [i-1 for i in map(int, input().split())]

left, right = 1, 10**9
while left < right:
    middle = (left + right)//2

    count = 0
    for i in a:
        count += i//middle
    
    if count <= k:
        right = middle
    else:
        left = middle + 1

print(left)

from math import ceil


N, K = list(map(int, input().split()))
A = list(map(int, input().split()))

def f(x):
    cnt = 0
    for a in A:
        cnt += ceil(a / x) - 1
    return True if cnt <= K else False

OK, NG = 10**9, 0
while OK - NG > 1:
    mid = (OK + NG) // 2
    if f(mid):
        OK = mid
    else:
        NG = mid

print(OK)


n,k=map(int,input().split())
*a,=map(int,input().split())
l,r=0,10**9
while r-l>1:
    m=(l+r)//2
    t=0
    for x in a:
        if x<=m:
            continue
        t+=(x+m-1)//m-1
    if t<=k:
        r=m
    else:
        l=m
print(r)

# coding: utf-8
import numpy as np


def solve(*args: str) -> str:
    n, k = list(map(int, args[0].split()))
    A = np.array(tuple(map(int, args[1].split())))

    l, r = 0, np.max(A)
    while l+1 < r:
        m = (l+r)//2
        if k < np.sum(np.ceil(A/m)-1):
            l = m
        else:
            r = m

    return str(r)


def __starting_point():
    print((solve(*(open(0).read().splitlines()))))

__starting_point()

def is_good(mid, key):
    res = 0
    for a in A:
        res += (a + mid - 1) // mid
    return res - N <= key


def binary_search(bad, good, key):
    while good - bad > 1:
        mid = (bad + good) // 2
        if is_good(mid, key):
            good = mid
        else:
            bad = mid
    return good


N, K, *A = list(map(int, open(0).read().split()))
print((binary_search(0, 1_000_000_000, K)))


# region header
import sys, bisect, math, itertools, heapq, collections
from operator import itemgetter
# a.sort(key=itemgetter(i)) # i番目要素でsort
from functools import lru_cache
import copy
# @lru_cache(maxsize=None)
# sys.setrecursionlimit(10**8)
input = sys.stdin.readline
INF = float('inf')
mod = 10**9 + 7
eps = 10**-7
# endregion
# region input function


def inp():
    '''
    一つの整数
    '''
    return int(input())


def inpl():
    '''
    一行に複数の整数
    '''
    return list(map(int, input().split()))


def str_inp():
    '''
    文字列をリストとして読み込む
    '''
    return list(input()[:-1])

# endregion


n, k = inpl()
a = inpl()

l = 0
r = 10**9
while l + 1 < r:
    x = (l + r) // 2
    cnt = 0
    for i in range(n):
        cnt += math.ceil(a[i] / x) - 1
        if cnt > k:
            break
    if cnt <= k:
        r = x
    else:
        l = x
print(r)


_, k = list(map(int, input().split()))
A = [*[int(x)-1 for x in input().split()]]
ng, ok = 0, 1<<30
while ok - ng > 1:
    m = (ng + ok) // 2
    if k < sum(a//m for a in A): ng = m
    else: ok = m
print(ok)


import math
n, k = list(map(int, input().split()))
a = list(map(int, input().split()))

def flag(mid):
    count = 0
    for a0 in a:
        count += math.ceil(a0/mid)-1
    if count <= k:
        return True
    else:
        return False
        
def cal(i, j):

    while abs(i-j) > 1:
        mid = (i+j)//2
        if flag(mid):
            j = mid
        else:
            i = mid
    print(j)
    
cal(0, max(a))    


n, k, *a = list(map(int, open(0).read().split()))


def c(x):
    res = 0
    for b in a:
        # bを最大がxになるように、できるだけ少ない回数で
        # だいたいb/x等分？
        res += 0 - - b // x - 1
    return res <= k


ng = 0
ok = 10 ** 10
while ok - ng > 1:
    mid = (ok + ng) >> 1
    if c(mid):
        ok = mid
    else:
        ng = mid
print(ok)


n, k = map(int, input().split())
a = list(map(int, input().split()))

low = 0
high = max(a)

while low + 1 < high:
    mid = (low + high) // 2
    m = 0
    for x in a:
        m += (x - 1) // mid
    
    if m <= k:
        high = mid
    else:
        low = mid

print(high)

import sys
import heapq
import math
def input(): return sys.stdin.readline().rstrip()
def main():
    n, k = map(int,input().split())
    A = list(map(int,input().split()))
    def is_good(mid, key):
        kk = 0
        for a in A:
            kk += -(-a//mid)-1
        if kk <= key:
            return True
        else:
            return False
    def bi_search(bad, good, key):
        while good - bad > 1:
            mid = (bad + good)//2
            if is_good(mid, key):
                good = mid
            else:
                bad = mid
        return good
    
    print(bi_search(0, max(A), k))
    
    
    


def __starting_point():
    main()
__starting_point()

n,k,*A=map(int,open(0).read().split());l=1;r=max(A)
while l!=r:
  c=(l+r)//2
  if k>=sum(-(-a//c)-1 for a in A):r=c
  else:l=c+1
print(l)

n,k = map(int,input().split())
a = list(map(int,input().split()))

def is_ok(l):
  cnt = 0
  for L in a:
    cnt += -(-L//l)-1
  return cnt<=k

def bisect(top,bot):
    while top - bot > 1:
        mid = (top + bot)//2
        if is_ok(mid):
            top = mid
        else:
            bot = mid
    return top

print(bisect(max(a),0))

N, K = list(map(int, input().split()))
A = list(map(int, input().split()))

def isOK(x):
    cnt = 0
    for a in A:
        cnt += (a + x - 1) // x - 1
    return cnt <= K

left, right = 0, 10 ** 10
while right - left > 1:
    mid = (left + right) // 2
    if isOK(mid):
        right = mid
    else:
        left = mid
print(right)


import math

n, k = map(int, input().split())
a = list(map(int, input().split()))

def is_ok(x,a,k):
    b = 0
    for ai in a:
        b += math.ceil(ai/x)
        b -= 1
    if b <= k:
        return True

def meguru_bisect(ng, ok):
    while (abs(ok - ng) > 1):
        mid = (ok + ng) // 2
        if is_ok(mid,a,k):
            ok = mid
        else:
            ng = mid
    return ok


print(meguru_bisect(0,max(a)))

N,K=map(int,input().split())
*A,=map(int,input().split())

def C(x):
  return sum([(A[i]+x-1)//x-1 for i in range(N)]) <= K
  
def binary_search2(func, n_min, n_max):
    left,right=n_min,n_max
    while right-left>1:
        middle = (left+right)//2
        y_middle = func(middle)
        if y_middle: right=middle
        else: left=middle

    return right
  
print(binary_search2(C, 0, max(A)+1))

n, k = map(int, input().split())
A = tuple(map(int, input().split()))
A = sorted(A, reverse=True)

l = 0
r = max(A)+1
def cut(l, k):
    # 長さlの丸太を最大とすることができるかどうかを返す
    for a in A:
        if a > l:
            k -= (-(-a//l) - 1)
    return k >= 0

while r-l > 1:
    mid = (r+l)//2
    if cut(mid, k):
        r = mid
    else:
        l = mid
print(r)

N,K = list(map(int,input().split()))
log_ls = list(map(int,input().split()))

Max = max(log_ls)

def less_k(min_length,log_ls = log_ls,K=K):
    times = 0
    for log in log_ls:
        if log % min_length == 0:
            times += log // min_length -1
        else:
            times += log // min_length
    if times <= K:
        return True
    else:
        return False
#print(less_k(5,[10,10],2))

def return_min_length():
    r = Max
    l = -1
    while True:
        next_length = (r+l) // 2
        if next_length == 0 or not less_k(next_length):
            l = next_length
        else:
            r = next_length
        if r - l == 1:
            return r

ans = return_min_length()
print(ans)


n,k=map(int,input().split())
a=list(map(int,input().split()))
ng=0
ok=10**10
while ok-ng>1:
  m=(ok+ng)//2
  c=0
  for i in a:
    c+=(i//m-(i%m==0))
  if c<=k:
    ok=m
  else:
    ng=m
print(ok)

#!/usr/bin/env python3
import sys
from itertools import chain


def cut_count(A, m):
    """最長の長さ(切り上げ)がm以下になるような切断回数"""
    total = 0
    for a in A:
        n = (a - 1) // m
        total += n
    return total


def solve(N: int, K: int, A: "List[int]"):
    r = max(A)
    l = 0
    while l + 1 < r:
        m = (r + l) // 2
        if cut_count(A, m) <= K:
            r = m  # r は K回以下の切断回数で到達できる長さ
        else:
            l = m  # l は K回より多いの切断回数で到達できる長さ
    # print(l, r)
    return r


def main():
    tokens = chain(*(line.split() for line in sys.stdin))
    # N, K, A = map(int, line.split())
    N = int(next(tokens))  # type: int
    K = int(next(tokens))  # type: int
    A = [int(next(tokens)) for _ in range(N)]  # type: "List[int]"
    answer = solve(N, K, A)
    print(answer)


def __starting_point():
    main()

__starting_point()

n,k,*a = map(int,open(0).read().split())
def func(b):
  c = k
  for i in a:
    c -= (i-1)//b
    if c < 0:
      return False
  return True
l = 1
r = max(a)
while(r>l):
  lr = (l+r)//2
  if func(lr):
    r = lr
  else:
    l = lr + 1
print(r)

# coding: utf-8

def solve(*args: str) -> str:
    n, k = list(map(int, args[0].split()))
    A = tuple(map(int, args[1].split()))

    l, r = 0, max(A)
    while l+1 < r:
        m = (l+r)//2
        cnt = 0
        for a in A:
            cnt += -(-a//m)-1

        if k < cnt:
            l = m
        else:
            r = m

    return str(r)


def __starting_point():
    print((solve(*(open(0).read().splitlines()))))

__starting_point()

n, k = map(int, input().split())
a = [i-1 for i in map(int, input().split())]

left, right = 0, 10**9
while left < right:
    middle = (left+right)//2
    if middle==0:
        left=1
        break
    count = 0
    for i in a:
        count += i//middle
    
    if count <= k:
        right = middle
    else:
        left = middle + 1

print(left)

from collections import defaultdict
from collections import deque
from collections import Counter
import math

def readInt():
	return int(input())
def readInts():
	return list(map(int, input().split()))
def readChar():
	return input()
def readChars():
	return input().split()

n,k = readInts()
a = readInts()

a.sort(reverse=True)

if n==1:
	print((math.ceil(a[0]/(k+1))))
	return

def get(left, right):
	l = (right-left)//2+left
	ans = 0
	for i in a:
		ans+=math.ceil(i/l)-1
	#print(l, ans, left, right)
	return ans,l

def nibu(left,right):
	ans,l = get(left, right)

	if left<right:
		if ans<=k:
			return nibu(left,l)
		else:
			return nibu(l+1, right)
	else:
		return right


print((nibu(1,a[0])))


N, K = map(int, input().split())

Alist = list(map(int, input().split()))

left = 0
right = max(Alist)

while right - left > 1:
    mid = (left + right) // 2
    
    cnt = 0
    for A in Alist:
        if A % mid == 0:
            cnt += (A // mid) - 1
        else:
            cnt += (A // mid)
    
    if cnt <= K:
        right = mid
    else:
        left = mid

print(right)

def is_good(mid, key):
    return sum((a + mid - 1) // mid for a in A) - N <= key


def binary_search(bad, good, key):
    while good - bad > 1:
        mid = (bad + good) // 2
        if is_good(mid, key):
            good = mid
        else:
            bad = mid
    return good


N, K, *A = list(map(int, open(0).read().split()))
print((binary_search(0, 1_000_000_000, K)))


# ABC174 E

n, k = list(map(int, input().split()))
a_l = [int(x) for x in input().split()]

left = 0
right = max(a_l)


def cut(len):
    ret = 0
    for i in range(n):
        if a_l[i] % len == 0:
            ret += a_l[i] // len - 1
        else:
            ret += a_l[i] // len
    return ret


while (right - left) > 1:
    _q = (left + right) // 2
    _ret = cut(_q)
    if k >= _ret:
        right = _q
    else:
        left = _q

print(right)