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: MEDIUM_HARD
Tags: Sorting

Greedy algorithms
Skill types: Sorting

Greedy algorithms

Starter code:

Solutions:
(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)


import sys
from collections import deque, defaultdict, namedtuple
from math import sqrt, factorial, gcd, ceil, atan, pi

def input():
	return sys.stdin.readline()[:-1]
import string
import operator
from bisect import bisect_left, bisect_right
from functools import lru_cache, reduce
MOD = int(1000000000.0) + 7
INF = float('inf')

def solve():
	(n, M) = [int(x) for x in input().split()]
	a = [int(x) for x in input().split()]
	total = sum(a)
	if total < M:
		print(-1)
		return
	l = 0
	r = n + 1
	a.sort(reverse=True)

	def f(x):
		cnt = 0
		cycle = 0
		i = 0
		for e in a:
			if e > cycle:
				i = (i + 1) % x
				cnt += e - cycle
			if i == 0:
				cycle += 1
		return cnt >= M
	while l + 1 < r:
		m = (l + r) // 2
		if f(m):
			r = m
		else:
			l = m
	print(r)
t = 1
for case in range(1, t + 1):
	ans = solve()


(n, t) = map(int, input().split())
z = list(map(int, input().split()))
if sum(z) < t:
	print(-1)
	exit()
else:
	import math
	mini = math.inf
	z.sort()
	z = z[::-1]
	l = 1
	u = len(z)
	from collections import *
	al = defaultdict(int)
	while l <= u and l >= 1:
		i = (l + u) // 2
		m = z.copy()
		j = 0
		total = 0
		flag = 0
		while j < len(m):
			r = j // i
			total += max(z[j] - r, 0)
			if total >= t:
				mini = min(mini, i)
				flag = 1
			j += 1
		if al[i] == 1:
			break
		else:
			al[i] = 1
		if flag == 0:
			l = i + 1
		else:
			u = i - 1
	print(mini)


import sys
input = sys.stdin.readline

def fun(x):
	su = 0
	global ar, n
	for i in range(n):
		su += max(0, ar[i] - i // x)
	return bool(su >= m)
(n, m) = map(int, input().split())
ar = list(map(int, input().split()))
ar.sort(reverse=True)
if sum(ar) < m:
	print(-1)
else:
	l = 1
	r = n
	while l <= r:
		mid = (l + r) // 2
		if fun(mid):
			r = mid - 1
		else:
			l = mid + 1
	print(l)


(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')
	exit()
elif full_coffe == m:
	print(len(cups))
	exit()
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)


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
	if ANS >= m:
		MAX = d
	else:
		MIN = d + 1
print(MIN)


from sys import stdin, stdout

def fn(days):
	sm1 = 0
	for i in range(n):
		if a[i] - i // days <= 0:
			break
		sm1 += a[i] - i // days
	return sm1
for _ in range(1):
	(n, k) = list(map(int, stdin.readline().split()))
	a = list(map(int, stdin.readline().split()))
	a.sort(reverse=True)
	ans = float('inf')
	(l, r) = (1, n)
	ans = float('inf')
	while l <= r:
		mid = l + r >> 1
		if fn(mid) >= k:
			r = mid - 1
		else:
			l = mid + 1
	if l <= n:
		ans = min(ans, l)
	print(ans if ans != float('inf') else -1)


from os import path
import sys
from functools import cmp_to_key as ctk
from collections import deque, defaultdict as dd
from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from itertools import permutations
from datetime import datetime
from math import ceil, sqrt, log, gcd

def ii():
	return int(input())

def si():
	return input()

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

def li():
	return list(mi())
abc = 'abcdefghijklmnopqrstuvwxyz'
abd = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
mod = 1000000007
inf = float('inf')
vow = ['a', 'e', 'i', 'o', 'u']
(dx, dy) = ([-1, 1, 0, 0], [0, 0, 1, -1])

def bo(i):
	return ord(i) - ord('a')

def check(a, m):
	n = len(a)
	(c, k, s) = (0, 0, 0)
	for i in range(n - 1, -1, -1):
		if a[i] > k:
			s += a[i] - k
		else:
			break
		c += 1
		if c % m == 0:
			k += 1
	return s

def solve():
	(n, m) = mi()
	a = li()
	if m > sum(a):
		print('-1')
		exit(0)
	a.sort()
	l = 1
	r = n
	ans = n
	while l <= r:
		mid = l + (r - l) // 2
		x = check(a, mid)
		if x >= m:
			ans = mid
			r = mid - 1
		else:
			l = mid + 1
	print(ans)
solve()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class SegmentTree:

	def __init__(self, data, default=-10 ** 6, func=lambda a, b: max(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)

class SegmentTree1:

	def __init__(self, data, default=10 ** 6, func=lambda a, b: min(a, b)):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		if start == stop:
			return self.__getitem__(start)
		stop += 1
		start += self._size
		stop += self._size
		res = self._default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)
MOD = 10 ** 9 + 7

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD
mod = 10 ** 9 + 7
omod = 998244353
prime = [True for i in range(200001)]
pp = [0] * 200001

def SieveOfEratosthenes(n=200000):
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
(n, m) = map(int, input().split())
a = list(map(int, input().split()))
a.sort(reverse=True)

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


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

def solve(days):
	pages = 0
	for i in range(n):
		pages += max(0, a[i] - i // days)
	return pages >= m
res = -1
lo = 1
hi = n + 1
while lo < hi:
	mid = lo + (hi - lo) // 2
	if solve(mid):
		hi = mid
	else:
		lo = mid + 1
print(lo if lo <= n else -1)


import sys
(n, m) = 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
	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)


(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')


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)
	exit()
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)


def sum1(day, n, lst):
	std = n // day
	sumi = 0
	sub = -1
	for i in range(n):
		if i % day == 0:
			sub += 1
		sumi += max(0, lst[i] - sub)
	return sumi

def binary(n, m, arr):
	l = 1
	r = n
	ans = -1
	while l <= r:
		mid = (l + r) // 2
		pages = sum1(mid, n, arr)
		if pages >= m:
			r = mid - 1
			ans = mid
		elif pages < m:
			l = mid + 1
	return ans
(n, m) = map(int, input().strip().split())
cafe = list(map(int, input().strip().split()))
cafe.sort(reverse=True)
print(binary(n, m, cafe))


import sys
from collections import defaultdict as dd
from collections import deque
from fractions import Fraction as f

def eprint(*args):
	print(*args, file=sys.stderr)
zz = 1
from math import *
import copy
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')

def li():
	return [int(x) for x in input().split()]

def fi():
	return int(input())

def si():
	return list(input().rstrip())

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

def gh():
	sys.stdout.flush()

def bo(i):
	return ord(i) - ord('a')
from copy import *
from bisect import *
from itertools import permutations

def can(mid):
	c = 0
	for i in range(n):
		c += max(0, a[i] - i // mid)
	return c >= m
(n, m) = mi()
a = li()
if sum(a) < m:
	print(-1)
	exit(0)
a.sort(reverse=True)
l = 1
r = 10 ** 15
while l <= r:
	mid = (l + r) // 2
	if can(mid):
		ans = mid
		r = mid - 1
	else:
		l = mid + 1
print(ans)


def search_binary(cups, pages, doses):
	if sum(doses) < pages:
		return -1
	elif sum(doses) == pages:
		return len(doses)
	else:
		doses = sorted(doses, reverse=True)
	new_doses = []
	new_doses = doses[0:pages]
	max_days = len(new_doses)
	min_days = 0
	while max_days - min_days > 1:
		days = (max_days + min_days) // 2
		test = count_coffee(days, pages, doses)
		if test == True:
			max_days = days
		elif test == False:
			min_days = days
	return max_days

def count_coffee(days, pages, doses):
	new_doses = []
	rest_doses = []
	new_doses = doses[:days]
	rest_doses = doses[days:]
	pages -= sum(new_doses)
	n = 1
	j = 0
	while pages > 0:
		for i in range(len(new_doses)):
			if j >= len(rest_doses) and pages > 0:
				return False
			elif j >= len(rest_doses):
				break
			elif rest_doses[j] - n <= 0 and pages <= 0:
				break
			if pages < 0:
				break
			new_doses[i] += rest_doses[j] - n
			pages -= rest_doses[j] - n
			j += 1
		n += 1
	return True
(cups, pages) = map(int, input().split())
doses = list(map(int, input().split()))
print(search_binary(cups, pages, doses))


def stack(days, count):
	x = count // days
	y = count % days
	return days * x * (x - 1) // 2 + y * x

def func(arr, days):
	total = 0
	for x in range(len(arr)):
		if arr[x] <= x // days:
			break
		else:
			total += arr[x] - x // days
	return total

def main():
	arr = input().split()
	n = int(arr[0])
	pages = int(arr[1])
	arr = input().split()
	for x in range(n):
		arr[x] = int(arr[x])
	arr.sort(reverse=True)
	lower = 1
	upper = 4 * 10 ** 5
	while upper - lower > 1:
		mid = (upper + lower) // 2
		total = func(arr, mid)
		if total >= pages:
			upper = mid
		else:
			lower = mid
	if func(arr, lower) >= pages:
		return lower
	elif func(arr, upper) >= pages:
		return upper
	else:
		return -1
print(main())


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):
			return True
	return False

def bins(ans, n, low, high):
	if low == high and calc(ans, low, n):
		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(bins(ans, k, 1, n))


[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)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import factorial
from collections import Counter, defaultdict
from heapq import heapify, heappop, heappush

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

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

def N():
	return int(input())

def comb(n, m):
	return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0

def perm(n, m):
	return factorial(n) // factorial(n - m) if n >= m else 0

def mdis(x1, y1, x2, y2):
	return abs(x1 - x2) + abs(y1 - y2)

def ctd(chr):
	return ord(chr) - ord('a')
mod = 998244353
INF = float('inf')

def main():
	(n, m) = RL()
	arr = RLL()
	arr.sort(reverse=1)

	def c(num):
		now = 0
		for i in range(n):
			now += max(0, arr[i] - i // num)
		return now >= m
	(l, r) = (1, n + 1)
	while l < r:
		mid = (l + r) // 2
		if c(mid):
			r = mid
		else:
			l = mid + 1
	print(l if l <= n else -1)
main()


(n, m) = map(int, input().split())
A = list(map(int, input().split()))
if sum(A) < m:
	print(-1)
	exit()
A.sort(reverse=True)

def is_ok(x):
	temp = 0
	for i in range(n):
		temp += max(0, A[i] - i // x)
	if temp >= m:
		return True
	else:
		return False
ng = 0
ok = n
while ng + 1 < ok:
	c = (ng + ok) // 2
	if is_ok(c):
		ok = c
	else:
		ng = c
print(ok)


(n, m) = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]
a.sort(reverse=True)
if sum(a) < m:
	print(-1)
else:
	l = 1
	r = n
	while l < r:
		mid = l + r >> 1
		s = 0
		for j in range(n):
			s += max(0, a[j] - j // mid)
		if s >= m:
			r = mid
		else:
			l = mid + 1
	else:
		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)


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

def func(i):
	ans = 0
	for j in range(0, n):
		ans += max(A[j] - j // i, 0)
	return ans >= m
l = 1
r = n
while r - l > 1:
	s = l + r >> 1
	if func(s) == 1:
		r = s
	else:
		l = s
if func(l) == 1:
	print(l)
elif func(r) == 1:
	print(r)
else:
	print('-1')


(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)


import sys, os, io
from sys import stdin
from math import log, gcd, ceil
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import math
alphabets = list('abcdefghijklmnopqrstuvwxyz')

def isPrime(x):
	for i in range(2, x):
		if i * i > x:
			break
		if x % i == 0:
			return False
	return True

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(int(i))
			n = n / i
	if n > 2:
		l.append(n)
	return list(set(l))

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def SieveOfEratosthenes(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime

def countdig(n):
	c = 0
	while n > 0:
		n //= 10
		c += 1
	return c

def si():
	return input()

def prefix_sum(arr):
	r = [0] * (len(arr) + 1)
	for (i, el) in enumerate(arr):
		r[i + 1] = r[i] + el
	return r

def divideCeil(n, x):
	if n % x == 0:
		return n // x
	return n // x + 1

def ii():
	return int(input())

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

def ws(s):
	sys.stdout.write(s + '\n')

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')

def power_set(L):
	cardinality = len(L)
	n = 2 ** cardinality
	powerset = []
	for i in range(n):
		a = bin(i)[2:]
		subset = []
		for j in range(len(a)):
			if a[-j - 1] == '1':
				subset.append(L[j])
		powerset.append(subset)
	powerset_orderred = []
	for k in range(cardinality + 1):
		for w in powerset:
			if len(w) == k:
				powerset_orderred.append(w)
	return powerset_orderred

def fastPlrintNextLines(a):
	print('\n'.join(map(str, a)))

def sortByFirstAndSecond(A):
	A = sorted(A, key=lambda x: x[0])
	A = sorted(A, key=lambda x: x[1])
	return list(A)
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
else:
	input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def check(d, m, a):
	curSum = sum(a[:d])
	minus = 1
	if curSum >= m:
		return True
	temp = d
	for i in range(d, len(a)):
		curSum += max(a[i] - minus, 0)
		temp -= 1
		if temp == 0:
			minus += 1
			temp = d
		if curSum >= m:
			return True
	return False

def solve():
	(n, m) = li()
	a = li()
	l = 1
	r = m
	ans = -1
	a.sort(reverse=True)
	while l <= r:
		mid = (l + r) // 2
		if check(mid, m, a):
			r = mid - 1
			ans = mid
		else:
			l = mid + 1
	print(ans)
t = 1
for _ in range(t):
	solve()


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)


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)


(n, m) = map(int, input().split())
a = list(map(int, input().split()))
a.sort(reverse=True)
l = 1
r = n
d = -1
while l <= r:
	mid = (l + r) // 2
	ans = 0
	for i in range(n):
		ans += max(0, a[i] - i // mid)
	if ans >= m:
		r = mid - 1
		d = mid
	else:
		l = mid + 1
print(d)


def check(d, a):
	ans = 0
	for q in range(len(a)):
		ans += max(a[q] - q // d, 0)
	return ans
(n, m) = 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)


class Solution:

	def __init__(self):
		firstline = input().split()
		n = int(firstline[0])
		m = int(firstline[1])
		a = input().split()
		for i in range(n):
			a[i] = int(a[i])
		a.sort(key=int, reverse=True)
		l = 1
		r = m + 1
		while l < r:
			mid = int(l + r >> 1)
			sum = 0
			for i in range(n):
				if a[i] - int(i / mid) <= 0:
					break
				sum += max(0, a[i] - int(i / mid))
				if sum >= m:
					break
			if sum >= m:
				r = mid
			else:
				l = mid + 1
		if r == m + 1:
			print('-1')
		else:
			print(r)
Solution()


def check(num):
	arr = [[] for i in range(num)]
	(j, count) = (0, 0)
	for i in range(n):
		arr[j].append(max(0, c[i] - len(arr[j])))
		count += arr[j][-1]
		j = (j + 1) % num
	if count >= m:
		return True
	return False
(n, m) = map(int, input().split())
c = list(map(int, input().split()))
c.sort(reverse=True)
if sum(c) < m:
	print(-1)
	exit()
low = 1
high = n
while low < high:
	mid = (low + high) // 2
	if check(mid):
		high = mid - 1
	else:
		low = mid + 1
if check(low):
	print(low)
else:
	print(low + 1)


(n_cups, target) = [int(i) for i in input().split()]
cups = [int(i) for i in input().split()]
cups = sorted(cups, reverse=True)
found = False
if sum(cups) < target:
	print(-1)
	found = True

def find_value(c, days):
	val = 0
	for i in range(len(c)):
		val += max(c[i] - i // days, 0)
	return val
low = 1
high = n_cups
while not found:
	current = (low + high) // 2
	val = find_value(cups, current)
	if low == current or high == current:
		if val >= target:
			print(current)
			found = True
			break
		else:
			print(current + 1)
			found = True
			break
	if val < target:
		low = current
	elif val > target:
		high = current
	else:
		print(current)
		found = True
		break


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)
threading.stack_size(2 ** 27)
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, 1000000000.0)
max_operation = Operation('max', max, max_multiple, -1000000000.0)

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):
	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):
	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 = []
entry_finder = {}
REMOVED = '<removed-task>'

def add_task(task, priority=0):
	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):
	entry = entry_finder.pop(task)
	entry[-1] = REMOVED

def pop_task():
	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
TestCases = False
testingMode = False
fac_warmup_size = 10 ** 5 + 100
optimiseForReccursion = True

def binary_serach(i, li):
	fn = lambda x: li[x] - x // i
	x = -1
	b = len(li)
	while b >= 1:
		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):
		c = -1
		index = binary_serach(i, li)
		n = index // i
		curr = prefix_sum[index] - (i * n * (n - 1) // 2 + (index - n * i + 1) * n)
		if curr >= m:
			print(i)
			return
	print(-1)
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(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
		current_m = m
		for j in range(i):
			sub_c[j] = 0
		for j in range(0, n):
			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:
			possible_minimum = i
			r = i - 1
		else:
			l = i + 1
	return possible_minimum
print(proc(n, m, a))


from collections import defaultdict, Counter
from itertools import product, groupby, count, permutations, combinations
from math import pi, sqrt, sin, cos, ceil, floor
from collections import deque
from bisect import bisect, bisect_left, bisect_right
from string import ascii_lowercase
from functools import lru_cache
import sys
sys.setrecursionlimit(1000000000)
INF = float('inf')
(YES, Yes, yes, NO, No, no) = ('YES', 'Yes', 'yes', 'NO', 'No', 'no')
(dy4, dx4) = ([0, 1, 0, -1], [1, 0, -1, 0])
(dy8, dx8) = ([0, -1, 0, 1, 1, -1, -1, 1], [1, 0, -1, 0, 1, 1, -1, -1])

def inside(y, x, H, W):
	return 0 <= y < H and 0 <= x < W

def ceil(a, b):
	return (a + b - 1) // b

def gcd(a, b):
	if b == 0:
		return a
	return gcd(b, a % b)

def lcm(a, b):
	g = gcd(a, b)
	return a / g * b

def euclidean_distance(y1, x1, y2, x2):
	return sqrt((y1 - y2) ** 2 + (x1 - x2) ** 2)

def manhattan_distance(y1, x1, y2, x2):
	return abs(y1 - y2) + abs(x1 - x2)

def ok(d, M, C):
	page = 0
	for i in range(len(C)):
		page += max(0, C[i] - i // d)
	return M <= page

def main():
	(N, M) = map(int, input().split())
	C = list(sorted(list(map(int, input().split())), reverse=True))
	(low, high) = (0, N + 1)
	ans = -1
	while high - low > 1:
		middle = (low + high) // 2
		if ok(middle, M, C):
			high = middle
			ans = middle
		else:
			low = middle
	print(ans)
main()


(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):
	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):
	global 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)
	elif rs:
		binary_search(lf, mid)
	else:
		binary_search(mid, r)
if summ < m:
	print('-1')
elif summ == m:
	print(n)
else:
	l = sorted(l, reverse=True)
	binary_search(1, n)
	print(result)


import sys
input = sys.stdin.readline

def ceil_div(x, y):
	return -(-x // y)

def can(a, k, m):
	if len(a) <= k:
		return sum(a) >= m
	else:
		sum_ = 0
		minus = 0
		for i in range(len(a)):
			if i % k == 0 and i != 0:
				minus += 1
			sum_ += max(0, a[i] - minus)
		return sum_ >= m

def main():
	(n, m) = [int(x) for x in input().split(' ')]
	a = [int(x) for x in input().split(' ')]
	a = sorted(a, reverse=True)
	sum_a = sum(a)
	if sum_a < m:
		print(-1)
	elif sum_a == m:
		print(len(a))
	else:
		pos = 0
		for i in range(31, -1, -1):
			jump = 2 ** i
			if not can(a, pos + jump, m):
				pos += jump
		print(pos + 1)
main()


import os
import sys
from io import BytesIO, IOBase
import math
from queue import Queue
import collections
import itertools
import bisect
import heapq
import random

def main():
	pass
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def binary(n):
	return bin(n).replace('0b', '')

def decimal(s):
	return int(s, 2)

def pow2(n):
	p = 0
	while n > 1:
		n //= 2
		p += 1
	return p

def primeFactors(n):
	l = []
	while n % 2 == 0:
		l.append(2)
		n = n / 2
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			l.append(i)
			n = n / i
	if n > 2:
		l.append(int(n))
	return l

def isPrime(n):
	if n == 1:
		return False
	else:
		root = int(n ** 0.5)
		root += 1
		for i in range(2, root):
			if n % i == 0:
				return False
		return True

def maxPrimeFactors(n):
	maxPrime = -1
	while n % 2 == 0:
		maxPrime = 2
		n >>= 1
	for i in range(3, int(math.sqrt(n)) + 1, 2):
		while n % i == 0:
			maxPrime = i
			n = n / i
	if n > 2:
		maxPrime = n
	return int(maxPrime)

def countcon(s, i):
	c = 0
	ch = s[i]
	for i in range(i, len(s)):
		if s[i] == ch:
			c += 1
		else:
			break
	return c

def lis(arr):
	n = len(arr)
	lis = [1] * n
	for i in range(1, n):
		for j in range(0, i):
			if arr[i] > arr[j] and lis[i] < lis[j] + 1:
				lis[i] = lis[j] + 1
	maximum = 0
	for i in range(n):
		maximum = max(maximum, lis[i])
	return maximum

def isSubSequence(str1, str2):
	m = len(str1)
	n = len(str2)
	j = 0
	i = 0
	while j < m and i < n:
		if str1[j] == str2[i]:
			j = j + 1
		i = i + 1
	return j == m

def maxfac(n):
	root = int(n ** 0.5)
	for i in range(2, root + 1):
		if n % i == 0:
			return n // i
	return n

def p2(n):
	c = 0
	while n % 2 == 0:
		n //= 2
		c += 1
	return c

def seive(n):
	primes = [True] * (n + 1)
	primes[1] = primes[0] = False
	i = 2
	while i * i <= n:
		if primes[i] == True:
			for j in range(i * i, n + 1, i):
				primes[j] = False
		i += 1
	pr = []
	for i in range(0, n + 1):
		if primes[i]:
			pr.append(i)
	return pr

def ncr(n, r, p):
	num = den = 1
	for i in range(r):
		num = num * (n - i) % p
		den = den * (i + 1) % p
	return num * pow(den, p - 2, p) % p

def denofactinverse(n, m):
	fac = 1
	for i in range(1, n + 1):
		fac = fac * i % m
	return pow(fac, m - 2, m)

def numofact(n, m):
	fac = 1
	for i in range(1, n + 1):
		fac = fac * i % m
	return fac

def sod(n):
	s = 0
	while n > 0:
		s += n % 10
		n //= 10
	return s

def getXor(n):
	xor = 1
	for i in range(2, n + 1):
		xor = xor ^ i
	return xor

def canDo(k):
	cov = 0
	for i in range(0, n):
		cov += max(0, l[i] - i // k)
	return cov >= m
(n, m) = map(int, input().split())
l = list(map(int, input().split()))
l.sort(reverse=True)
if sum(l) < m:
	print(-1)
else:
	f = 1
	r = n
	while f < r:
		mid = (f + r) // 2
		if canDo(mid):
			r = mid
		else:
			f = mid + 1
	print(f)


(n, m) = map(int, input().strip().split())
arr = list(map(int, input().strip().split()))
arr = sorted(arr, reverse=True)
low = 1
high = n

def check(k, 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
	if m <= 0:
		return 1
	else:
		return 0
ans = []
while high >= low:
	mid = low + (high - low) // 2
	if check(mid, m):
		ans.append(mid)
		high = mid - 1
	else:
		low = mid + 1
if len(ans) > 0:
	print(min(ans))
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
		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
			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
		if avail(k):
			(start, end) = (start, k)
		else:
			(start, end) = (k + 1, end)
	if n == 1:
		print(1)
	else:
		print(start)


(n, m) = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort(reverse=True)
(l, r) = (1, n)
while l <= r:
	k = (l + r) // 2
	total = 0
	for i in range(n):
		total += max(0, arr[i] - i // k)
	if total < m:
		l = k + 1
	else:
		r = k - 1
if l > n:
	print(-1)
else:
	print(r + 1)


import sys
input = sys.stdin.buffer.readline
(n, m) = map(int, input().split())
a = list(map(int, input().split()))
a.sort(reverse=True)
a = [0] + a
sum_a = []
add = 0
for i in range(n + 1):
	add += a[i]
	sum_a.append(add)
mini = 999999999999999
p = n
i = 0
if sum(a) < m:
	print(-1)
else:
	flag = 0
	for i in range(n, 0, -1):
		while a[p] < (p - 1) // i:
			p -= 1
		if sum_a[p] - (p % i * (p // i) * (p // i + 1) // 2 + (i - p % i) * (p // i) * (p // i - 1) // 2) < m:
			flag = 1
			break
	if flag == 1:
		print(i + 1)
	else:
		print(i)


import sys
input = sys.stdin.readline

def judge(x):
	b = a[:]
	for i in range(n):
		b[i] = max(0, b[i] - i // x)
	return sum(b) >= m

def binary_search():
	(l, r) = (1, n)
	while l <= r:
		m = (l + r) // 2
		if judge(m):
			r = m - 1
		else:
			l = m + 1
	return l
(n, m) = map(int, input().split())
a = list(map(int, input().split()))
a.sort(reverse=True)
ans = binary_search()
if ans == n + 1:
	print(-1)
else:
	print(ans)


def isvalid(d, li, m):
	if d == 0:
		return 0
	n = len(li)
	sumi = 0
	for i in range(n):
		sumi += max(0, li[i] - i // d)
	if sumi >= m:
		return 1
	return 0

def binary_search(li, left, right, m):
	if right < left:
		return 0
	mid = (left + right) // 2
	if isvalid(mid, li, m):
		if isvalid(mid - 1, li, m) == 0:
			return mid
		return binary_search(li, left, mid - 1, m)
	return binary_search(li, mid + 1, right, m)
l = input().split()
n = int(l[0])
m = int(l[1])
l = input().split()
li = [int(i) for i in l]
li.sort()
li.reverse()
if sum(li) < m:
	print(-1)
else:
	print(binary_search(li, 1, 2 * 10 ** 5 + 1, m))


def check(a, k, m):
	s = 0
	for (i, v) in enumerate(a):
		s += max(0, a[i] - i // k)
	return s >= m

def main():
	(n, m) = map(int, input().split())
	a = list(map(int, input().split()))
	a.sort(reverse=True)
	(left, right, ret) = (1, n, n + 1)
	while left <= right:
		mid = (left + right) // 2
		if check(a, mid, m):
			right = mid - 1
			ret = mid
		else:
			left = mid + 1
	print(ret if ret <= n else -1)
main()


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

def search(i):
	s = 0
	for j in range(n):
		s += max(0, a[j] - j // i)
	return s >= m
(l, r) = (1, n)
while r - l > 1:
	mid = (l + r) // 2
	if search(mid):
		r = mid
	else:
		l = mid
if search(l):
	print(l)
elif search(r):
	print(r)
else:
	print(-1)


def check(k):
	s = 0
	for i in range(n):
		s += max(0, a[i] - i // k)
	return s >= m
(n, m) = map(int, input().split())
a = list(map(int, input().split()))
a.sort(reverse=True)
low = 1
high = n + 1
while low <= high:
	mid = (low + high) // 2
	if check(mid):
		high = mid - 1
	else:
		low = mid + 1
if low <= n:
	print(low)
else:
	print(-1)


(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)


import os
import sys
from io import BytesIO, IOBase
_print = print
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def inp():
	return sys.stdin.readline().rstrip()

def mpint():
	return map(int, inp().split(' '))

def itg():
	return int(inp())

def amortized_tuple(n, m) -> tuple:
	(q, r) = divmod(n, m)
	return (q, m - r, r)
from itertools import accumulate

def solve():
	(n, m) = mpint()
	coffee = sorted(mpint(), reverse=True)
	prefix = tuple(accumulate(coffee))

	def check(d):
		for (num, s) in enumerate(prefix, 1):
			(q, a, b) = amortized_tuple(num, d)
			c2 = max(0, q * (q + 1) // 2)
			c1 = max(0, c2 - q)
			cost = c1 * a + c2 * b
			if s - cost >= m:
				return True
		return False
	(lo, hi) = (1, n + 1)
	while lo < hi:
		mi = lo + hi >> 1
		if check(mi):
			hi = mi
		else:
			lo = mi + 1
	return -1 if lo == n + 1 else lo

def main():
	print(solve())
DEBUG = 0
URL = 'https://codeforces.com/contest/1118/problem/D2'
if DEBUG == 1:
	import requests
	from ACgenerator.Y_Test_Case_Runner import TestCaseRunner
	runner = TestCaseRunner(main, URL)
	inp = runner.input_stream
	print = runner.output_stream
	runner.checking()
else:
	if DEBUG != 2:
		(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	if DEBUG:

		def print(*args, **kwargs):
			_print(*args, **kwargs)
			sys.stdout.flush()
	main()


def check(arr, d, mm):
	ss = 0
	k = -1
	for i in range(n):
		if i % d == 0:
			k += 1
		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 sys import exit
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)
solve()


def check(mid):
	tp = su = s = 0
	for i in range(n):
		su += max(0, lis[i] - s)
		tp += 1
		if tp == mid:
			s += 1
			tp = 0
	return su >= m
(n, m) = map(int, input().split())
lis = sorted(map(int, input().split()), reverse=True)
if sum(lis) < m:
	print('-1')
elif sum(lis) == m:
	print(len(lis))
else:
	l = 1
	r = n
	while l <= r:
		mid = l + r >> 1
		if check(mid):
			r = mid - 1
			ans = mid
		else:
			l = mid + 1
	print(ans)


import math, sys
from sys import stdin, stdout
from collections import Counter, defaultdict, deque
input = stdin.readline
I = lambda : int(input())
li = lambda : list(map(int, input().split()))

def solve(a, mid, s):
	c = 0
	i = 0
	p = 0
	while i < len(a):
		c += max(0, a[i] - p)
		i = i + 1
		if not i % mid:
			p += 1
		if c >= s:
			return 1
	return 0

def case(test):
	(n, s) = li()
	a = li()
	if sum(a) < s:
		print(-1)
		return
	a.sort(reverse=True)
	(l, r) = (1, n)
	m = n
	while l <= r:
		mid = (l + r) // 2
		p = solve(a, mid, s)
		if p:
			r = mid - 1
			m = min(m, mid)
		else:
			l = mid + 1
	print(m)
for test in range(1):
	case(test + 1)


from sys import stdin, stdout
from itertools import combinations
from collections import defaultdict, OrderedDict
import math
import heapq

def listIn():
	return list(map(int, stdin.readline().strip().split()))

def stringListIn():
	return [x for x in stdin.readline().split()]

def intIn():
	return int(stdin.readline())

def stringIn():
	return stdin.readline().strip()
(n, m) = listIn()
a = listIn()
if m > sum(a):
	print(-1)
else:
	a.sort(reverse=True)
	s = sum(a)
	f = 1
	day = 1
	sum_arr = [0] * n
	for i in range(n):
		if i == 0:
			sum_arr[i] = a[i]
		else:
			sum_arr[i] = sum_arr[i - 1] + a[i]
	i = 1
	k = n
	while i <= k:
		day = (i + k) // 2
		p_sum = 0
		for j in range(n):
			t = a[j] - j // day
			if t > 0:
				p_sum += t
			else:
				break
		if p_sum >= m:
			f = 1
			res = day
			k = day - 1
		else:
			i = day + 1
	print(res)


import bisect
from itertools import accumulate, count
import os
import sys
import math
from decimal import *
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))

def input():
	return sys.stdin.readline().rstrip('\r\n')

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True

def SieveOfEratosthenes(n):
	prime = []
	primes = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if primes[p] == True:
			for i in range(p * p, n + 1, p):
				primes[i] = False
		p += 1
	for i in range(2, len(primes)):
		if primes[i] == True:
			prime.append(i)
	return prime

def primefactors(n):
	fac = []
	while n % 2 == 0:
		fac.append(2)
		n = n // 2
	for i in range(3, int(math.sqrt(n)) + 2):
		while n % i == 0:
			fac.append(i)
			n = n // i
	if n > 1:
		fac.append(n)
	return fac

def factors(n):
	fac = set()
	fac.add(1)
	fac.add(n)
	for i in range(2, int(math.sqrt(n)) + 1):
		if n % i == 0:
			fac.add(i)
			fac.add(n // i)
	return list(fac)

def NcR(n, r):
	p = 1
	k = 1
	if n - r < r:
		r = n - r
	if r != 0:
		while r:
			p *= n
			k *= r
			m = math.gcd(p, k)
			p //= m
			k //= m
			n -= 1
			r -= 1
	else:
		p = 1
	return p

def Log2(x):
	if x == 0:
		return False
	return math.log10(x) / math.log10(2)

def isPowerOfTwo(n):
	return math.ceil(Log2(n)) == math.floor(Log2(n))
(n, m) = map(int, input().split())
a = sorted(list(map(int, input().split())))
a = a[::-1]

def solve(days):
	pages = 0
	for i in range(n):
		pages += max(0, a[i] - i // days)
	return pages >= m
res = -1
lo = 1
hi = n + 1
while lo < hi:
	mid = lo + (hi - lo) // 2
	if solve(mid):
		hi = mid
	else:
		lo = mid + 1
print(lo if lo <= n else -1)


import sys
import math
input = sys.stdin.readline
for _ in range(1):
	(n, m) = map(int, input().split())
	l = list(map(int, input().split()))
	l.sort(reverse=True)
	if sum(l) < m:
		print(-1)
		continue
	ans = 10 ** 18
	low = 1
	high = n
	while low < high:
		mid = low + (high - low) // 2
		som = 0
		for i in range(n):
			x = l[i]
			som = som + max(x - i // mid, 0)
		if som >= m:
			high = mid
		else:
			low = mid + 1
	print(high)


import sys
input = sys.stdin.readline

def binary_search(c1, c2):
	mi = (c1 + c2 + 1) // 2
	if abs(c1 - c2) <= 1:
		return error_check(mi)
	else:
		if ok(mi):
			c2 = mi
		else:
			c1 = mi
		return binary_search(c1, c2)

def ok(x):
	c = 0
	for i in range(n):
		if a[i] >= i // x:
			c += a[i] - i // x
		else:
			break
	return True if c >= m else False

def error_check(x):
	for i in range(max(1, x - 3), max(n + 1, x + 4)):
		if ok(i):
			return i
(n, m) = map(int, input().split())
a = list(map(int, input().split()))
a.sort(reverse=True)
ans = binary_search(0, n + 1) if sum(a) >= m else -1
print(ans)


def func(mid):
	s = 0
	c = 0
	v = 0
	for i in range(n):
		c += 1
		s += max(a[i] - v, 0)
		if c == mid:
			v += 1
			c = 0
	return s >= m
(n, m) = map(int, input().split())
a = [int(x) for x in input().split()]
a.sort(reverse=True)
an = 0
if sum(a) < m:
	an = -1
up = n
do = 1
while up >= do:
	mid = (up + do) // 2
	if func(mid):
		an = mid
		up = mid - 1
	else:
		do = mid + 1
print(an)


def fastio():
	import sys
	from io import StringIO
	from atexit import register
	global input
	sys.stdin = StringIO(sys.stdin.read())
	input = lambda : sys.stdin.readline().rstrip('\r\n')
	sys.stdout = StringIO()
	register(lambda : sys.__stdout__.write(sys.stdout.getvalue()))
MOD = 10 ** 9 + 7
I = lambda : list(map(int, input().split()))
(n, m) = I()
l = I()
l.sort(reverse=True)
lo = 1
hi = 10 ** 20

def check(k):
	s = 0
	i = 0
	d = 0
	while i < n and s < m:
		s += max(0, l[i] - d)
		i += 1
		if i % k == 0:
			d += 1
	return s >= m
while lo < hi:
	mid = (lo + hi) // 2
	if check(mid):
		hi = mid
	else:
		lo = mid + 1
if lo == 10 ** 20:
	print(-1)
	exit()
print(lo)


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)


(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)


from sys import stdin, stdout
import collections
import math
(N, M) = [int(x) for x in stdin.readline().split()]
arr = [int(x) for x in stdin.readline().split()]
arr.sort(reverse=True)
if sum(arr) < M:
	print(-1)
	quit()
left = 1
right = 0
s = 0
for i in range(N):
	if s <= M:
		right += 1
	else:
		break
	s += arr[i]
res = right
while left <= right:
	mid = (left + right) // 2
	k = 0
	fill = 0
	flag = 0
	for i in range(N):
		for j in range(mid):
			effect = arr[k] - i
			fill += effect
			k += 1
			if effect == 0 or fill >= M or k == N:
				flag = 1
				break
		if flag == 1:
			break
	if fill < M:
		left = mid + 1
	elif fill >= M:
		res = min(res, mid)
		right = mid - 1
print(res)


from sys import exit, setrecursionlimit
setrecursionlimit(10 ** 6)
inn = lambda : input().strip()
mapp = lambda : map(int, inn().split(' '))
(N, work) = mapp()
coffee = list(mapp())
coffee.sort(reverse=True)
if sum(coffee) < work:
	print(-1)
	exit()

def getMaxPower(day):
	if day == 0:
		return False
	maxPower = 0
	for (i, a) in enumerate(coffee):
		add = a - i // day
		if add <= 0:
			break
		maxPower += add
	return maxPower
(lo, hi) = (-1, 1000000001)
for a in range(36):
	mid = (lo + hi) // 2
	if getMaxPower(mid) >= work:
		hi = mid
	else:
		lo = mid
print(hi)


def solveFor(m):
	sm = 0
	for i in range(m):
		ct = 0
		for j in range(i, n, m):
			if arr[j] > ct:
				sm += arr[j] - ct
			else:
				break
			ct += 1
	return sm
(n, k) = map(int, input().split())
arr = list(map(int, input().split()))
arr.sort()
arr = arr[::-1]
begin = 1
end = n
ans = -1
while begin <= end:
	mid = (begin + end) // 2
	value = solveFor(mid)
	if value == k:
		ans = mid
		break
	elif value > k:
		ans = mid
		end = mid - 1
	else:
		begin = mid + 1
print(ans)


import os
import sys
from io import BytesIO, IOBase

def check(a, mid, m):
	(z, su, j) = (0, 0, 0)
	for i in a:
		su += max(i - z, 0)
		j += 1
		if j == mid:
			j = 0
			z += 1
	return su >= m

def main():
	(n, m) = map(int, input().split())
	a = sorted(map(int, input().split()), reverse=True)
	if sum(a) < m:
		print(-1)
	else:
		(lo, hi, ans) = (1, n, 1)
		while lo <= hi:
			mid = (lo + hi) // 2
			if check(a, mid, m):
				hi = mid - 1
				ans = mid
			else:
				lo = mid + 1
		print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()