CodeEff/ECCO huggingface dataset:
# Original solution
import bisect
import copy
import heapq
import math
import sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product
def input():
    return sys.stdin.readline()[:-1]
def ruiseki(lst):
    return [0]+list(accumulate(lst))
sys.setrecursionlimit(500000)
mod=pow(10,9)+7
al=[chr(ord('a') + i) for i in range(26)]
direction=[[1,0],[0,1],[-1,0],[0,-1]]

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

l,h=0,max(a)
while h-l>0.0000001:
    mid=(h+l)/2
    # print(l,h,mid)
    cnt=0
    for i in range(n):
        cnt+=math.ceil(a[i]/mid)-1
    #     print(a[i]/mid)
    # print(cnt)
    if cnt<=k:
        h=mid
    else:
        l=mid

# print(l)
print((math.ceil(l-0.000001)))

# Optimized solution
import bisect
import copy
import heapq
import math
import sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product
def input():
    return sys.stdin.readline()[:-1]
def ruiseki(lst):
    return [0]+list(accumulate(lst))
sys.setrecursionlimit(500000)
mod=pow(10,9)+7
al=[chr(ord('a') + i) for i in range(26)]
direction=[[1,0],[0,1],[-1,0],[0,-1]]

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

l,h=0,max(a)
while h-l>1:
    mid=(h+l)//2
    # print(l,h,mid)
    cnt=0
    for i in range(n):
        cnt+=math.ceil(a[i]/mid)-1
    #     print(a[i]/mid)
    # print(cnt)
    if cnt<=k:
        h=mid
    else:
        l=mid

# print(l)
print(h)
# Original solution
N, K = list(map(int,input().split()))
A = list(map(int,input().split()))
start = 0
end = max(A)
while end - start > 1:
   l = (start + end)/2
   l = int(l)
   count = 0
   for i in range(N):
      q = A[i]/l
      if q == int(q):
         q -= 1
      count += int(q)
   if count <= K:
      end = l
   else:
      start = l
print(end)



# Optimized solution
N, K = list(map(int,input().split()))
A = list(map(int,input().split()))
start = 0
end = 10**9
while end - start > 1:
   l = (start + end)/2
   l = int(l)
   count = 0
   for i in range(N):
      q = A[i]/l
      if q == int(q):
         q -= 1
      count += int(q)
   if count <= K:
      end = l
   else:
      start = l
print(end)
# Original solution
import math
from heapq import heapify, heappop, heappush

LI = lambda: list(map(int, input().split()))

N, K = LI()
A = LI()


def main():
    hq = [(-a, -a, 1) for a in A]
    heapify(hq)
    for _ in range(K):
        x = heappop(hq)
        t = (x[1] / (x[2] + 1), x[1], x[2] + 1)
        heappush(hq, t)
    
    ans = math.ceil(-heappop(hq)[0])
    print(ans)


if __name__ == "__main__":
    main()


# Optimized solution
import math

LI = lambda: list(map(int, input().split()))

N, K = LI()
A = LI()


def judge(x):
    k = 0
    for a in A:
        if a <= x:
            continue
        if a % x == 0:
            k += a // x - 1
        else:
            k += a // x
    if k <= K:
        return True
    else:
        return False


def solve():
    left, right = 0, max(A)
    while right - left > 1:
        x = (left + right) // 2
        if judge(x):
            right = x
        else:
            left = x
    return right


def main():
    ans = solve()
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
import heapq
import bisect

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


# Optimized solution
n,k=list(map(int, input().split()))
A=[int(i) for i in input().split()]
ng=0
ok = max(A)
while(ng+1!=ok):
    mid = (ok+ng)//2
    ans = 0
    for i in A:
        ans += 0--i//mid-1
    if(ans<=k):
        ok = mid
    else:
        ng = mid
print(ok)
# Original solution
n,k=list(map(int,input().split()))
a=list(map(int,input().split()))
suma=sum(a)
import math
def func(x):
  chk=0
  for ai in a:
    # 長さx以下に分割するなら最小でtmp本にわかれる
    tmp=math.ceil(ai/x)
    chk+=tmp
  return chk<=n+k
l,r=0,max(a)
for _ in range(100):
  x=(l+r)/2
  if func(x):# k回ですべてx以下にできるなら、もっと小さくできそう
    l,r=l,x
  else:
    l,r=x,r
x=(l+r)/2
print((math.ceil(x)))
#print(l,r,x)

# Optimized solution
n,k=list(map(int,input().split()))
a=list(map(int,input().split()))
suma=sum(a)
import math
def func(x):
  chk=0
  for ai in a:
    # 長さx以下に分割するなら最小でtmp本にわかれる
    tmp=math.ceil(ai/x)
    chk+=tmp
  return chk<=n+k
l,r=0,max(a)
for _ in range(50):
  x=(l+r)/2
  if func(x):# k回ですべてx以下にできるなら、もっと小さくできそう
    l,r=l,x
  else:
    l,r=x,r
x=(l+r)/2
print((math.ceil(x)))
#print(l,r,x)
# Original solution
import math
n,k = list(map(int,input().split()))
a = list(map(int,input().split()))

if k == 0:
	print((max(a)))
	exit()

suki = 1000000000
kirai = 0
while int(suki) != int(kirai):
	targ = (suki+kirai)/2
	cnt = 0
	mode = 1
	for i in range(n):
		cnt += math.ceil(a[i] / targ)-1
		if cnt > k:
			mode = 0
			break
	if mode:
		suki = targ
	else:
		kirai = targ

print((math.ceil(suki)))

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

if k == 0:
	print((max(a)))
	exit()

suki = 1000000000
kirai = 0
while int(suki) != int(kirai):
	targ = (suki+kirai)/2
	cnt = 0
	mode = 1
	for i in range(n):
		cnt += (a[i]-1)//targ
		if cnt > k:
			mode = 0
			break
	if mode:
		suki = targ
	else:
		kirai = targ

print((math.ceil(suki)))
# Original solution
import sys
readline = sys.stdin.readline

from heapq import *

def solve():
    N, K = list(map(int, readline().split()))
    A = list(map(int ,readline().split()))

    A.sort()

    B = [(-a, 1) for a in A]

    heapify(B)

    for i in range(K):
        b, n = heappop(B)
        heappush(B, (b * n / (n + 1), n + 1))

    ans = -min(B)[0]
    if ans != int(ans):
        print((int(1 + ans)))
    else:
        print(ans)

solve()

# Optimized solution
import sys
readline = sys.stdin.readline
 
N, K = list(map(int, readline().split()))
A = list(map(int, readline().split()))
 
l = 0
r = 10**10
 
def test(m):
  return sum((a + m - 1) // m for a in A) - N <= K

while l + 1 < r:
  m = (l + r) // 2
  if test(m):
  	r = m
  else:
    l = m
print(r)
# Original solution
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return list(map(int, sys.stdin.readline().split()))
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for i in range(N)]
def dp2(ini, i, j): return [[ini]*i for i2 in range(j)]
#import bisect #bisect.bisect_left(B, a)
#from collections import defaultdict #d = defaultdict(int) d[key] += value
#from collections import Counter # a = Counter(A).most_common()
from itertools import accumulate #list(accumulate(A))
import math

N, K = mi()
A = li()

if K == 0:
    print((max(A)))
    exit()

left = 0
right = max(A)

def count(num):
    cnt = 0
    for i in range(N):
        cnt += math.ceil(A[i] / num) - 1
    return cnt

while True:
    mid = (left + right) // 2
    if mid == 0:
        print((1))
        exit()
    tmp = count(mid)
    if right - left <= 1:
        mid = right
        break
    elif tmp > K:
        left = mid
    else:
        right = mid

right = mid

while True:
    tmp = count(mid)
    if tmp == K and tmp != count(mid-1):
        print(mid)
        break
    elif tmp == K:
        right = mid
    else:
        #if left == mid:
            #print(mid+1)
            #break
        left = mid
    mid = (left + right) // 2
    if mid == 0:
        print((1))
        break

# Optimized solution
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return list(map(int, sys.stdin.readline().split()))
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for i in range(N)]
def dp2(ini, i, j): return [[ini]*i for i2 in range(j)]
#import bisect #bisect.bisect_left(B, a)
#from collections import defaultdict #d = defaultdict(int) d[key] += value
#from collections import Counter # a = Counter(A).most_common()
from itertools import accumulate #list(accumulate(A))
import math

N, K = mi()
A = li()

if K == 0:
    print((max(A)))
    exit()

left = 0
right = max(A)

def count(num):
    cnt = 0
    for i in range(N):
        cnt += math.ceil(A[i] / num) - 1
    return cnt

while True:
    mid = (left + right) // 2
    if mid == 0:
        print((1))
        exit()
    tmp = count(mid)
    if right - left <= 1:
        mid = right
        break
    elif tmp > K:
        left = mid
    else:
        right = mid

right = mid

while True:
    tmp = count(mid)
    if tmp == K and tmp != count(mid-1):
        print(mid)
        break
    elif tmp == K:
        right = mid
    else:
        if left == mid:
            print(right)
            break
        left = mid
    mid = (left + right) // 2
    if mid == 0:
        print((1))
        break
# Original solution
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return list(map(int, sys.stdin.readline().split()))
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for i in range(N)]
def dp2(ini, i, j): return [[ini]*i for i2 in range(j)]
#import bisect #bisect.bisect_left(B, a)
#from collections import defaultdict #d = defaultdict(int) d[key] += value
#from collections import Counter # a = Counter(A).most_common()
#from itertools import accumulate #list(accumulate(A))
import math
 
N, K = mi()
A = li()
 
if K == 0:
    print((max(A)))
    exit()
 
left = 0
right = max(A)
 
def count(num):
    cnt = 0
    for i in range(N):
        cnt += math.ceil(A[i] / num) - 1
    return cnt
 
while True:
    mid = (left + right) // 2
    if mid == 0:
        mid += 1
        break
    tmp = count(mid)
    if tmp == K:
        break
    elif tmp > K:
        if left == mid:
            mid = right
            break
        left = mid
    else:
        right = mid
 
if mid == 0 or mid == 1:
    print(mid)
    exit()
 
right = mid
 
while True:
    tmp = count(mid)
    if tmp == K and tmp != count(mid-1):
        print(mid)
        break
    elif tmp == K:
        right = mid
    else:
        if left == mid:
            print(right)
            break
        left = mid
    mid = (left + right) // 2
    if mid == 0:
        print((1))
        break

# Optimized solution
import sys
sys.setrecursionlimit(10**8)
def ii(): return int(sys.stdin.readline())
def mi(): return list(map(int, sys.stdin.readline().split()))
def li(): return list(map(int, sys.stdin.readline().split()))
def li2(N): return [list(map(int, sys.stdin.readline().split())) for i in range(N)]
def dp2(ini, i, j): return [[ini]*i for i2 in range(j)]
#import bisect #bisect.bisect_left(B, a)
#from collections import defaultdict #d = defaultdict(int) d[key] += value
#from collections import Counter # a = Counter(A).most_common()
#from itertools import accumulate #list(accumulate(A))
import math
 
N, K = mi()
A = li()
 
if K == 0:
    print((max(A)))
    exit()
 
left = 0
right = max(A)
 
def count(num):
    cnt = 0
    for i in range(N):
        cnt += math.ceil(A[i] / num) - 1
    return cnt
 
while True:
    mid = (left + right) // 2
    if mid == 0:
        print((1))
        break
    tmp = count(mid)
    if right - left <= 1:
        print(right)
        exit()
    elif tmp > K:
        left = mid
    else:
        right = mid
# Original solution
#from fractions import Fraction
from math import ceil
from heapq import heappush, heappop

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

A_queue = []
for a in input().split():
	a = float(a)
	heappush(A_queue, (-a, a, 1))

# search smallest i such that f(i) == True
def auto_bisearch_smallest(f, s = None):
	if s == None:
		s = 0
		w = -1
		while f(s) == True:
			s = w
			w *= 2
	e = s
	w = 1
	while f(e) == False:
		e = s + w
		w *= 2
	
	return bisearch_smallest(f, s, e + 1)

# search smallest i ( s <= i < e ) such that f(i) == True
def bisearch_smallest(f, s, e = None):
	if e == None:
		e = s - 1
		s = 0
	else:
		e -= 1
	
	while s < e:
		m = (s + e) // 2
		if f(m):
			e = m
		else:
			s = m + 1
	
	if s == e and f(s):
		return s
	else:
		return -1

def calc(K):
	while K > 0:
		length, a, div = heappop(A_queue)
		if len(A_queue) > 0:
			ref = A_queue[0][0]
			new_div = auto_bisearch_smallest(lambda div: -a / div > ref, div)
			K -= (new_div - div)
			heappush(A_queue, (-a / new_div, a, new_div))
		else:
			div += K
			K = 0
			heappush(A_queue, (-a / div, a, div))
	return -A_queue[0][0]

print((ceil(calc(K))))


# Optimized solution
N, K = list(map(int, input().split()))

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

# search smallest i such that f(i) == True
def auto_bisearch_smallest(f, s = None):
	if s == None:
		s = 0
		w = -1
		while f(s) == True:
			s = w
			w *= 2
	e = s
	w = 1
	while f(e) == False:
		e = s + w
		w *= 2
	
	return bisearch_smallest(f, s, e + 1)

# search smallest i ( s <= i < e ) such that f(i) == True
def bisearch_smallest(f, s, e = None):
	if e == None:
		e = s - 1
		s = 0
	else:
		e -= 1
	
	while s < e:
		m = (s + e) // 2
		if f(m):
			e = m
		else:
			s = m + 1
	
	if s == e and f(s):
		return s
	else:
		return -1

def calc(length):
	count = 0
	for a in A_list:
		if a > length:
			if a % length == 0:
				count += (a // length) - 1
			else:
				count += a // length
	return count

print((auto_bisearch_smallest(lambda length: calc(length) <= K, 1)))
# Original solution
import heapq
import math

def resolve():
    _,k = list(map(int, input().split()))
    A = list(map(int, input().split()))
    heap = []
    for a in A:
        heapq.heappush(heap, (-a, -a, 1))
    
    while k > 0:
        a = heapq.heappop(heap)
        origin = a[1]
        denom = a[2]
        denom += 1
        new = (origin/denom, origin, denom)
        heapq.heappush(heap, new)
        k -= 1

    a = heapq.heappop(heap)
    ans = a[0]*-1
    print((math.ceil(ans)))
    
resolve()

# Optimized solution
import math

def resolve():
    _,K = list(map(int, input().split()))
    A = list(map(int, input().split()))

    start = 0
    end = 10**9

    while end - start > 1:
        cnt = 0
        mid = (start + end) // 2
        for a in A:
            cnt += math.ceil(a/mid) - 1
        if cnt <= K:
            end = mid
        else:
            start = mid

    print(end)
    
resolve()
# Original solution
import math

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

#  にぶたん！ 半開区間二分探索は正義

def calc(x):
    count = 0
    for a in A:
        count += (a - 1) // x

    return count <= K

A.sort(reverse=True)

r = 10 ** 9
l = 0

while abs(r - l) > 1:
    mid = (r + l) // 2
    
    if calc(mid):
        r = mid
    else:
        l = mid

print(r)


# Optimized solution
import math

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

#  めぐる式二分探索で実装

def calc(x):
    count = 0
    for a in A:
        count += (a - 1) // x

    return count <= K

ok = 10 ** 9
ng = 0

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

print(ok)
# Original solution
from bisect import bisect_left

def main():
    N, K = list(map(int, input().split()))
    A = list(map(int, input().split()))
    A.sort()
    def check(x):
        index = bisect_left(A,x)
        ans = 0
        for i in range(index,N):
            if A[i] % x == 0:
                tmp = (A[i] // x) - 1
            else:
                tmp = A[i] // x
            ans += tmp
        if ans <= K:
            return True
        else:
            return False
    ok = max(A)
    ng = 0
    while abs(ok- ng) > 1:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok)


if __name__ == "__main__":
    main()

# Optimized solution
from bisect import bisect_left

def main():
    N, K = list(map(int, input().split()))
    A = list(map(int, input().split()))
    A.sort()
    def check(x):
        index = bisect_left(A,x)
        ans = 0
        for i in range(index,N):
            tmp = -(-A[i] // x) - 1
            ans += tmp
        if ans <= K:
            return True
        else:
            return False
    ok = max(A)
    ng = 0
    while abs(ok- ng) > 1:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok)


if __name__ == "__main__":
    main()
# Original solution
# -*- coding: utf-8 -*-
# template: v1.3.1

# 丸太の分割分割問題。
# 速度の観点から、「答えの二分探索」が必要。典型らしい。



import io
import sys
import math

### DEBUG ###
_DEB = 0   # 1:ON / 0:OFF

_INPUT = """\
2 1
1 50
"""

# Worst
# _INPUT = f"{str(2*(10**5))} {str(10**9)}\n{(str(10**9)+' ')*(2*(10**5)) }"
# _INPUT = f"{str(2*(10**5))} {str(10**9)}\n{(str(10**9)+' ')*(2*(10**5)) }"


_EXPECTED = """\
ABC
"""
if _DEB:
    sys.stdin = io.StringIO(_INPUT)
    print("!! Debug Mode !!")


def logd(str):
    if _DEB: print(f"[deb] {str}")

# is_m_OK?
def f(m):
    cut=0
    for aa in a:
        c=math.ceil(aa/m)
        cut+=c-1
        if cut > k:
            return False
    return True
#m=7,a=[7,9]


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

### Solve ####
def solve():
    # Process

    ans=0
    l,r=0,10**9
    while abs(r-l)!=1:
        m=(l+r)//2
        if f(m): # m is ok: Go left
            r=m
        else: # m is ng : Go right
            l=m
    
    ans=r
    # ans=min(r,max(a))

    # OUPUT
    ans = str(ans)
    print(ans)
    return ans

### MAIN ###
if __name__ == "__main__":
    ans = solve()

    # Checker
    if _DEB:
        if _EXPECTED.strip() == ans.strip(): print("\n!! Success !!")
        else: print(f"\n!! Failed... !!\nANSWER:   {ans}\nExpected: {_EXPECTED}")

# Optimized solution
# -*- coding: utf-8 -*-
# template: v1.3.1

# 丸太の分割分割問題。
# 速度の観点から、「答えの二分探索」が必要。典型らしい。
# f(x) の処理、すぬけさんのをチェック


import io
import sys
import math

### DEBUG ###
_DEB = 0   # 1:ON / 0:OFF

_INPUT = """\
2 1
1 3
"""

# Worst
# _INPUT = f"{str(2*(10**5))} {str(10**9)}\n{(str(10**9)+' ')*(2*(10**5)) }"
# _INPUT = f"{str(2*(10**5))} {str(10**9)}\n{(str(10**9)+' ')*(2*(10**5)) }"


_EXPECTED = """\
ABC
"""
if _DEB:
    sys.stdin = io.StringIO(_INPUT)
    print("!! Debug Mode !!")


def logd(str):
    if _DEB: print(f"[deb] {str}")

# is_m_OK?
def f(m):
    cut=0
    for aa in a:
        #ここを変えた
        c=(aa-1)//m 
        cut+=c
        if cut > k:
            return False
    return True
#m=7,a=[7,9]


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

### Solve ####
def solve():
    # Process

    ans=0
    l,r=0,10**9
    while abs(r-l)!=1:
        m=(l+r)//2
        if f(m): # m is ok: Go left
            r=m
        else: # m is ng : Go right
            l=m
    
    ans=r
    # ans=min(r,max(a))

    # OUPUT
    ans = str(ans)
    print(ans)
    return ans

### MAIN ###
if __name__ == "__main__":
    ans = solve()

    # Checker
    if _DEB:
        if _EXPECTED.strip() == ans.strip(): print("\n!! Success !!")
        else: print(f"\n!! Failed... !!\nANSWER:   {ans}\nExpected: {_EXPECTED}")
# Original solution
from bisect import bisect_right
from math import ceil
N,K=list(map(int, input().split()))
A=list(map(int, input().split()))
if K==0:
    print((max(A)))
    exit()

A=sorted(A)
# 最小値で二分探索 してまだ行けるかどうか
# 回数で二分探索
left=0
right=max(A)

ans=float("INF")
pre=ans
flag=False
count=0
while True:
    now=0
    mid=(left+right)/2
    idx=bisect_right(A, mid)
    for i in range(idx, N):
        now+=ceil(A[i]/mid)-1
    if now==K:
        if ans!=float("INF"):
            if ans==ceil(mid):
                flag=True
        ans=min(ans, ceil(mid))
        right=mid
        
        #if flag:
        #    break
        pre=ans
    if now>K:
        left=mid
        pre=mid
    if now<K:
        ans=min(ans, ceil(mid))
        right=mid
        pre=mid
    count+=1
    if count>=10**3:
        break
    


if ans==float("INF"):
    ans=max(A)
print((ceil(ans)))


# Optimized solution
from bisect import bisect_right
from math import ceil
N,K=list(map(int, input().split()))
A=list(map(int, input().split()))
if K==0:
    print((max(A)))
    exit()

A=sorted(A)
# 最小値で二分探索 してまだ行けるかどうか
# 回数で二分探索
left=0
right=max(A)

ans=float("INF")
pre=ans
flag=False
count=0
while True:
    now=0
    mid=(left+right)/2
    idx=bisect_right(A, mid)
    for i in range(idx, N):
        now+=ceil(A[i]/mid)-1
    if now==K:
        if ans!=float("INF"):
            if ans==ceil(mid):
                flag=True
        ans=min(ans, ceil(mid))
        right=mid
        
        #if flag:
        #    break
        pre=ans
    if now>K:
        left=mid
        pre=mid
    if now<K:
        ans=min(ans, ceil(mid))
        right=mid
        pre=mid
    count+=1
    if count>=10**2:
        break
    


if ans==float("INF"):
    ans=max(A)
print((ceil(ans)))
# Original solution
from bisect import bisect_right
from math import ceil
N,K=list(map(int, input().split()))
A=list(map(int, input().split()))
if K==0:
    print((max(A)))
    exit()

A=sorted(A)
# 最小値で二分探索 してまだ行けるかどうか
# 回数で二分探索
left=0
right=max(A)

ans=float("INF")
pre=ans
flag=False
count=0
while True:
    now=0
    mid=(left+right)/2
    idx=bisect_right(A, mid)
    for i in range(idx, N):
        now+=ceil(A[i]/mid)-1
    if now==K:
        if ans!=float("INF"):
            if ans==ceil(mid):
                flag=True
        ans=min(ans, ceil(mid))
        right=mid
        
        #if flag:
        #    break
        pre=ans
    if now>K:
        left=mid
        pre=mid
    if now<K:
        ans=min(ans, ceil(mid))
        right=mid
        pre=mid
    count+=1
    if count>=10**2:
        break
    


if ans==float("INF"):
    ans=max(A)
print((ceil(ans)))

# Optimized solution
from math import ceil
N,K=list(map(int, input().split()))

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

left=1
right=10**9+1
ans=float("INF")
while True:
    mid=(left+right)//2
    now=0
    for i in range(N):
        now+=ceil(A[i]/mid)-1

    if now>K:
        if left==mid:
            break
        left=mid
    else:
        ans=min(ans, mid)
        if right==mid:
            break
        right=mid

print(ans)
# Original solution
n,k = list(map(int,input().split()))
A = list(map(int,input().split()))

left = 0
right = max(A)

#if accumulate[(ai-1)//k]<=k return True?
def is_ok(x):
  cnt = 0
  for i in range(n):
    cnt += (A[i]-1)//x 
  return cnt<=k
     
#binary search
while (right-left)>1:
  mid = (left+right)//2
  if is_ok(mid):
    right = mid
  else:
    left = mid
    
print(right)

# Optimized solution
n,k = list(map(int,input().split()))
A = list(map(int,input().split()))

def is_ok(s):
    cnt = 0
    for i in range(n):
        cnt += (A[i]-1)//s
    return cnt<=k
def main():
    left = 0
    right = max(A)
    while (right-left)>1:
        mid = (right+left)//2
        if is_ok(mid):
            right = mid
        else:
            left = mid
    return right
print((main()))
# Original solution
n, k = list(map(int, input().split()))
a = list(map(int, input().split()))


def check(l):
    cnt = 0
    for i in range(n):
        cnt += a[i] // mid
        if a[i] % mid != 0:
            cnt += 1
        cnt -= 1

    return cnt <= k


lb, ub = 0, max(a)
while ub - lb > 1:
    mid = (ub + lb) // 2

    if check(mid):
        ub = mid
    else:
        lb = mid

print(ub)


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


def check(l):
    cnt = 0
    for L in a:
        cnt += L // mid
        if L % mid != 0:
            cnt += 1
        cnt -= 1

    return cnt <= k


lb, ub = 0, max(a)
while ub - lb > 1:
    mid = (ub + lb) // 2

    if check(mid):
        ub = mid
    else:
        lb = mid

print(ub)