The only difference between easy and hard versions is the constraints.

Polycarp has to write a coursework. The coursework consists of $m$ pages.

Polycarp also has $n$ cups of coffee. The coffee in the $i$-th cup Polycarp has $a_i$ caffeine in it. Polycarp can drink some cups of coffee (each one no more than once). He can drink cups in any order. Polycarp drinks each cup instantly and completely (i.e. he cannot split any cup into several days).

Surely, courseworks are not being written in a single day (in a perfect world of Berland, at least).

Let's consider some day of Polycarp's work. Consider Polycarp drinks $k$ cups of coffee during this day and caffeine dosages of cups Polycarp drink during this day are $a_{i_1}, a_{i_2}, \dots, a_{i_k}$. Then the first cup he drinks gives him energy to write $a_{i_1}$ pages of coursework, the second cup gives him energy to write $max(0, a_{i_2} - 1)$ pages, the third cup gives him energy to write $max(0, a_{i_3} - 2)$ pages, ..., the $k$-th cup gives him energy to write $max(0, a_{i_k} - k + 1)$ pages.

If Polycarp doesn't drink coffee during some day, he cannot write coursework at all that day.

Polycarp has to finish his coursework as soon as possible (spend the minimum number of days to do it). Your task is to find out this number of days or say that it is impossible.


-----Input-----

The first line of the input contains two integers $n$ and $m$ ($1 \le n \le 2 \cdot 10^5$, $1 \le m \le 10^9$) — the number of cups of coffee and the number of pages in the coursework.

The second line of the input contains $n$ integers $a_1, a_2, \dots, a_n$ ($1 \le a_i \le 10^9$), where $a_i$ is the caffeine dosage of coffee in the $i$-th cup.


-----Output-----

If it is impossible to write the coursework, print -1. Otherwise print the minimum number of days Polycarp needs to do it.


-----Examples-----
Input
5 8
2 3 1 1 2

Output
4

Input
7 10
1 3 4 2 1 4 2

Output
2

Input
5 15
5 5 5 5 5

Output
1

Input
5 16
5 5 5 5 5

Output
2

Input
5 26
5 5 5 5 5

Output
-1



-----Note-----

In the first example Polycarp can drink fourth cup during first day (and write $1$ page), first and second cups during second day (and write $2 + (3 - 1) = 4$ pages), fifth cup during the third day (and write $2$ pages) and third cup during the fourth day (and write $1$ page) so the answer is $4$. It is obvious that there is no way to write the coursework in three or less days.

In the second example Polycarp can drink third, fourth and second cups during first day (and write $4 + (2 - 1) + (3 - 2) = 6$ pages) and sixth cup during second day (and write $4$ pages) so the answer is $2$. It is obvious that Polycarp cannot write the whole coursework in one day in this test.

In the third example Polycarp can drink all cups of coffee during first day and write $5 + (5 - 1) + (5 - 2) + (5 - 3) + (5 - 4) = 15$ pages of coursework.

In the fourth example Polycarp cannot drink all cups during first day and should drink one of them during the second day. So during first day he will write $5 + (5 - 1) + (5 - 2) + (5 - 3) = 14$ pages of coursework and during second day he will write $5$ pages of coursework. This is enough to complete it.

In the fifth example Polycarp cannot write the whole coursework at all, even if he will drink one cup of coffee during each day, so the answer is -1.

Difficulty: introductory

Starter code:

Solutions:
n, m = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]
a.sort(reverse=True)

def check(d):
    s=0
    for i in range(len(a)):
        s+=max(0,a[i]-i//d)
    return s>=m
if sum(a)<m:
    print(-1)
else:
    l, r = 1,n
    mid = l+r>>1
    while l<r:
        if check(mid):
            r=mid
        else:
            l=mid+1
        mid=l+r>>1
    print(l)


[n, m] = list(map(int, input().split()))
arr = list(map(int, input().split()))
arr.sort(reverse=True)
def check (i):
    mins = 0
    cnt = 0
    sums = 0
    for x in arr:
        sums += max(x-mins,0)
        if sums >= m:
            return True
        cnt += 1
        if cnt >= i:
            cnt = 0
            mins += 1
    return False

l = 1
r = n+1
while l!= r:
    if check((l+r)//2) :
        r = (l+r)//2
    else:
        l = (l+r)//2+1

print(l if l > 0 and l <= n else -1)

''' CODED WITH LOVE BY SATYAM KUMAR '''


from sys import stdin, stdout
import cProfile, math
from collections import Counter
from bisect import bisect_left,bisect,bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
sys.setrecursionlimit(10**6) # max depth of recursion
threading.stack_size(2**27)  # new thread will get stack of such size
fac_warmup = False
printHeap = str()
memory_constrained = False
P = 10**9+7
import sys

class Operation:
    def __init__(self, name, function, function_on_equal, neutral_value=0):
        self.name = name
        self.f = function
        self.f_on_equal = function_on_equal
def add_multiple(x, count):
    return x * count
def min_multiple(x, count):
    return x
def max_multiple(x, count):
    return x
sum_operation = Operation("sum", sum, add_multiple, 0)
min_operation = Operation("min", min, min_multiple, 1e9)
max_operation = Operation("max", max, max_multiple, -1e9)
class SegmentTree:
    def __init__(self,
                 array,
                 operations=[sum_operation, min_operation, max_operation]):
        self.array = array
        if type(operations) != list:
            raise TypeError("operations must be a list")
        self.operations = {}
        for op in operations:
            self.operations[op.name] = op
        self.root = SegmentTreeNode(0, len(array) - 1, self)
    def query(self, start, end, operation_name):
        if self.operations.get(operation_name) == None:
            raise Exception("This operation is not available")
        return self.root._query(start, end, self.operations[operation_name])
    def summary(self):
        return self.root.values
    def update(self, position, value):
        self.root._update(position, value)
    def update_range(self, start, end, value):
        self.root._update_range(start, end, value)
    def __repr__(self):
        return self.root.__repr__()
class SegmentTreeNode:
    def __init__(self, start, end, segment_tree):
        self.range = (start, end)
        self.parent_tree = segment_tree
        self.range_value = None
        self.values = {}
        self.left = None
        self.right = None
        if start == end:
            self._sync()
            return
        self.left = SegmentTreeNode(start, start + (end - start) // 2,
                                    segment_tree)
        self.right = SegmentTreeNode(start + (end - start) // 2 + 1, end,
                                     segment_tree)
        self._sync()
    def _query(self, start, end, operation):
        if end < self.range[0] or start > self.range[1]:
            return None
        if start <= self.range[0] and self.range[1] <= end:
            return self.values[operation.name]
        self._push()
        left_res = self.left._query(start, end,
                                    operation) if self.left else None
        right_res = self.right._query(start, end,
                                      operation) if self.right else None
        if left_res is None:
            return right_res
        if right_res is None:
            return left_res
        return operation.f([left_res, right_res])
    def _update(self, position, value):
        if position < self.range[0] or position > self.range[1]:
            return
        if position == self.range[0] and self.range[1] == position:
            self.parent_tree.array[position] = value
            self._sync()
            return
        self._push()
        self.left._update(position, value)
        self.right._update(position, value)
        self._sync()
    def _update_range(self, start, end, value):
        if end < self.range[0] or start > self.range[1]:
            return
        if start <= self.range[0] and self.range[1] <= end:
            self.range_value = value
            self._sync()
            return
        self._push()
        self.left._update_range(start, end, value)
        self.right._update_range(start, end, value)
        self._sync()
    def _sync(self):
        if self.range[0] == self.range[1]:
            for op in self.parent_tree.operations.values():
                current_value = self.parent_tree.array[self.range[0]]
                if self.range_value is not None:
                    current_value = self.range_value
                self.values[op.name] = op.f([current_value])
        else:
            for op in self.parent_tree.operations.values():
                result = op.f(
                    [self.left.values[op.name], self.right.values[op.name]])
                if self.range_value is not None:
                    bound_length = self.range[1] - self.range[0] + 1
                    result = op.f_on_equal(self.range_value, bound_length)
                self.values[op.name] = result
    def _push(self):
        if self.range_value is None:
            return
        if self.left:
            self.left.range_value = self.range_value
            self.right.range_value = self.range_value
            self.left._sync()
            self.right._sync()
            self.range_value = None
    def __repr__(self):
        ans = "({}, {}): {}\n".format(self.range[0], self.range[1],
                                      self.values)
        if self.left:
            ans += self.left.__repr__()
        if self.right:
            ans += self.right.__repr__()
        return ans

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def primeFactors(n): #n**0.5 complex 
    factors = dict()
    for i in range(2,math.ceil(math.sqrt(n))+1):  
        while n % i== 0: 
            if i in factors:
                factors[i]+=1
            else: factors[i]=1
            n = n // i 
    if n>2:
        factors[n]=1
    return (factors)

def binary(n,digits = 20):
    b = bin(n)[2:]
    b = '0'*(20-len(b))+b
    return b

def isprime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True
factorial_modP = []
def warm_up_fac(MOD):
    nonlocal factorial_modP,fac_warmup
    if fac_warmup: return
    factorial_modP= [1 for _ in range(fac_warmup_size+1)]
    for i in range(2,fac_warmup_size):
        factorial_modP[i]= (factorial_modP[i-1]*i) % MOD
    fac_warmup = True

def InverseEuler(n,MOD):
    return pow(n,MOD-2,MOD)

def nCr(n, r, MOD):
    nonlocal fac_warmup,factorial_modP
    if not fac_warmup:
        warm_up_fac(MOD)
        fac_warmup = True
    return (factorial_modP[n]*((pow(factorial_modP[r], MOD-2, MOD) * pow(factorial_modP[n-r], MOD-2, MOD)) % MOD)) % MOD

def test_print(*args):
    if testingMode:
        print(args)

def display_list(list1, sep=" "):
    stdout.write(sep.join(map(str, list1)) + "\n")

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))
import heapq,itertools
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = '<removed-task>' 
def add_task(task, priority=0):
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task(task)
    count = next(counter)
    entry = [priority, count, task]
    entry_finder[task] = entry
    heapq.heappush(pq, entry)

def remove_task(task):
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop(task)
    entry[-1] = REMOVED

def pop_task():
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heapq.heappop(pq)
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError('pop from an empty priority queue')
memory = dict()
def clear_cache():
    nonlocal memory
    memory = dict()
def cached_fn(fn, *args):
    nonlocal memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result


# -------------------------------------------------------------- MAIN PROGRAM
TestCases = False
testingMode = False
fac_warmup_size = 10**5+100
optimiseForReccursion = True #Can not be used clubbed with TestCases

def binary_serach(i,li):
    #print("Search for ",i)
    fn = lambda x: li[x]-x//i
    x = -1
    b = len(li)
    while b>=1:
        #print(b,x)
        while b+x<len(li) and fn(b+x)>0:
            x+=b
        b=b//2
    return x


def main():
    n, m = get_tuple()
    li = get_list()
    li.sort(reverse=True)
    prefix_sum = []
    sm=0
    for i in li:
        prefix_sum.append(sm+i)
        sm+=i
    for i in range(1,n+1):
        #curr = prefix_sum[i-1] #Replce with prefix sum
        c = -1
        index = binary_serach(i,li)
        n = index//i # Kitna lagega
        curr = prefix_sum[index] - (i*n*(n-1)//2 + (index-n*i+1)*n)
        #print("III",i,"CURR",curr,index,n)
        if curr>=m:
            print(i)
            return
    print(-1)

# --------------------------------------------------------------------- END=


if TestCases: 
    for _ in range(get_int()): 
        cProfile.run('main()') if testingMode else main() 
else: (cProfile.run('main()') if testingMode else main()) if not optimiseForReccursion else threading.Thread(target=main).start()

n,m = list(map(int,input().split()))
a = list(map(int,input().split()))
ans=1
su = sum(a)
a.sort(reverse=True)
s = [0]*n
s[0] = a[0]
for i in range(1,n):
    s[i] = s[i-1]+a[i]

def pos(d):
    i=d
    while i<=n:
        k = i//d
        neg = k*i-((k*(k+1))//2)*d
        if(s[i-1]-neg >= m):
            return True
        i+=1
    return False



if(su < m):
    ans = -1
    print(ans)

else:
    first = 0
    last = n

    while first<last-1:
        midpoint = (first + last)//2
        if pos(midpoint):
            last = midpoint
        else:
            first = midpoint

    print(last)


n, m = list(map(int, input().split()))
a = list(sorted(map(int, input().split()), reverse=True))


def proc(n, m, a):
    possible_minimum = -1
    l, r = 1, n
    sub_c = [0] * n
    while l <= r:
        i = (l + r) // 2
        # if i == 100:

        current_m = m
        for j in range(i):
            sub_c[j] = 0

        for j in range(0, n):
            # a[j:j + i]
            pos = j % i
            if a[j] < sub_c[pos]:
                break
            current_m -= a[j] - sub_c[pos]
            sub_c[pos] += 1
            if current_m <= 0:
                break
        if current_m <= 0:
            # print('[{}, {}] => {} SUCCESS'.format(l, r, i))
            possible_minimum = i
            r = i - 1
        else:
            # print('[{}, {}] => {} FAIL'.format(l, r, i))
            l = i + 1
    return possible_minimum


print(proc(n, m, a))


def check(arr,d,mm):
	ss=0
	k=-1
	for i in range(n):
		if (i)%d==0:
			# print("i is ",i)
			k+=1
		# print("k is ",k)
		ss+=max(0,arr[i]-k)
	if ss>=mm:
		return True
	else:
		return False
n,m=map(int,input().split())
arr=list(map(int,input().split()))
arr.sort(reverse=True)
s=1 
e=n 
ans=1000000000000000000000
while s<=e:
	mid=(s+e)//2
	if check(arr,mid,m):
		ans=min(ans,mid)
		e=mid-1
	else:
		s=mid+1
if ans==1000000000000000000000:
	ans=-1
print(ans)

import io, sys, atexit, os

import math as ma
from decimal import Decimal as dec
from itertools import permutations


def li ():
	return list (map (int, input ().split ()))


def num ():
	return map (int, input ().split ())


def nu ():
	return int (input ())


def find_gcd ( x, y ):
	while (y):
		x, y = y, x % y
	return x


def solve ():
	t = 1
	for it in range (t):
		n,m = num ()
		a = li ()
		a.sort(reverse = True)
		lo=1
		hi=n
		ans=-1
		while(lo<=hi):
			mid=(lo+hi)//2
			pp=0
			ss=0
			for i in range(n):
				if (i % mid == 0 and i != 0):
					pp += 1
				ss+=max(a[i]-pp,0)
			if(ss>=m):
				hi=mid-1
			else:
				lo=mid+1
		if(lo==n+1):
			print(-1)
		else:
			print(lo)


def __starting_point():
	solve ()
__starting_point()

n, m = list(map(int, input().strip().split()))
cups = list(map(int, input().strip().split()))


full_coffe = sum(cups)

if full_coffe < m:
    print("-1")
    return
elif full_coffe == m:
    print(len(cups))
    return

cups.sort(reverse=True)

def check_day(day):
    if day == 0:
        return False
    done = 0
    for idx, c in enumerate(cups):
        done += max(0, c - idx//day)
    return done >= m

lower = 0
upper = n
while upper - lower > 1:
    middle = lower + (upper - lower)//2
    if check_day(middle):
        upper = middle
    else:
        lower = middle

print(upper)



n,m = list(map(int,input().strip().split()))

arr = list(map(int,input().strip().split()))

arr = sorted(arr,reverse=True)

low = 1
high = n
#print(arr)
def check(k,m):
    #print(m)
    #print(m)
    if m>0:
        l = 0
        z = 0
        for i in range(n):
            m-=max(0,arr[i]-(l))
            z+=1
            if z==k:
                z = 0
                l+=1
            
    #print(m)
    if m<=0:
        return 1
    else:
        return 0
ans = []
while high >= low:
    
    mid = low+(high-low)//2
    #print(low,high,mid)
    if check(mid,m):
        ans.append(mid)
        high = mid-1
    else:
        low = mid+1
#print(ans)
if len(ans)>0:
    print(min(ans))
else:
    print(-1)


import sys

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

if sum(A)<m:
    print(-1)
    return

A.sort(reverse=True)

MIN=1
MAX=n

while MIN!=MAX:
    d=(MIN+MAX)//2


    ANS=0
    j=0
    count=0
    for a in A:
        if a<=j:
            continue
        
        ANS+=(a-j)
        count+=1

        if count==d:
            j+=1
            count=0

    #print(d,ANS)

    if ANS>=m:
        MAX=d
    else:
        MIN=d+1
print(MIN)
            


nb_cups, nb_task = [int(x) for x in input().split()]
caffines = sorted([int(x) for x in input().split()], reverse=True)


def check(d):
    done = 0
    for i, v in enumerate(caffines):
        done += max(0, v - i // d)
    return done >= nb_task

if sum(caffines) < nb_task:
    print(-1)
else:
    left, rite = 1, nb_cups
    mid = left + rite >> 1
    while left < rite:
        if check(mid):
            rite = mid
        else:
            left = mid + 1
        mid = left + rite >> 1
    print(left)     


n,m = [int(x) for x in input().split()]

l = [int(x) for x in input().split()]
summ = sum(l)
result = 0

def find(x) :
    # xét nếu uống trong x ngày kịp làm
    # thứ tự uống trong mỗi ngày ưu tiên cốc lớn trước . ex : với x = 2 : a1x1 > a1x2 > a2x1 >a2x2 >...
    s = 0
    pos_count = 0
    day_count = 0

    for i in l :
        s += max(0,i-pos_count)
        day_count+=1
        if day_count == x :
            day_count = 0
            pos_count+=1

    if s < m :
        return 0
    else :
        return x

def binary_search(lf,r) :
    nonlocal result
    mid = int((lf+r)/2)

    rs = find(mid)

    if lf==r :
        result = rs
    elif lf == r-1 :
        if rs :
            result = rs
        else :
            binary_search(r,r)
    else :
        if rs :
            binary_search(lf,mid)
        else :
            binary_search(mid,r)


if summ<m:
    print('-1')
elif summ == m :
    print(n)
# elif summ - sum(range(n)) == m:
#     print('1')
else :
    l= sorted(l,reverse=True)
    binary_search(1,n)
    print(result)


def check_possibility(days, m, coffee):
    sum_coffee = 0
    for i, cup in enumerate(coffee):
        tax = i // days
        if sum_coffee >= m or tax >= cup:
            break
        sum_coffee += cup - tax
    return sum_coffee >= m


n, m = list(map(int, input().split()))
coffee = sorted(map(int, input().split()), reverse=True)

bad = 0
good = len(coffee)

while good - bad > 1:
    days = (bad + good) // 2
    if check_possibility(days, m, coffee):
        good = days
    else:
        bad = days

possible = check_possibility(good, m, coffee)
print(good if possible else -1)


import sys
n , m = list(map(int,input().split()))
l = list(map(int,input().split()))
l.sort(reverse = True)

left = 1
right = n+1

ans = 10**18 + 1
while left != right:
    mid = (left+right)//2
    #print(mid,left,right)
    din = 0
    kaam = 0
    c = 0
    for i in l:
        if i - din <=0:
            break
        kaam += i - din
        c += 1
        if c == mid:
            c = 0
            din += 1
    if kaam >= m:
        ans = min(ans,mid)
        right = mid
    else:
        left = mid+1

if ans == 10**18+1:
    print(-1)
else:
    print(ans)
'''
import sys
n = int(input())
l = list(map(int,input().split()))

freq = [0]*1001

for i in range(n*n):
    freq[l[i]] += 1

odd = oc = 0
two = []
print(freq[:11])
if n > 2:
    mn = 4
    
    for i in range(1001):
        if freq[i] != 0:
            
            if freq[i]%2 == 1:
                odd = i
                oc += 1
                freq[i] -= 1
            if freq[i]%2 == 0 and freq[i]%4 != 0:
                two.append(i)
                freq[i] -= freq[i]%4
                continue
                
            if freq[i]%4 != 0:
                print('NO')
                return
                
ans = [ [0]*n for i in range(n) ]

if not n%2 and odd != 0:
    print('NO')
    return


if oc > 1:
    print('NO')
    return
    
if n%2:
    ans[n//2][n//2] = odd

r = c = 0

print(two)
print(freq[:11])
mid = 0
for i in range(n):
    for j in range(n):
        if ans[i][j] == 0:
            for k in range(1,1001):
                if freq[k] != 0:
                    temp = k
                    r = i
                    c = j

                    ans[r][c] = ans[n-1-r][c] = ans[r][n-1-c] = ans[n-1-r][n-1-c] = temp
                    flag = False
                    if n%2 and ( n//2 == i or n//2 == j):
                        #print('are ye to odd hai')
                        if len(two) != 0:
                            ans[n//2][mid] = ans[n//2][n-mid-1] = two[-1]
                            flag = True
                            two.pop()
                        else:
                            ans[n//2][mid] = ans[n//2][n-mid-1] = temp
                        mid+=1
                    #print(freq[:7])
                    if not flag:
                        freq[k] =freq[k] - 4
                    else:
                        freq[k] = freq[k] - 2
                    #print(freq[:7])
                    break
print("YES")
for i in range(n):
    print(*ans[i])
'''


n, m = list(map(int, input().split()))

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

l.sort(reverse = True)

left = 1
right = n

def check(k,m):
  if m > 0:
    lef = 0
    z = 0
    for i in range(n):
      m -= max(0, l[i]-lef)
      z += 1
      if z == k:
        z = 0
        lef += 1
  if m <= 0:
    return 1
  else:
    return 0

res = []

while left <= right:
  mid = int((left+right)/2)
  if check(mid, m):
    res.append(mid)
    right = mid - 1
  else:
    left = mid + 1
if len(res) > 0:
  print(min(res))
else:
  print("-1")

"""
n, m = map(int, input().split())

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

s = sum(l)
ans = 0

def find(x):
  su = 0
  days = 0
  z = 0

  for i in l:
    su += max(0, i-z)
    days += 1
    if days == x:
      days = 0
      z += 1
  if su < m:
    return 0
  return x

def binary(left, right):
  nonlocal ans
  mid = int((left+right)/2)
  r = find(mid)
  if right == left:
    ans = r
  elif left == right - 1:
    if r:
      ans = r
    else:
      binary(r, r)
  else:
    if r:
      binary(left, mid)
    else:
      binary(mid, right)

if s < m:
  print("-1")
elif s == m:
  print(n)
else:
  l.sort(reverse = True)
  binary(1,n)
  print(ans)
print(ans)
"""


from math import ceil
def check(p):
    sm = 0
    k = 0
    d = 0
    for i in range(ceil(len(a)/p)):
        for j in range(p):
            if k < len(a):
                sm += max(0, a[k]-d)
                k+=1
        d += 1
    return sm >= m

n,m=list(map(int,input().split()))
a=[int(x) for x in input().split()]
a.sort(reverse=True)

l=1
r=len(a)
if sum(a) < m:
    print(-1)
else:
    while(l < r):
        mid = (l + r) // 2

        if check(mid):
            r = mid
        else:
            l = mid+1
    print(l)


n, m = list(map(int, input().split()))
l = list(map(int, input().split()))
l.sort(reverse=True)
ans = []
def bin(s):
    tmp = [[] for k in range(s)]
    cur = s
    tr = 0
    for i in range(n):
        if (cur == s):
            cur = 0
        tmp[cur].append(l[i])
        cur += 1
    for i in range(s):
        for k in range(len(tmp[i])):
            tr += max(tmp[i][k] - k, 0)
    if tr >= m:
        return 1
    else:
        return 0
uk2 = n
uk1 = 1
while (uk2 - uk1 > 1):
    if bin((uk2 + uk1) // 2):
        uk2 = (uk2 + uk1) // 2
    else:
        uk1 = (uk2 + uk1) // 2
if bin(uk1):
    print(uk1)
elif bin(uk2):
    print(uk2)
else:
    print(-1)

import math

n, m = list(map(int, input().split()))
a = list(map(int, input().split())) + [-1]
a.sort(reverse=True)
s = sum(a)

if m > s + 1:
    print(-1)
    return

left, r = 0, n
while r - left > 1:
    mid = (left + r) // 2

    minus = 0
    i = 0
    ans = 0
    while a[i] > minus:
        cur = i
        while cur - i < mid:
            if a[cur] <= minus:
                minus = 999999999
                break
            ans += a[cur] - minus
            cur += 1
        i = cur
        minus += 1
    if ans >= m:
        r = mid
    else:
        left = mid
print(r)


def check(sz):
        aa=0
        for i in range(n):
                aa+=max(0,a[i]-i//sz)
                if aa>=M:
                        return True
        return False 
n,M=map(int,input().split())
a=list(map(int,input().split()))
if sum(a)<M:print(-1);return
a.sort(reverse=True)
l=1;r=n
while l<r:
        m=l+r
        m>>=1
        if check(m):
                r=m
        else:
                l=m+1
print(l)

import math

n, m = list(map(int, input().split()))
a = list(map(int, input().split())) + [-1]
a.sort(reverse=True)
s = sum(a)

if m > s + 1:
    print(-1)
    return

left, r = 0, n
while r - left > 1:
    mid = (left + r) // 2

    minus = 0
    i = 0
    ans = 0
    while a[i] > minus:
        cur = i
        while cur - i < mid:
            if a[cur] <= minus:
                minus = 999999999
                break
            ans += a[cur] - minus
            cur += 1
        i = cur
        minus += 1
    if ans >= m:
        r = mid
    else:
        left = mid
print(r)


def check(d, a):
    ans = 0
    for q in range(len(a)):
        ans += max(a[q]-q//d, 0)
    return ans


n, m = list(map(int, input().split()))
a = sorted(list(map(int, input().split())), reverse=True)
if sum(a) < m:
    print(-1)
else:
    l, r = 0, n
    while r-l > 1:
        m1 = (l+r)//2
        if check(m1, a) >= m:
            r = m1
        else:
            l = m1
    print(r)


n, m = (int(t) for t in input().split(' '))
a = [int(t) for t in input().split(' ')]

a.sort(reverse=True)

def possible(d):
    total = 0
    for i in range(d):
        step = 0
        for j in range(i, n, d):
            total += max(a[j] - step, 0)
            step += 1

    return total >= m

l, r = 0, n+1

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

if possible(l):
    print(l)
else:
    print(-1)


_ = input()
n, m = _.split()
n, m = int(n), int(m)
_ = input()
_a = _.split()
b = []
num_list = []
_counter = {}
_sum = 0
for i in _a:
    value = int(i)
    _sum = _sum + value
    b.append(value)
    if value in _counter:
        _counter[value] = _counter[value] + 1
    else:
        _counter[value] = 1
        num_list.append(value)
if m > _sum:
    print("-1")
else:
    num_list.sort()
    num_list.reverse()
    counter = []
    sum_list = []
    whole_sum_list = []
    _ = 0
    __ = 0
    for num in num_list:
        num_count = _counter[num]
        counter.append(num_count)
        _ = _ + num_count
        __ = __ + num_count *num
        sum_list.append(_)
        whole_sum_list.append(__)
    def avail(k):
        parse = len(num_list) - 1
        for i in range(len(num_list)):
            if sum_list[i]//k >= num_list[i]:
                parse = i
                break
        parse = parse - 1 if parse > 0 else 0
        floor = sum_list[parse]//k - 1
        token = sum_list[parse]%k
        # print(k, sum_list[parse], floor, token)
        whole_sum = whole_sum_list[parse] - k * int(floor*(floor+1)//2) - token * (floor+1)
        if whole_sum >= m:
            return True
        if len(num_list) == 1:
            return False
        floor = floor + 1
        _value = num_list[parse+1]
        for i in range(counter[parse+1]):
            if _value <= floor:
                break
            if whole_sum >= m:
                return True
            whole_sum = whole_sum + _value - floor
            # print(k, i, whole_sum)
            token = token + 1
            if token >= k:
                floor, token = floor + 1, 0
        if whole_sum >= m:
            return True
        return False

    def _avail(k):
        token = 0
        floor = 0
        cafe = 0
        available = False
        for value, count in zip(num_list, counter):
            if cafe - floor * token >= m:
                available = True
            if floor >= value:
                break
            cafe = cafe + value * count
            token = token + count
            for i in range(0, token//k):
                cafe = cafe - (floor + i) * k
            floor = floor + token // k
            token = token % k
        if cafe - floor * token>= m:
            available = True
        return available

    start = 1
    end = n
    while start != end:
        k = (start + end) // 2
        # print(start,end,avail(k))
        if avail(k):
            start, end = start, k
        else:
            start, end = k+1, end
    if n == 1:
        print(1)
    else:
        print(start)

def calc(ans,k,n):
    for i in range(1,len(ans)):
        if ans[i]>=n + k*(((i-k)//k)*((i-k)//k  + 1))//2 + ((i-k)%k)*((i-k)//k  + 1):
            #print("panne ",i,k,ans[i],(((i-k)//k)*((i-k)//k  + 1))//2 + ((i-k)%k)*((i-k)//k  + 1))
            return True
            
    return False

def bins(ans,n,low,high):
    if low==high and calc(ans,low,n):
        #print(low,high)
        return low
    elif low==high :
        return -1
    if calc(ans,(low+high)//2,n):
        return bins(ans,n,low,(low+high)//2)
    else:
        return bins(ans,n,(low+high)//2 + 1,high)

n,k=list(map(int,input().split()))
a=list(map(int,input().split()))
a.sort(reverse=True)
ans=[0]*(n+1)
for i in range(1,n+1):
    ans[i]=ans[i-1]+a[i-1]
#print(ans)
print(bins(ans,k,1,n))
#print(calc(ans,7,550))
#print(ans[47])