AtCoder Beginner Contest 155 - Pairs

We have N integers A_1, A_2, ..., A_N.
There are \frac{N(N-1)}{2} ways to choose two of them and form a pair. If we compute the product of each of those pairs and sort the results in ascending order, what will be the K-th number in that list?

-----Constraints-----
 - All values in input are integers.
 - 2 \leq N \leq 2 \times 10^5
 - 1 \leq K \leq \frac{N(N-1)}{2}
 - -10^9 \leq A_i \leq 10^9\ (1 \leq i \leq N)

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

-----Output-----
Print the answer.

-----Sample Input-----
4 3
3 3 -4 -2

-----Sample Output-----
-6

There are six ways to form a pair. The products of those pairs are 9, -12, -6, -12, -6, 8.
Sorting those numbers in ascending order, we have -12, -12, -6, -6, 8, 9. The third number in this list is -6.

Difficulty: MEDIUM_HARD

Starter code:

Solutions:
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
Am = []
n0 = 0
Ap = []
for a in A:
	if a < 0:
		Am.append(a)
	if a == 0:
		n0 += 1
	if a > 0:
		Ap.append(a)
Am = sorted(Am)
Ap = sorted(Ap)
nm = len(Am)
np = len(Ap)
Nm = nm * np
N0 = n0 * (n0 - 1) // 2 + n0 * (nm + np)
Np = nm * (nm - 1) // 2 + np * (np - 1) // 2
if K <= Nm:
	min_ok = 0
	max_ng = -10 ** 20
	while min_ok - max_ng > 1:
		tgt = (min_ok + max_ng) // 2
		k = 0
		i = 0
		for a in Am:
			while i < np and a * Ap[i] > tgt:
				i += 1
			k += np - i
		if k >= K:
			min_ok = tgt
		else:
			max_ng = tgt
	print(min_ok)
elif K <= Nm + N0:
	print(0)
else:
	K -= Nm + N0
	Am = [-a for a in Am[::-1]]
	min_ok = +10 ** 20
	max_ng = 0
	while min_ok - max_ng > 1:
		tgt = (min_ok + max_ng) // 2
		k = 0
		i = np - 1
		for (j, a) in enumerate(Ap):
			while i >= 0 and a * Ap[i] > tgt:
				i -= 1
			if i <= j:
				break
			k += i - j
		i = nm - 1
		for (j, a) in enumerate(Am):
			while i >= 0 and a * Am[i] > tgt:
				i -= 1
			if i <= j:
				break
			k += i - j
		if k >= K:
			min_ok = tgt
		else:
			max_ng = tgt
	print(min_ok)


import sys
import numpy as np
(N, K) = map(int, sys.stdin.readline().rstrip().split())
A = np.array(sys.stdin.readline().rstrip().split(), np.int64)
A = np.sort(A)
zero = A[A == 0]
pos = A[A > 0]
neg = A[A < 0]

def f2(x):
	cnt_tpl = 0
	B = A.copy()
	B = -B
	B.sort()
	cnt_tpl += np.searchsorted(B, x // -neg, side='right').sum()
	if x >= 0:
		cnt_tpl += len(zero) * N
	cnt_tpl += np.searchsorted(A, x // pos, side='right').sum()
	cnt_tpl -= np.count_nonzero(A * A <= x)
	assert cnt_tpl % 2 == 0
	return cnt_tpl // 2
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	x = (left + right) // 2
	if f2(x) >= K:
		right = x
	else:
		left = x
print(right)


def comb(li):
	return len(li) * (len(li) - 1) // 2

def count_large(x, li):
	cnt = 0
	j = 0
	for e in li:
		cnt -= e * e >= x
		while li[j - 1] * e >= x:
			j -= 1
		cnt -= j
	cnt //= 2
	return cnt
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
INF = 10 ** 20
neg = []
pos = []
for e in a:
	if e > 0:
		pos.append(e)
	elif e < 0:
		neg.append(e)
if k <= len(pos) * len(neg):
	neg.sort()
	neg.append(0)
	pos.sort()
	lb = -10 ** 18 - 1
	ub = 0
	while ub - lb > 1:
		m = (lb + ub) // 2
		j = -1
		cnt = 0
		for e in pos:
			while neg[j + 1] * e <= m:
				j += 1
			cnt += j + 1
		if cnt >= k:
			ub = m
		else:
			lb = m
	print(ub)
elif k >= n * (n - 1) // 2 - comb(pos) - comb(neg) + 1:
	neg = [-e for e in neg]
	neg.append(0)
	neg.sort()
	pos.append(0)
	pos.sort()
	lb = 1
	ub = 10 ** 18 + 1
	while ub - lb > 1:
		m = (lb + ub) // 2
		cnt = count_large(m, neg) + count_large(m, pos)
		if cnt >= n * (n - 1) // 2 - k + 1:
			lb = m
		else:
			ub = m
	print(lb)
else:
	print(0)


from bisect import bisect_left

def binsearch(l, r, fn):
	while r - l > 1:
		m = (l + r) // 2
		if fn(m):
			l = m
		else:
			r = m
	return l

def main():
	(N, K) = list(map(int, input().split()))
	A = sorted(list(map(int, input().split())))
	p = bisect_left(A, 0)
	An = A[:p]
	Ap = A[p:]
	if K <= p * (N - p):

		def helper(x):
			t = 0
			r = 0
			for p in Ap:
				while t < len(An) and An[t] * p <= x:
					t += 1
				r += t
			return r < K
		l = binsearch(Ap[-1] * An[0] - 1, 1, helper)
	else:
		K -= p * (N - p)
		An.reverse()

		def helper(x):
			r = 0
			for a in [Ap, An]:
				t = len(a) - 1
				for (i, p) in enumerate(a):
					if t <= i:
						break
					while t > i and a[t] * p > x:
						t -= 1
					r += t - i
			return r < K
		m = Ap[-1]
		if An:
			m = max(m, -An[-1])
		l = binsearch(-1, m * m, helper)
	print(l + 1)
main()


def d_pairs():
	import numpy as np
	(N, K) = [int(i) for i in input().split()]
	A = np.array([int(i) for i in input().split()], np.int64)
	A = np.sort(A)
	zero = A[A == 0]
	positive = A[A > 0]
	negative = A[A < 0]

	def f(c):
		count_pair = 0
		if c >= 0:
			count_pair += len(zero) * N
		count_pair += np.searchsorted(A, c // positive, side='right').sum()
		count_pair += (N - np.searchsorted(A, (-c - 1) // -negative, side='right')).sum()
		count_pair -= np.count_nonzero(A * A <= c)
		return count_pair // 2
	(lower, upper) = (-10 ** 18, 10 ** 18)
	while upper - lower > 1:
		x = (lower + upper) // 2
		if f(x) >= K:
			upper = x
		else:
			lower = x
	return upper
print(d_pairs())


import numpy as np

def get_Negative(K, pos, neg):
	K = len(pos) * len(neg) - K + 1
	l = 0
	r = 10 ** 18 + 10
	while r - l > 1:
		m = (l + r) // 2
		target = m // pos
		x = np.searchsorted(neg, target, side='right').sum()
		if x >= K:
			r = m
		else:
			l = m
	return -r

def get_Positive(K, pos, neg):
	l = 0
	r = 10 ** 18 + 10
	tmp_pos = np.arange(len(pos))
	tmp_neg = np.arange(len(neg))
	while r - l > 1:
		m = (r + l) // 2
		cnt = 0
		if len(pos) > 1:
			t1 = m // pos
			x1 = np.searchsorted(pos, t1, side='right')
			x1 = np.maximum(0, x1 - tmp_pos - 1)
			cnt += x1.sum()
		if len(neg) > 0:
			t2 = m // neg
			x2 = np.searchsorted(neg, t2, side='right')
			x2 = np.maximum(0, x2 - tmp_neg - 1)
			cnt += x2.sum()
		if cnt >= K:
			r = m
		else:
			l = m
	return r

def main():
	(N, K) = map(int, input().split())
	A = np.array(input().split(), dtype=np.int64)
	positive = A[A > 0]
	negative = -A[A < 0]
	positive.sort()
	negative.sort()
	Npos = len(positive)
	Nneg = len(negative)
	Nzero = N - Npos - Nneg
	P_neg = Npos * Nneg
	P_pos = 0
	if Npos:
		P_pos += Npos * (Npos - 1) // 2
	if Nneg:
		P_pos += Nneg * (Nneg - 1) // 2
	P_zero = N * (N - 1) // 2 - P_pos - P_neg
	if K <= P_neg:
		ans = get_Negative(K, positive, negative)
		return ans
	K -= P_neg
	if K <= P_zero:
		return 0
	K -= P_zero
	ans = get_Positive(K, positive, negative)
	return ans

def __starting_point():
	print(main())
__starting_point()


import numpy as np
(n, k) = list(map(int, input().split()))
a = list(map(int, input().split()))
a = np.array(a)
a.sort()
p = a[a > 0]
z = a[a == 0]
m = a[a < 0]
low = -10 ** 18
high = 10 ** 18
while high - low > 1:
	mid = (high + low) // 2
	count = 0
	if mid >= 0:
		count += len(z) * n
	count += a.searchsorted(mid // p, side='right').sum()
	count += (n - a.searchsorted(-(-mid // m), side='left')).sum()
	count -= np.count_nonzero(a * a <= mid)
	count /= 2
	if count >= k:
		high = mid
	if count < k:
		low = mid
print(high)


import numpy as np
(n, k) = list(map(int, input().split()))
A = np.array(input().split(), np.int64)
A.sort()
zero = A[A == 0]
neg = A[A < 0]
pos = A[A > 0]

def f(x):
	cnt = 0
	if x >= 0:
		cnt += len(zero) * n
	cnt += A.searchsorted(x // pos, side='right').sum()
	cnt += (n - A.searchsorted(-(-x // neg), side='left')).sum()
	cnt -= np.count_nonzero(A * A <= x)
	return cnt // 2
l = -10 ** 18
r = 10 ** 18
while l < r:
	pov = (l + r) // 2
	if f(pov) >= k:
		r = pov
	else:
		l = pov + 1
print(l)


import sys
sr = lambda : sys.stdin.readline().rstrip()
ir = lambda : int(sr())
lr = lambda : list(map(int, sr().split()))
import numpy as np

def resolve():
	(N, K) = lr()
	A = np.sort(np.array(lr(), np.int64))
	z = A[A == 0]
	p = A[A > 0]
	n = A[A < 0]

	def count_func(x):
		cnt = 0
		if x >= 0:
			cnt += len(z) * N
		cnt += np.searchsorted(A, x // p, side='right').sum()
		cnt += (N - np.searchsorted(A, -(-x // n), side='left')).sum()
		cnt -= np.count_nonzero(A * A <= x)
		assert cnt % 2 == 0
		return cnt // 2
	l = -10 ** 18
	r = 10 ** 18
	while l + 1 < r:
		x = (l + r) // 2
		if count_func(x) >= K:
			r = x
		else:
			l = x
	print(r)
resolve()


import numpy as np
(N, K) = list(map(int, input().split()))
A = np.sort(np.array(input().split(), np.int64))
z = A[A == 0]
p = A[A > 0]
n = A[A < 0]

def check(x):
	count = 0
	if x >= 0:
		count += len(z) * N
	count += np.searchsorted(A, x // p, side='right').sum()
	count += (N - np.searchsorted(A, (-x - 1) // -n, side='right')).sum()
	count -= np.count_nonzero(A * A <= x)
	assert count % 2 == 0
	count //= 2
	return count >= K
left = -10 ** 19
right = 10 ** 19
while right > left + 1:
	mid = (left + right) // 2
	if check(mid):
		right = mid
	else:
		left = mid
print(right)


import numpy as np
import sys
input = sys.stdin.readline
(n, k) = [int(x) for x in input().split()]
A = np.array([int(a) for a in input().split()], dtype='int64')
A = np.sort(A)
A_pos = A[A > 0]
A_neg = A[A < 0]
A_zero = A[A == 0]

def n_comb_lt(c):
	n_comb = 0
	target = c // A_pos
	n_comb += np.searchsorted(A, target, side='right').sum()
	n_comb += n * len(A_zero) if c >= 0 else 0
	target = -(-c // A_neg)
	n_comb += (n - np.searchsorted(A, target, side='left')).sum()
	n_comb -= A[A * A <= c].size
	n_comb //= 2
	return n_comb
ok = -10 ** 18 - 1
ng = 10 ** 18 + 1
while ng - ok > 1:
	mid = (ng + ok) // 2
	if n_comb_lt(mid - 1) < k:
		ok = mid
	else:
		ng = mid
print(ok)


(N, K) = map(int, input().split())
A = list(map(int, input().split()))
P = []
M = []
z = 0
for a in A:
	if a == 0:
		z += 1
	elif a > 0:
		P.append(a)
	else:
		M.append(a)
P.sort()
M.sort()

def helper(n):
	if n < 0:
		res = 0
		p = 0
		for m in range(len(M)):
			while p < len(P) and P[p] * M[m] > n:
				p += 1
			res += len(P) - p
	elif n == 0:
		res = len(P) * len(M) + z * (N - z) + z * (z - 1) // 2
	else:
		res = len(P) * len(M) + z * (N - z) + z * (z - 1) // 2
		pr = len(P) - 1
		for pl in range(len(P)):
			while pr > pl and P[pl] * P[pr] > n:
				pr -= 1
			res += max(0, pr - pl)
		ml = 0
		for mr in range(len(M) - 1, -1, -1):
			while mr > ml and M[ml] * M[mr] > n:
				ml += 1
			res += max(0, mr - ml)
	return res
l = -10 ** 18
r = 10 ** 18
while True:
	num = (l + r) // 2
	if helper(num) < K:
		l = num
	else:
		r = num
	if r - l <= 1:
		print(r)
		break


import numpy as np
(N, K) = map(int, input().split())
A = np.array(list(map(int, input().split())))
A.sort()
G = A[A > 0]
Z = A[A == 0]
L = A[A < 0]
ok = 10 ** 18 + 1
ng = -10 ** 18 - 1
while ok - ng > 1:
	mid = (ng + ok) // 2
	cg = np.searchsorted(A, mid // G, side='right').sum()
	cl = (N - np.searchsorted(A, (-mid - 1) // -L, side='right')).sum()
	d = np.count_nonzero(A * A <= mid)
	z = 0
	if mid >= 0:
		z += len(Z) * N
	c = cg + cl + z - d
	c //= 2
	if c >= K:
		ok = mid
	else:
		ng = mid
print(ok)


(n, k) = map(int, input().split())
a = list(map(int, input().split()))
minus = [-x for x in a if x < 0]
plus = [x for x in a if x >= 0]
minus.sort()
plus.sort()

def cnt(x):
	ans = 0
	if x < 0:
		x = -x
		r = 0
		for num in minus[::-1]:
			while r < len(plus) and plus[r] * num < x:
				r += 1
			ans += len(plus) - r
		return ans
	r = 0
	for num in minus[::-1]:
		if num * num <= x:
			ans -= 1
		while r < len(minus) and minus[r] * num <= x:
			r += 1
		ans += r
	r = 0
	for num in plus[::-1]:
		if num * num <= x:
			ans -= 1
		while r < len(plus) and plus[r] * num <= x:
			r += 1
		ans += r
	ans //= 2
	ans += len(minus) * len(plus)
	return ans
bottom = 0
top = 2 * 10 ** 18 + 2
while top - bottom > 1:
	mid = (top + bottom) // 2
	if cnt(mid - 10 ** 18 - 1) < k:
		bottom = mid
	else:
		top = mid
print(int(top - 10 ** 18 - 1))


from sys import stdin
import numpy as np

def main():
	readline = stdin.readline
	(n, k) = map(int, readline().split())
	a = np.array(readline().strip().split(), dtype='int64')
	a.sort()
	neg = a[a < 0]
	neg_p = neg ** 2
	zero = a[a == 0]
	pos = a[a > 0]
	pos_p = pos ** 2
	l = -10 ** 18 - 1
	r = 10 ** 18
	while l < r - 1:
		x = (l + r) // 2
		cnt = 0
		if neg.size > 0:
			cnt += (a.size - np.searchsorted(a, (x + neg + 1) // neg)).sum()
			cnt -= neg_p[neg_p <= x].size
		if zero.size > 0:
			if x >= 0:
				cnt += (a.size - 1) * zero.size
		if pos.size > 0:
			cnt += np.searchsorted(a, x // pos, side='right').sum()
			cnt -= pos_p[pos_p <= x].size
		cnt //= 2
		if cnt >= k:
			r = x
		else:
			l = x
	print(r)

def __starting_point():
	main()
__starting_point()


import numpy as np
(n, k) = [int(i) for i in input().split()]
a = np.array(sorted([int(i) for i in input().split()]))
posi = a[a > 0]
zero = a[a == 0]
nega = a[a < 0]
l = -10 ** 18 - 1
r = 10 ** 18 + 1
while r - l > 1:
	mid = (r + l) // 2
	cnt = 0
	if mid >= 0:
		cnt += len(zero) * n
	cnt += a.searchsorted(mid // posi, side='right').sum()
	cnt += (n - a.searchsorted(-(-mid // nega), side='left')).sum()
	cnt -= np.count_nonzero(a * a <= mid)
	cnt //= 2
	if cnt >= k:
		r = mid
	else:
		l = mid
print(r)


(n, k) = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
inf = int(1e+18) + 1
l = -inf
r = inf
while l + 1 < r:
	c = (l + r) // 2
	cnt = 0
	for i in range(n):
		if a[i] < 0:
			_l = i
			_r = n
			while _l + 1 < _r:
				_c = (_l + _r) // 2
				if a[i] * a[_c] >= c:
					_l = _c
				else:
					_r = _c
			if _r != n:
				cnt += n - _r
		else:
			_l = i
			_r = n
			while _l + 1 < _r:
				_c = (_l + _r) // 2
				if a[i] * a[_c] < c:
					_l = _c
				else:
					_r = _c
			if _l != i:
				cnt += _l - i
	if cnt < k:
		l = c
	else:
		r = c
print(l)


import sys
(n, k) = map(int, sys.stdin.readline().strip().split())
a = map(int, sys.stdin.readline().strip().split())

def main(n, k, a):
	nega = []
	posi = []
	zeros = 0
	for ai in a:
		if ai < 0:
			nega.append(ai)
		elif ai > 0:
			posi.append(ai)
		else:
			zeros += 1
	posi.sort()
	nega.sort(reverse=True)
	ng = -10 ** 18 - 1
	ok = 10 ** 18 + 1
	while ok - ng > 1:
		mid = (ok + ng) // 2
		cnt = 0
		if mid >= 0:
			cnt += zeros * (zeros - 1) // 2 + zeros * (n - zeros)
		if mid > 0:
			cnt += len(nega) * len(posi)
			for a in (posi, nega):
				l = 0
				r = len(a) - 1
				while l < r:
					while l < r and a[l] * a[r] > mid:
						r -= 1
					cnt += r - l
					l += 1
		else:
			r = len(nega) - 1
			for l in range(len(posi)):
				while r >= 0 and posi[l] * nega[r] <= mid:
					r -= 1
				cnt += len(nega) - r - 1
		if cnt >= k:
			ok = mid
		else:
			ng = mid
	print(ok)
main(n, k, a)


import numpy as np
(n, k) = map(int, input().split())
a = np.array(list(map(int, input().split())))
a.sort()
posi = a[a > 0]
zero = a[a == 0]
nega = a[a < 0]
l = -10 ** 18 - 1
r = 10 ** 18 + 1
while r - l > 1:
	mid = (r + l) // 2
	cnt = 0
	if mid >= 0:
		cnt += len(zero) * n
	cnt += a.searchsorted(mid // posi, side='right').sum()
	cnt += (n - a.searchsorted(-(-mid // nega), side='left')).sum()
	cnt -= np.count_nonzero(a * a <= mid)
	cnt //= 2
	if cnt >= k:
		r = mid
	else:
		l = mid
print(r)


def main():
	from bisect import bisect
	(n, k, *a) = map(int, open(0).read().split())
	a.sort()
	i = bisect(a, 0)
	(a, b) = (a[i:], a[i - 1::-1])
	(n, m) = (len(a), len(b))
	ok = 10 ** 18
	ng = -ok
	while ok - ng > 1:
		x = (ok + ng) // 2
		s = 0
		if x >= 0:
			s += n * m
			t = 0
			i = n
			for y in a:
				while i and a[i - 1] * y > x:
					i -= 1
				t += i
				if y * y <= x:
					t -= 1
			s += t // 2
			t = 0
			i = m
			for y in b:
				while i and b[i - 1] * y > x:
					i -= 1
				t += i
				if y * y <= x:
					t -= 1
			s += t // 2
		else:
			i = m
			for y in a:
				while i and b[i - 1] * y <= x:
					i -= 1
				s += m - i
		if s >= k:
			ok = x
		else:
			ng = x
	print(ok)
main()


import bisect
(n, k) = map(int, input().split())
a = sorted(map(int, input().split()))

def count(t):
	c = 0
	for x in a:
		if x == 0:
			c += len(a) - 1 if t >= 0 else 0
		elif x > 0:
			c += bisect.bisect_left(a, t // x + 1) - (x * x <= t)
		else:
			c += len(a) - bisect.bisect_left(a, -(t // -x)) - (x * x <= t)
	return c
lo = -1000000000000000001
hi = 1000000000000000001
while hi - lo > 1:
	mid = (lo + hi) // 2
	if count(mid) < k * 2:
		lo = mid
	else:
		hi = mid
print(hi)


import bisect
(n, k) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
zero = A.count(0)
inm = bisect.bisect_left(A, 0)
inp = bisect.bisect_right(A, 0)
mi = [-x for x in A[:inm]]
mi = mi[::-1]
pl = A[inp:]
numm = inm
nump = n - inp

def shaku(x, l):
	count = 0
	if len(l) <= 1:
		return 0
	ri = len(l) - 1
	for i in range(len(l)):
		while ri >= 0 and l[ri] * l[i] > x:
			ri -= 1
		count += max(ri - i, 0)
	return count

def search(x):
	count = 0
	if x >= 0:
		count += zero * (n - zero) + numm * nump + zero * (zero - 1) // 2
		count += shaku(x, pl)
		count += shaku(x, mi)
		return count
	else:
		ri = 0
		for i in pl[::-1]:
			while ri < numm and i * mi[ri] < -x:
				ri += 1
			count += numm - ri
		return count
left = -10 ** 18 - 1
right = 10 ** 18 + 1
while right > left + 1:
	mid = (left + right) // 2
	a = search(mid)
	if a >= k:
		right = mid
	else:
		left = mid
print(right)


import numpy as np

def main():
	(N, K) = [int(x) for x in input().split()]
	A = np.array(input().split(), np.int64)
	A = np.sort(A)
	minus = A[A < 0]
	zero = A[A == 0]
	plus = A[A > 0]

	def f(x):
		res = 0
		if x >= 0:
			res += len(zero) * N
		res += np.searchsorted(A, x // plus, side='right').sum()
		res += (N - np.searchsorted(A, (-x - 1) // -minus, side='right')).sum()
		res -= np.count_nonzero(A * A <= x)
		res //= 2
		return res
	l = -10 ** 18
	r = 10 ** 18
	while l + 1 < r:
		mid = (l + r) // 2
		if f(mid) >= K:
			r = mid
		else:
			l = mid
	print(r)

def __starting_point():
	main()
__starting_point()


(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
(mA, nA) = ([], [])
dd = []
for a in A:
	if a < 0:
		mA.append(a)
	else:
		nA.append(a)
	dd.append(a * a)
lnA = len(nA)
lmA = len(mA)

def F(idx):
	j = lnA - 1
	r = 0
	for a in nA:
		while j >= 0:
			if nA[j] * a <= idx:
				break
			j -= 1
		r += j + 1
	j = 0
	for a in mA[::-1]:
		while j < lmA:
			if mA[j] * a <= idx:
				break
			j += 1
		r += lmA - j
	j = 0
	for a in mA:
		while j < lnA:
			if nA[j] * a <= idx:
				break
			j += 1
		r += 2 * (lnA - j)
	for a in dd:
		if a <= idx:
			r -= 1
	return r // 2
(mx, mn) = (2 * 10 ** 18, -2 * 10 ** 18)
idx = (mx + mn) // 2
target = K
while mx - mn > 1:
	if F(idx) < target:
		(idx, mn) = ((idx + mx) // 2, idx)
		continue
	(idx, mx) = ((idx + mn) // 2, idx)
print(idx + 1)


import sys
import numpy as np
sr = lambda : sys.stdin.readline().rstrip()
ir = lambda : int(sr())
lr = lambda : list(map(int, sr().split()))
(N, K) = lr()
A = np.array(lr())
A.sort()
neg = A[A < 0]
zero = A[A == 0]
pos = A[A > 0]

def check(x):
	cnt = 0
	if x >= 0:
		cnt += len(zero) * N
	cnt += np.searchsorted(A, x // pos, side='right').sum()
	cnt += (N - np.searchsorted(A, (-x - 1) // -neg, side='right')).sum()
	cnt -= np.count_nonzero(A * A <= x)
	assert cnt % 2 == 0
	return cnt // 2 >= K
ok = 10 ** 18
ng = -10 ** 18 - 1
while abs(ng - ok) > 1:
	mid = (ok + ng) // 2
	if check(mid):
		ok = mid
	else:
		ng = mid
print(ok)


import numpy as np
(n, k) = map(int, input().split())
a = np.array(list(map(int, input().split())))
a.sort()
posi = a[a > 0]
zero = a[a == 0]
nega = a[a < 0]

def cnt(x):
	c = 0
	if x >= 0:
		c += len(zero) * n
	c += np.searchsorted(a, x // posi, side='right').sum()
	c += (n - np.searchsorted(a, (-x - 1) // -nega, side='right')).sum()
	c -= np.count_nonzero(a * a <= x)
	return c // 2
l = -10 ** 18
r = 10 ** 18
while l + 1 < r:
	m = (l + r) // 2
	if cnt(m) < k:
		l = m
	else:
		r = m
print(r)


def solve():
	from bisect import bisect_left, bisect_right
	(N, K) = map(int, input().split())
	As = list(map(int, input().split()))
	As.sort()
	negAs = [-A for A in As[::-1]]
	A2s = [A * A for A in As]
	A2s.sort()
	pstvBs = []
	numB0 = 0
	ngtvBs = []
	for A in As:
		if A > 0:
			pstvBs.append(A)
		elif A == 0:
			numB0 += 1
		else:
			ngtvBs.append(A)

	def isOK(x):
		if x >= 0:
			dire = 1
		else:
			dire = -1
		num = 0
		iA = 0
		for B in pstvBs[::-dire]:
			key = x // B
			while iA < N and As[iA] <= key:
				iA += 1
			num += iA
		if x >= 0:
			num += N * numB0
		iA = 0
		for B in ngtvBs[::dire]:
			key = x // -B
			while iA < N and negAs[iA] <= key:
				iA += 1
			num += iA
		i = bisect_right(A2s, x)
		num -= i
		num //= 2
		return num >= K
	(ng, ok) = (-10 ** 18 - 1, 10 ** 18 + 1)
	while abs(ok - ng) > 1:
		mid = (ng + ok) // 2
		if isOK(mid):
			ok = mid
		else:
			ng = mid
	print(ok)
solve()


(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
ll = -10 ** 18 - 1
rr = 10 ** 18 + 1
while ll + 1 < rr:
	x = (ll + rr) // 2
	tot = 0
	for i in range(N):
		if A[i] < 0:
			l = -1
			r = N
			while l + 1 < r:
				c = (l + r) // 2
				if A[i] * A[c] < x:
					r = c
				else:
					l = c
			tot += N - r
		else:
			l = -1
			r = N
			while l + 1 < r:
				c = (l + r) // 2
				if A[i] * A[c] < x:
					l = c
				else:
					r = c
			tot += r
		if A[i] * A[i] < x:
			tot -= 1
	tot //= 2
	if tot < K:
		ll = x
	else:
		rr = x
print(ll)


import numpy as np
(N, K) = list(map(int, input().split()))
A = np.array(tuple(map(int, input().split())), dtype=np.int64)
A = np.sort(A)
pos = A[A > 0]
neg = A[A < 0]
zero = len(A[A == 0])

def cnt(x):
	ret = 0
	if x >= 0:
		ret += zero * N
	ret += np.searchsorted(A, x // pos, side='right').sum()
	ret += (N - np.searchsorted(A, (-x - 1) // -neg, side='right')).sum()
	ret -= (A * A <= x).sum()
	return ret // 2
overEq = 10 ** 18 + 100
less = -10 ** 18 - 100
while less + 1 < overEq:
	mid = (overEq + less) // 2
	if cnt(mid) >= K:
		overEq = mid
	else:
		less = mid
print(overEq)


import numpy as np

def f(nums, a):
	return 0 if nums.size <= 1 else (np.searchsorted(nums, a // nums, side='right').sum() - np.searchsorted(nums, int(pow(a, 1 / 2)), side='right')) // 2
(N, K) = map(int, input().split())
A = np.sort(list(map(int, input().split())))
p = np.sum(A > 0)
q = np.sum(A < 0)
Z = N - p - q
AP = A[-p:] if p > 0 else np.array([])
AN = A[:q] if q > 0 else np.array([])
b = (N - Z) * Z + Z * (Z - 1) // 2
a = p * q
if K <= a:
	x = AP[-1] * AN[0] - 1
	y = AP[0] * AN[-1]
	while y - x > 1:
		tmp = (y + x) // 2
		counter = np.searchsorted(AN, tmp // AP, side='right').sum()
		if counter < K:
			x = tmp
		else:
			y = tmp
	print(y)
elif K <= a + b:
	print(0)
else:
	if q > 1:
		AN = -AN[::-1]
	x = 0
	y = 10 ** 18
	K = K - a - b
	while y - x > 1:
		tmp = (y + x) // 2
		if f(AP, tmp) + f(AN, tmp) < K:
			x = tmp
		else:
			y = tmp
	print(y)


import numpy as np
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A = np.array(A)
A_pos = np.sort(A[A > 0])
A_neg = np.sort(A[A < 0])
A_neg2 = -A_neg[::-1]
n_pos = len(A_pos)
n_neg = len(A_neg)
n_zero = N - n_pos - n_neg

def position_in_neg(x):
	y = n_pos - np.searchsorted(A_pos, x // A_neg, side='right')
	return y.sum()

def position_in_pos(x):
	z = np.searchsorted(A_pos, -(-x // A_pos), side='left')
	w = np.searchsorted(A_neg2, -(-x // A_neg2), side='left')
	tmp = len(A_pos[A_pos ** 2 < x]) + len(A_neg2[A_neg2 ** 2 < x])
	return (z.sum() + w.sum() - tmp) // 2

def position(x):
	if x < 0:
		return position_in_neg(x)
	elif x == 0:
		return n_pos * n_neg
	else:
		return position_in_pos(x) + n_pos * n_neg + (n_pos + n_neg) * n_zero + n_zero * (n_zero - 1) // 2
l = -pow(10, 18)
r = pow(10, 18)
while r - l > 1:
	mid = (l + r) // 2
	if position(mid) < K:
		l = mid
	else:
		r = mid
print(l)


import numpy as np
from numba import njit
(N, K) = [int(_) for _ in input().split()]
A = np.array(sorted([int(_) for _ in input().split()]))

@njit
def solve(N, K, A):
	lb = -10 ** 18 - 1
	rb = 10 ** 18 + 1

	def check(x):
		cnt = 0
		for (i, a) in enumerate(A):
			l = 0
			r = i
			if a > 0:
				l = -1
				r = np.searchsorted(A, x // a, side='right')
			elif a < 0:
				l = np.searchsorted(A, 0 - x // -a, side='left')
				r = N + 1
			elif x < 0:
				r = 0
			l = min(max(l, 0), i)
			r = max(min(r, i), 0)
			cnt += r - l
		return cnt >= K
	while rb - lb > 1:
		mid = (rb + lb) // 2
		if check(mid):
			rb = mid
		else:
			lb = mid
	print(rb)
solve(N, K, A)


import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop, heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10 ** 9 + 7
inf = float('inf')

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

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

def f(x):
	cnt = 0
	if x < 0:
		j = p - 1
		for i in range(m)[::-1]:
			while j >= 0 and plus[j] * minus[i] <= x:
				j -= 1
			cnt += p - j - 1
	else:
		j = 0
		for i in range(m)[::-1]:
			while j < m and minus[j] * minus[i] > x:
				j += 1
			cnt += max(0, i - j)
		j = p - 1
		for i in range(p):
			while j >= 0 and plus[j] * plus[i] > x:
				j -= 1
			cnt += max(0, j - i)
		cnt += zero * (zero - 1) // 2 + m * p + zero * (m + p)
	return cnt >= k
(n, k) = LI()
a = LI()
a.sort()
minus = [x for x in a if x < 0]
plus = [x for x in a if x > 0]
(m, p) = (len(minus), len(plus))
zero = bl(a, 1) - br(a, -1)
(ok, ng) = (10 ** 18, -10 ** 18 - 1)
while ok - ng > 1:
	mid = (ok + ng) // 2
	if f(mid):
		ok = mid
	else:
		ng = mid
print(ok)


(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
inf = max(A[0] ** 2, A[-1] ** 2)
ok1 = inf
ng1 = -inf
while abs(ok1 - ng1) > 1:
	arg = (ok1 + ng1) // 2
	ans = 0
	for i in range(N):
		if A[i] * A[i] < arg:
			ans -= 1
		ok = N
		ng = -1
		if A[i] == 0:
			if arg > 0:
				ans += N
		elif A[i] > 0:
			while abs(ok - ng) > 1:
				mid = (ok + ng) // 2
				if A[i] * A[mid] < arg:
					ng = mid
				else:
					ok = mid
			ans += ok
		else:
			while abs(ok - ng) > 1:
				mid = (ok + ng) // 2
				if A[i] * A[mid] < arg:
					ok = mid
				else:
					ng = mid
			ans += N - ok
	ans /= 2
	if K > ans:
		ng1 = arg
	else:
		ok1 = arg
print(ng1)


import sys
input = sys.stdin.readline
(N, K) = map(int, input().split())
A = sorted(map(int, input().split()))
M = []
Z = []
P = []
for a in A:
	if a < 0:
		M.append(-a)
	elif a == 0:
		Z.append(a)
	else:
		P.append(a)
M.reverse()
MINUS = len(M) * len(P)
PLUS = len(P) * (len(P) - 1) // 2 + len(M) * (len(M) - 1) // 2
ZERO = N * (N - 1) // 2 - PLUS - MINUS
if MINUS < K and K <= MINUS + ZERO:
	print(0)
	sys.exit()
if K <= MINUS:
	OK = 10 ** 18
	NG = 0
	while OK - NG > 1:
		mid = (OK + NG) // 2
		ANS = 0
		NOW = len(P) - 1
		for i in range(len(M)):
			while NOW >= 0 and mid < M[i] * P[NOW]:
				NOW -= 1
			ANS += len(P) - NOW - 1
		if ANS >= K:
			NG = mid
		else:
			OK = mid
	print(-OK)
else:
	OK = 0
	NG = 10 ** 18
	K -= MINUS + ZERO
	while NG - OK > 1:
		mid = (OK + NG) // 2
		ANS = 0
		NOW = len(P) - 1
		for i in range(len(P)):
			while NOW > 0 and mid <= P[i] * P[NOW]:
				NOW -= 1
			ANS += max(0, NOW - i)
		NOW = len(M) - 1
		for i in range(len(M)):
			while NOW > 0 and mid <= M[i] * M[NOW]:
				NOW -= 1
			ANS += max(0, NOW - i)
		if ANS >= K:
			NG = mid
		else:
			OK = mid
	print(OK)


import numpy as np
(n, k) = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
a = np.array(a)
a.sort()
plus = a[a > 0]
zero = a[a == 0]
minus = a[a < 0]
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	mid = (left + right) // 2
	cnt = 0
	if mid >= 0:
		cnt += len(zero) * n
	cnt += a.searchsorted(mid // plus, side='right').sum()
	cnt += (n - a.searchsorted(-(-mid // minus), side='left')).sum()
	cnt -= np.count_nonzero(a * a <= mid)
	cnt /= 2
	if cnt >= k:
		right = mid
	if cnt < k:
		left = mid
print(right)


import numpy as np

def partsolve(A, x, positive, zero, negative):
	count = 0
	if x >= 0:
		count = len(zero) * len(A)
	P = x // positive
	Pc = np.searchsorted(A, P, side='right')
	count += Pc.sum()
	N = (-x - 1) // -negative
	Nc = np.searchsorted(A, N, side='right')
	Nc = len(A) - Nc
	count += Nc.sum()
	count -= np.count_nonzero(A * A <= x)
	return count // 2

def solve(N, K, As):
	A = np.array(sorted(As), np.int64)
	positive = A[A > 0]
	zero = A[A == 0]
	negative = A[A < 0]
	left = -10 ** 18
	right = 10 ** 18
	while right - left > 1:
		mid = left + (right - left) // 2
		c = partsolve(A, mid, positive, zero, negative)
		if c < K:
			left = mid
		else:
			right = mid
	return right

def __starting_point():
	(N, K) = tuple(map(int, input().split(' ')))
	As = list(map(int, input().split(' ')))
	print(solve(N, K, As))
__starting_point()


import numpy as np
(n, k) = list(map(int, input().split()))
a = np.array(list(map(int, input().split())))
pos = np.sort(a[a > 0])
neg = np.sort(np.abs(a[a < 0]))
zero = (a == 0).sum()
INF = 2 * 10 ** 18
l = -INF
r = INF
while r - l > 1:
	mid = (l + r) // 2
	cnt = 0
	if mid >= 0:
		cnt = len(pos) * len(neg)
		cnt += (len(pos) + len(neg)) * zero
		cnt += zero * (zero - 1) // 2
		x = np.searchsorted(pos, mid // pos, side='right').sum()
		x += np.searchsorted(neg, mid // neg, side='right').sum()
		x -= (pos * pos <= mid).sum()
		x -= (neg * neg <= mid).sum()
		cnt += x / 2
	else:
		cnt = (len(neg) - np.searchsorted(neg, abs(mid) // pos + (mid % pos != 0), side='left')).sum()
	if cnt < k:
		l = mid
	else:
		r = mid
print(r)


import sys
input = sys.stdin.readline
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
nA = [a for a in A if a < 0]
zero = [a for a in A if a == 0]
pA = [a for a in A if a > 0]
nA.sort(reverse=True)
pA.sort()
pR = 0
neg = len(nA) * len(pA) * 2
zzz = len(zero) * (N - len(zero) + N - 1)

def f(x):
	global pR
	ret = 0
	if x < 0:
		pR = len(pA) - 1
		for na in nA:
			while pR >= 0:
				if na * pA[pR] > x:
					break
				pR -= 1
			ret += len(pA) - pR - 1
	elif x == 0:
		ret += neg
		ret += zzz
		ret //= 2
	else:
		ret += neg
		ret += zzz
		pR = len(nA) - 1
		for na in nA:
			while pR >= 0:
				if na * nA[pR] <= x:
					break
				pR -= 1
			ret += pR + 1
			ret -= 1 if na * na <= x else 0
		pR = len(pA) - 1
		for pa in pA:
			while pR >= 0:
				if pa * pA[pR] <= x:
					break
				pR -= 1
			ret += pR + 1
			ret -= 1 if pa * pa <= x else 0
		ret //= 2
	return ret
l = -10 ** 18 - 1
r = 10 ** 18
while r - l > 1:
	m = (r + l) // 2
	if f(m) < K:
		l = m
	else:
		r = m
print(r)


import numpy as np

def main():
	(n, k) = list(map(int, input().split()))
	a = list(map(int, input().split()))
	a.sort()
	(cnt_neg, cnt_zro, cnt_pos) = (0, 0, 0)
	(neg_a, zro_a, pos_a) = ([], [], [])
	n_ap = neg_a.append
	z_ap = zro_a.append
	p_ap = pos_a.append
	for v in a:
		if v < 0:
			cnt_neg += 1
			n_ap(v)
		elif v == 0:
			cnt_zro += 1
			z_ap(v)
		else:
			cnt_pos += 1
			p_ap(v)
	num_neg_pair = cnt_neg * cnt_pos
	num_pos_pair = cnt_neg * (cnt_neg - 1) // 2 + cnt_pos * (cnt_pos - 1) // 2
	num_zro_pair = n * (n - 1) // 2 - num_neg_pair - num_pos_pair
	if k <= num_neg_pair:
		neg_a = np.array(neg_a)
		pos_a = np.array(pos_a)
		l = -1 * 10 ** 18
		r = 0
		while l + 1 < r:
			p = (l + r) // 2
			cnt = np.searchsorted(pos_a, p // neg_a, side='riget').sum()
			result = n * cnt_neg - (cnt + (cnt_neg + cnt_zro) * cnt_neg)
			if result < k:
				l = p
			else:
				r = p
		print(l)
	elif k <= num_neg_pair + num_zro_pair:
		print('0')
	else:
		k -= num_neg_pair + num_zro_pair
		for i in range(len(neg_a)):
			neg_a[i] = -neg_a[i]
		neg_a = np.array(neg_a)
		neg_a = np.sort(neg_a)
		pos_a = np.array(pos_a)
		l = 1
		r = 10 ** 18 + 1
		while l + 1 < r:
			p = (l + r) // 2
			cnt_1 = np.searchsorted(neg_a, (p + neg_a - 1) // neg_a, side='left').sum()
			cnt_2 = np.searchsorted(pos_a, (p + pos_a - 1) // pos_a, side='left').sum()
			cnt_1 -= np.count_nonzero(neg_a < (p + neg_a - 1) // neg_a)
			cnt_2 -= np.count_nonzero(pos_a < (p + pos_a - 1) // pos_a)
			result = (cnt_1 + cnt_2) // 2
			if result < k:
				l = p
			else:
				r = p
		print(l)

def __starting_point():
	main()
__starting_point()


import sys
input = sys.stdin.readline

def main():
	(N, K) = map(int, input().split())
	A = sorted(list(map(int, input().split())))
	AM = []
	AP = []
	for a in A:
		if a > 0:
			AP.append(a)
		elif a < 0:
			AM.append(a)
	INF = 10 ** 18 + 1
	l = -INF
	r = INF
	while l + 1 < r:
		c = (l + r) // 2
		x = 0
		if c > 0:
			i = len(AP) - 1
			for j in range(len(AP)):
				if j >= i:
					break
				while j < i and AP[i] * AP[j] >= c:
					i -= 1
				x += i - j
			i = 0
			for j in range(len(AM) - 1, -1, -1):
				if j <= i:
					break
				while i < j and AM[i] * AM[j] >= c:
					i += 1
				x += j - i
			x += len(AP) * len(AM)
			x += (len(AP) + len(AM)) * (N - len(AP) - len(AM))
			if N - len(AP) - len(AM) > 1:
				x += (N - len(AP) - len(AM)) * (N - len(AP) - len(AM) - 1) // 2
		elif c == 0:
			x += len(AP) * len(AM)
		else:
			i = 0
			for j in range(len(AM)):
				while i < len(AP) and AP[i] * AM[j] >= c:
					i += 1
				x += len(AP) - i
		if x < K:
			l = c
		else:
			r = c
	print(l)
main()


import numpy as np
(n, k) = list(map(int, input().split()))
a = np.array(list(map(int, input().split())))
a.sort()
p = a[a > 0]
z = np.count_nonzero(a == 0)
m = a[a < 0]
r = 10 ** 19
l = -r
while r - l > 1:
	b = (l + r) // 2
	c = 0
	if b >= 0:
		c += z * n
	c += a.searchsorted(b // p, side='right').sum()
	c += n * len(m) - a.searchsorted(-(-b // m), side='left').sum()
	c -= np.count_nonzero(a * a <= b)
	if c // 2 >= k:
		r = b
	else:
		l = b
print(r)


import numpy as np

def resolve():
	(n, k) = map(int, input().split())
	a = np.array(input().split(), dtype=np.int64)
	a.sort()
	zero = np.count_nonzero(a == 0)
	positive = a[a > 0]
	negative = a[a < 0]

	def count(x):
		ans = 0
		if x >= 0:
			ans += n * zero
		ans += np.searchsorted(a, x // positive, side='right').sum()
		ans += n * len(negative) - np.searchsorted(a, -(-x // negative), side='left').sum()
		ans -= np.count_nonzero(a * a <= x)
		return ans // 2
	ok = 10 ** 18
	ng = -ok - 1
	while ok - ng > 1:
		cen = (ok + ng) // 2
		if count(cen) >= k:
			ok = cen
		else:
			ng = cen
	print(ok)

def __starting_point():
	resolve()
__starting_point()


import sys
input = sys.stdin.readline
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
(ap, an) = ([], [])
zeronum = 0
for i in range(n):
	if a[i] > 0:
		ap.append(a[i])
	elif a[i] < 0:
		an.append(-a[i])
	else:
		zeronum += 1
(np, nn) = (len(ap), len(an))

def fminus(x):
	j = 0
	cnt = 0
	for i in range(np):
		cnt += j
		while j < nn and an[j] * ap[i] >= x:
			j += 1
			cnt += 1
	return cnt

def fplus(x, length, lis):
	r = length - 1
	cnt = 0
	for l in range(length):
		while lis[r] * lis[l] > x:
			if r == l:
				break
			r -= 1
		if r == l:
			break
		elif lis[r] * lis[l] <= x:
			cnt += r - l
	return cnt
if np * nn < k <= np * nn + zeronum * (zeronum - 1) // 2 + zeronum * (np + nn):
	print(0)
elif k <= np * nn:
	an.sort(reverse=True)
	ap.sort()
	ng = 10 ** 18
	ok = 0
	while ng - ok > 1:
		mid = (ok + ng) // 2
		if fminus(mid) >= k:
			ok = mid
		else:
			ng = mid
	print(-ok)
else:
	an.sort()
	ap.sort()
	k -= np * nn + zeronum * (zeronum - 1) // 2 + zeronum * (np + nn)
	ok = 10 ** 18
	ng = 0
	while ok - ng > 1:
		mid = (ok + ng) // 2
		if fplus(mid, nn, an) + fplus(mid, np, ap) >= k:
			ok = mid
		else:
			ng = mid
	print(ok)


import numpy as np
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
a = np.array(a)
a.sort()
plus = a[a > 0]
zero = np.count_nonzero(a == 0)
minus = a[a < 0]
low = -10 ** 20
hi = 10 ** 20
while hi - low > 1:
	item = 0
	ave = (hi + low) // 2
	if ave >= 0:
		item += zero * n
	item += a.searchsorted(ave // plus, side='right').sum()
	item += n * len(minus) - a.searchsorted(-(-ave // minus), side='left').sum()
	item -= np.count_nonzero(a * a <= ave)
	if item // 2 >= k:
		hi = ave
	else:
		low = ave
print(hi)


(N, K) = map(int, input().split())
A = list(map(int, input().split()))
(mA, nA) = ([], [])
for a in A:
	if a < 0:
		mA.append(a)
	else:
		nA.append(a)
mA = sorted(mA)[::-1]
nA = sorted(nA)
lnA = len(nA)
lmA = len(mA)

def F(k):
	r = 0
	(i, j) = (0, lnA - 1)
	while i < lnA:
		while j >= 0 and nA[j] * nA[i] > k:
			j -= 1
		r += j + 1
		i += 1
	(i, j) = (0, lmA - 1)
	while i < lmA:
		while j >= 0 and mA[j] * mA[i] > k:
			j -= 1
		r += j + 1
		i += 1
	(i, j) = (lmA - 1, 0)
	while i >= 0:
		while j < lnA and nA[j] * mA[i] > idx:
			j += 1
		r += 2 * (lnA - j)
		i -= 1
	for a in A:
		if a * a <= k:
			r -= 1
	return r // 2
(mx, mn) = (2 * 10 ** 18, -2 * 10 ** 18)
idx = (mx + mn) // 2
target = K
while mx - mn > 1:
	if F(idx) < target:
		mn = idx
	else:
		mx = idx
	idx = (mx + mn) // 2
print(idx + 1)


import numpy as np
(N, K) = list(map(int, input().split()))
A = np.sort(np.array(input().split(), np.int64))
z = A[A == 0]
p = A[A > 0]
n = A[A < 0]

def f(x):
	cnt = 0
	if x >= 0:
		cnt += len(z) * N
	cnt += np.searchsorted(A, x // p, side='right').sum()
	cnt += (N - np.searchsorted(A, (-x - 1) // -n, side='right')).sum()
	cnt -= np.count_nonzero(A * A <= x)
	assert cnt % 2 == 0
	return cnt // 2
l = -10 ** 18
r = 10 ** 18
while l + 1 < r:
	x = (l + r) // 2
	if f(x) >= K:
		r = x
	else:
		l = x
print(r)


from bisect import *

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

def get_count1(k, A):
	(l, r) = (0, len(A) - 1)
	res = 0
	while l < r:
		if A[l] * A[r] > k:
			r -= 1
			continue
		res += r - l
		l += 1
	return res

def get_count2(k, B, C):
	(l, r) = (0, len(C) - 1)
	res = 0
	while True:
		if l > len(B) - 1 or r < 0:
			break
		if B[l] * C[r] < -k:
			l += 1
			continue
		res += len(B) - l
		r -= 1
	return res

def test1(k):
	return get_count1(k, B) + get_count1(k, C) + count_negative < K

def test2(k):
	return get_count2(k, B, C) < K
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
at_zero = bisect_left(A, 0)
B = A[:at_zero]
B = list(map(lambda x: -x, B))
B = list(reversed(B))
C = A[at_zero:]
count_positive = len(B) * (len(B) - 1) // 2 + len(C) * (len(C) - 1) // 2
count_negative = N * (N - 1) // 2 - count_positive
if K > count_negative:
	print(binary_search_int(-1, 10 ** 18 + 1, test1))
else:
	print(binary_search_int(-10 ** 18, 1, test2))


import numpy as np
(n, k) = list(map(int, input().split()))
a = np.array(list(map(int, input().split())))
a.sort()
p = a[a > 0]
zeros = np.count_nonzero(a == 0)
m = a[a < 0]

def count(x):
	cnt = 0
	if x >= 0:
		cnt += zeros * n
	cnt += a.searchsorted(x // p, side='right').sum()
	cnt += n * len(m) - a.searchsorted(-(-x // m), side='left').sum()
	cnt -= np.count_nonzero(a * a <= x)
	return cnt // 2
(l, r) = (-10 ** 19, 10 ** 19)
while r - l > 1:
	mid = (r + l) // 2
	if count(mid) >= k:
		r = mid
	else:
		l = mid
print(r)


from bisect import bisect_left, bisect_right
(n, k) = map(int, input().split())
a = sorted(list(map(int, input().split())))
pos_start = bisect_right(a, 0)
neg_end = bisect_left(a, 0)
pos_cnt = n - pos_start
neg_cnt = neg_end
pairs_cnt = n * (n - 1) // 2
pos_pairs_cnt = pos_cnt * (pos_cnt - 1) // 2 + neg_cnt * (neg_cnt - 1) // 2
neg_pairs_cnt = pos_cnt * neg_cnt
if k <= neg_pairs_cnt:
	high = 0
	low = -10 ** 18
	while abs(high - low) > 1:
		mid = (high + low) // 2
		cnt = 0
		r = pos_start
		for l in range(neg_end):
			while r < n and mid < a[r] * a[l]:
				r += 1
			cnt += pos_cnt - (r - pos_start)
		if cnt >= k:
			high = mid
		else:
			low = mid
	print(high)
elif pairs_cnt - pos_pairs_cnt < k:
	k -= pairs_cnt - pos_pairs_cnt
	high = 10 ** 18
	low = 0
	while abs(high - low) > 1:
		mid = (high + low) // 2
		cnt = 0
		r = n - 1
		for l in range(pos_start, n):
			while l < r and mid < a[r] * a[l]:
				r -= 1
			cnt += max(0, r - l)
		l = 0
		for r in range(neg_end - 1, -1, -1):
			while l < r and mid < a[r] * a[l]:
				l += 1
			cnt += max(0, r - l)
		if cnt >= k:
			high = mid
		else:
			low = mid
	print(high)
else:
	print(0)


(N, K) = map(int, input().split())
plus = []
minus = []
zero = 0
for i in map(int, input().split()):
	if i > 0:
		plus.append(i)
	elif i < 0:
		minus.append(i)
	else:
		zero += 1
plus.sort()
minus.sort(reverse=True)

def solve(mid):
	global N, K, zero
	cnt = 0
	if mid >= 0:
		cnt += len(plus) * len(minus)
		if mid > 0:
			cnt += zero * (zero - 1) // 2 + zero * (N - zero)
			for L in (plus, minus):
				(l, r) = (0, len(L) - 1)
				while l < r:
					while l < r and L[l] * L[r] >= mid:
						r -= 1
					cnt += r - l
					l += 1
	else:
		r = len(minus) - 1
		for l in range(len(plus)):
			while r >= 0 and plus[l] * minus[r] < mid:
				r -= 1
			cnt += len(minus) - (r + 1)
	return cnt < K
(ok, ng) = (-10 ** 19, 10 ** 19)
while abs(ok - ng) > 1:
	mid = (ok + ng) // 2
	if solve(mid):
		ok = mid
	else:
		ng = mid
print(ok)


(N, K) = list(map(int, input().split()))
A = list(map(int, input().split()))
A = sorted(A)
import numpy as np
A = np.array(A, dtype='int64')
Z = A[A == 0]
H = A[A < 0]
S = A[A > 0]
(l, r) = (-10 ** 19, 10 ** 19)
while r - l > 1:
	mid = (r + l) // 2
	cnt = 0
	cnt += A.searchsorted(mid // S, side='right').sum()
	cnt += (N - A.searchsorted((mid + 1) // H, side='right')).sum()
	cnt -= np.count_nonzero(A * A <= mid)
	if mid >= 0:
		cnt += len(Z) * N
	cnt //= 2
	if cnt >= K:
		r = mid
	else:
		l = mid
print(r)


import sys
readline = sys.stdin.readline
import numpy as np
(N, K) = list(map(int, readline().split()))
A = np.array(readline().split(), dtype=int)
nega_list = A[A < 0]
posi_list = A[A > 0]
zero_num = A[A == 0].size
nega_list = np.sort(nega_list)
posi_list = np.sort(posi_list)
nega_cnt = nega_list.size * posi_list.size
posi_cnt = (posi_list.size * posi_list.size - 1) // 2 + (nega_list.size * nega_list.size - 1) // 2
zero_cnt = zero_num * (zero_num - 1) // 2 + zero_num * (nega_list.size + posi_list.size)
if K <= nega_cnt:

	def isOkNega(x):
		return np.searchsorted(nega_list, x // posi_list, side='right').sum() >= K
	ok = 0
	ng = -10 ** 18 - 1
	while ok - ng > 1:
		mid = (ok + ng) // 2
		if isOkNega(mid):
			ok = mid
		else:
			ng = mid
	print(ok)
elif K <= nega_cnt + zero_cnt:
	print(0)
else:
	K -= nega_cnt + zero_cnt
	nega_list = np.flipud(nega_list * -1)
	self_nega = nega_list * nega_list
	self_posi = posi_list * posi_list

	def isOkPosi(x):
		nega_all = np.searchsorted(nega_list, x // nega_list, side='right')
		nega_cnt = nega_all.sum() - self_nega[self_nega <= x].size
		nega_cnt //= 2
		posi_all = np.searchsorted(posi_list, x // posi_list, side='right')
		posi_cnt = posi_all.sum() - self_posi[self_posi <= x].size
		posi_cnt //= 2
		return nega_cnt + posi_cnt >= K
	ok = 10 ** 18 + 1
	ng = 0
	while abs(ok - ng) > 1:
		mid = abs(ok + ng) // 2
		if isOkPosi(mid):
			ok = mid
		else:
			ng = mid
	print(ok)


from math import floor, ceil, sqrt, factorial, log
from collections import Counter, deque
from functools import reduce
import numpy as np

def S():
	return input()

def I():
	return int(input())

def MS():
	return map(str, input().split())

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

def LS():
	return list(MS())

def LI():
	return list(MI())

def LLS():
	return [list(map(str, l.split())) for l in input()]

def LLI():
	return [list(map(int, l.split())) for l in input()]

def LLSN(n: int):
	return [LS() for _ in range(n)]

def LLIN(n: int):
	return [LI() for _ in range(n)]
(n, k) = MI()
a = np.array(sorted([int(i) for i in input().split()]))
pos = a[a > 0]
zero = a[a == 0]
neg = a[a < 0]
l = -10 ** 18 - 1
r = 10 ** 18 + 1
while r - l > 1:
	mid = (r + l) // 2
	cnt = 0
	if mid >= 0:
		cnt += len(zero) * n
	cnt += a.searchsorted(mid // pos, side='right').sum()
	cnt += (n - a.searchsorted(-(-mid // neg), side='left')).sum()
	cnt -= np.count_nonzero(a * a <= mid)
	cnt //= 2
	if cnt >= k:
		r = mid
	else:
		l = mid
print(r)


(N, K) = map(int, input().split())
A = sorted(map(int, input().split()))
x = 0
r = 10 ** 18 + 1
l = -10 ** 18
while l + 1 < r:
	x = (l + r) // 2
	k = 0
	for a in A:
		if a < 0:
			(ll, rr) = (-1, N)
			while ll + 1 < rr:
				c = (rr + ll) // 2
				if x > a * A[c]:
					rr = c
				else:
					ll = c
			k += N - rr
		else:
			(ll, rr) = (-1, N)
			while ll + 1 < rr:
				c = (rr + ll) // 2
				if x > a * A[c]:
					ll = c
				else:
					rr = c
			k += rr
		if x > a ** 2:
			k -= 1
	k //= 2
	if k < K:
		l = x
	else:
		r = x
print(l)


from bisect import bisect_left, bisect_right
(N, K) = map(int, input().split())
As = sorted(map(int, input().split()))
l = -(10 ** 18 + 10)
r = 10 ** 18 + 10
while True:
	mid = (l + r) // 2
	count = 0
	for (i, A) in enumerate(As):
		if A > 0:
			count += bisect_right(As, mid // A, lo=i + 1) - (i + 1)
		elif A < 0:
			count += N - bisect_left(As, -(-mid // A), lo=i + 1)
		elif mid >= 0:
			count += N - i - 1
	if count < K:
		l = mid
	else:
		r = mid
	if r - l == 1:
		break
print(r)


def count1(T, A, B):
	if T <= 0 or len(A) == 0 or len(B) == 0:
		return 0
	(count, it) = (0, -1)
	for i in range(len(A) - 1, -1, -1):
		while it + 1 < len(B) and A[i] * B[it + 1] < T:
			it += 1
		count += len(B) - it - 1
	return count

def count2(T, A):
	count_all = len(A) * (len(A) - 1) // 2
	count = count1(T + 1, A, A)
	for e in A:
		if e * e >= T + 1:
			count -= 1
	count /= 2
	return count_all - count
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
(X, Y, Z) = ([], [], 0)
for e in A:
	if e < 0:
		X.append(-e)
	elif e > 0:
		Y.append(e)
	else:
		Z += 1
X.sort()
Y.sort()

def check(T):
	count = 0
	if T < 0:
		count += count1(abs(T), X, Y)
	else:
		count += len(X) * len(Y)
		count += Z * (Z - 1) // 2 + Z * (N - Z)
		count += count2(T, X) + count2(T, Y)
	return count < K
(ok, ng) = (-10 ** 18, 10 ** 18)
while ng - ok > 1:
	mid = (ok + ng) // 2
	if check(mid):
		ok = mid
	else:
		ng = mid
print(ok + 1)


import numpy as np
from bisect import bisect
DEBUG = False

def bisect_f(f, lo, hi):
	if DEBUG:
		assert f(lo) and (not f(hi))
	while hi - lo > 1:
		mid = (lo + hi) // 2
		if f(mid):
			lo = mid
		else:
			hi = mid
		if DEBUG:
			assert f(lo) and (not f(hi))
	if DEBUG:
		assert hi - lo == 1
		assert f(lo) and (not f(hi))
	return lo
(N, K) = list(map(int, input().split()))
A = list(map(int, input().split()))
A.sort()
neg = []
zero = []
pos = []
for x in A:
	if x < 0:
		neg.append(x)
	elif x == 0:
		zero.append(x)
	else:
		assert x > 0
		pos.append(x)
revAbsNeg = [-x for x in reversed(neg)]
posSq = [x ** 2 for x in pos]
negSq = [x ** 2 for x in revAbsNeg]
pos = np.array(pos, dtype=np.int64)
revAbsNeg = np.array(revAbsNeg, dtype=np.int64)

def countDistinctPairsLessThan(arr, prod):
	N = arr.shape[0]
	assert arr.shape == (N,)
	count3 = np.sum(np.minimum(np.arange(N), np.searchsorted(arr, (prod - 1) // arr, side='right')))
	if DEBUG:
		count = 0
		for (i, x) in enumerate(arr):
			count += bisect(arr, (prod - 1) // x, 0, i)
		count2 = 0
		for i in range(len(arr)):
			for j in range(i + 1, len(arr)):
				if arr[i] * arr[j] < prod:
					count2 += 1
		print((count, count2, count3))
		assert count == count2 == count3
	return count3

def countPairsLessThanOrEqual(arr1, arr2, prod):
	if len(arr1) > len(arr2):
		(arr1, arr2) = (arr2, arr1)
	count3 = np.sum(np.searchsorted(arr2, prod // arr1, side='right'))
	if DEBUG:
		count = 0
		for x in arr1:
			count += bisect(arr2, prod // x)
		count2 = 0
		for x in arr1:
			for y in arr2:
				if x * y <= prod:
					count2 += 1
		assert count == count2 == count3
	return count3

def getIndex(prod):
	count = 0
	if prod < 0:
		count += len(pos) * len(neg)
		count -= countPairsLessThanOrEqual(pos, revAbsNeg, -prod)
	elif prod >= 0:
		count += len(pos) * len(neg)
		if prod > 0:
			count += len(zero) * len(neg)
			count += len(zero) * (len(zero) - 1) // 2
			count += len(zero) * len(pos)
			count += countDistinctPairsLessThan(pos, prod)
			count += countDistinctPairsLessThan(revAbsNeg, prod)
	if DEBUG:
		count2 = 0
		for i in range(N):
			for j in range(i + 1, N):
				if A[i] * A[j] < prod:
					count2 += 1
		assert count == count2
	return count

def solve(K):
	lo = -10 ** 18
	hi = 10 ** 18 + 1
	if DEBUG:
		assert getIndex(lo) <= K < getIndex(hi)
	prod = bisect_f(lambda prod: getIndex(prod) <= K, lo, hi)
	if DEBUG:
		assert getIndex(prod) <= K < getIndex(prod + 1)
	return prod
if DEBUG:
	for k in range(N * (N - 1) // 2):
		print(('k', k, solve(k)))
print(solve(K - 1))


import sys
sysread = sys.stdin.readline
read = sys.stdin.read
sys.setrecursionlimit(10 ** 7)
import numpy as np

def run():
	(N, K, *A) = list(map(int, read().split()))
	B = [a for a in A if a > 0]
	C = [a for a in A if a < 0]
	C_abs = [-c for c in C]
	O = A.count(0)
	B = np.array(sorted(B), dtype=np.int64)
	C = np.array(sorted(C), dtype=np.int64)
	C_abs = np.array(sorted(C_abs), dtype=np.int64)
	n_neg = len(B) * len(C)
	n_0 = O * (O - 1) // 2 + O * (len(B) + len(C))

	def find(x):
		ret = 0
		if x < 0:
			ret += np.searchsorted(C, x // B, side='right').sum()
		elif x == 0:
			ret += n_0 + n_neg
		else:
			ret += n_neg + n_0
			b_count = (B ** 2 <= x).sum()
			c_count = (C ** 2 <= x).sum()
			ret += (np.searchsorted(B, x // B, side='right').sum() - b_count) // 2
			ret += (np.searchsorted(C_abs, x // C_abs, side='right').sum() - c_count) // 2
		return ret
	high = 10 ** 18
	low = -high
	current = 0
	while high - low > 1:
		tmp = find(current)
		if tmp < K:
			low = current
		else:
			high = current
		current = (low + high) // 2
	print(high)

def __starting_point():
	run()
__starting_point()


from bisect import bisect_left, bisect_right

def cntneg(X):
	(cnt, r) = (0, posst)
	for l in range(negend):
		while r < N and A[l] * A[r] > X:
			r += 1
		cnt += poscnt - (r - posst)
	return cnt

def cntpos(X):
	(cnt, r) = (0, N - 1)
	for l in range(posst, N):
		while l < r and A[l] * A[r] > X:
			r -= 1
		cnt += max(0, r - l)
	l = 0
	for r in range(negend - 1, -1, -1):
		while l < r and A[l] * A[r] > X:
			l += 1
		cnt += max(0, r - l)
	return cnt
(N, K) = map(int, input().split())
A = sorted(map(int, input().split()))
negend = bisect_left(A, 0)
posst = bisect_right(A, 0)
poscnt = N - posst
negcnt = negend
zerocnt = N - poscnt - negcnt
zeroans = zerocnt * (poscnt + negcnt) + zerocnt * (zerocnt - 1) // 2
posans = poscnt * (poscnt - 1) // 2 + negcnt * (negcnt - 1) // 2
negans = negcnt * poscnt
if K <= negans:
	(ng, ok) = (-10 ** 18, 0)
	while abs(ok - ng) > 1:
		X = (ng + ok) // 2
		if cntneg(X) >= K:
			ok = X
		else:
			ng = X
elif K <= negans + zeroans:
	print(0)
	exit()
else:
	K -= negans + zeroans
	(ng, ok) = (0, 10 ** 18)
	while abs(ok - ng) > 1:
		X = (ng + ok) // 2
		if cntpos(X) >= K:
			ok = X
		else:
			ng = X
print(ok)


import sys
input = sys.stdin.readline
import numpy as np
(n, k) = list(map(int, input().split()))
A = np.array(input().split(), np.int64)
A = np.sort(A)
P = A[A > 0]
Z = A[A == 0]
N = A[A < 0]

def ok(x):
	cnt = 0
	cnt += np.searchsorted(A, x // P, side='right').sum()
	cnt += (n - np.searchsorted(A, (-x - 1) // -N, side='right')).sum()
	if x >= 0:
		cnt += len(Z) * n
	cnt -= np.count_nonzero(A * A <= x)
	cnt = cnt // 2
	if cnt >= k:
		return True
	else:
		return False
l = -10 ** 18 - 1
r = 10 ** 18 + 1
while l + 1 < r:
	c = (l + r) // 2
	if ok(c):
		r = c
	else:
		l = c
print(r)


(n, k) = map(int, input().split())
a = list(map(int, input().split()))
minus = [-x for x in a if x < 0]
plus = [x for x in a if x >= 0]
minus.sort()
plus.sort()

def solve(x):
	ans = 0
	if x < 0:
		x = -x
		r = 0
		for mi in minus[::-1]:
			while r < len(plus) and plus[r] * mi < x:
				r += 1
			ans += len(plus) - r
		return ans
	r = 0
	for l in minus[::-1]:
		if l * l <= x:
			ans -= 1
		while r < len(minus) and minus[r] * l <= x:
			r += 1
		ans += r
	r = 0
	for l in plus[::-1]:
		if l * l <= x:
			ans -= 1
		while r < len(plus) and plus[r] * l <= x:
			r += 1
		ans += r
	ans //= 2
	ans += len(minus) * len(plus)
	return ans
low = -10 ** 18 - 1
high = 10 ** 18 + 1
while high - low > 1:
	mid = (high + low) // 2
	if solve(mid) < k:
		low = mid
	else:
		high = mid
print(high)


import numpy as np
(n, k) = map(int, input().split())
a = np.array(list(map(int, input().split())))
a.sort()
pos = a[a > 0]
zero = a[a == 0]
neg = a[a < 0]
negpos = (neg * -1)[::-1]
lenn = len(neg)
lenz = len(zero)
lenp = len(pos)
nnres = lenn * lenp
nzres = int(lenz * (lenn + lenp) + lenz * (lenz - 1) / 2)
npres = int(lenn * (lenn - 1) / 2 + lenp * (lenp - 1) / 2)
if k <= nnres:

	def count_nnres(x):
		cnt = np.searchsorted(neg, x // pos, side='right').sum()
		return int(cnt)
	left = -10 ** 18
	right = -1
	while left + 1 < right:
		mid = (left + right) // 2
		nebefore = count_nnres(mid)
		if nebefore >= k:
			right = mid
		elif nebefore < k:
			left = mid
	print(right)
elif nnres < k <= nnres + nzres:
	print(0)
elif nnres + nzres < k:

	def count_npres(x):
		cnt = 0
		cnt += int(np.searchsorted(pos, x // pos, side='right').sum() - (x // pos >= pos).sum()) // 2
		cnt += int(np.searchsorted(negpos, x // negpos, side='right').sum() - (x // negpos >= negpos).sum()) // 2
		return cnt
	k -= nnres + nzres
	left = 1
	right = 10 ** 18
	while left + 1 < right:
		mid = (left + right) // 2
		nebefore = count_npres(mid)
		if nebefore >= k:
			right = mid
		elif nebefore < k:
			left = mid
	print(right)


import numpy as np

def solve(*args: str) -> str:
	(n, k) = list(map(int, args[0].split()))
	A = np.array(sorted(map(int, args[1].split())))
	N = A[A < 0]
	P = A[0 < A]
	count = 0
	(left, right) = (-10 ** 18, 10 ** 18)
	while left + 1 < right:
		x = (left + right) // 2
		count = 0
		if k <= len(N) * len(P):
			count += (len(P) - np.searchsorted(P, -(-x // N), side='left')).sum()
		elif (n * (n - 1) - len(N) * (len(N) - 1) - len(P) * (len(P) - 1)) // 2 < k:
			for D in (-N[::-1], P):
				count += np.searchsorted(D, x // D, side='right').sum()
				count -= len(D[D * D <= x])
			count //= 2
			count += (n * (n - 1) - len(N) * (len(N) - 1) - len(P) * (len(P) - 1)) // 2
		else:
			right = 0
			break
		if count < k:
			left = x
		else:
			right = x
	return str(right)

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


(n, k) = map(int, input().split())
a = list(map(int, input().split()))
posi = []
nega = []
zero = []
for i in range(n):
	if a[i] < 0:
		nega.append(a[i] * -1)
	elif a[i] > 0:
		posi.append(a[i])
	else:
		zero.append(a[i])
zero = len(zero)
posi.sort()
nega.sort()
(lp, ln) = (len(posi), len(nega))
if k <= lp * ln:
	(l, r) = (0, 10 ** 18)
	while r - l > 1:
		m = (l + r) // 2
		cnt = lp * ln
		cur = 0
		for i in range(ln)[::-1]:
			while cur < lp and posi[cur] < (m + nega[i] - 1) // nega[i]:
				cur += 1
			cnt -= cur
		if cnt >= k:
			l = m
		else:
			r = m
	print(-1 * l)
elif k <= n * (n - 1) // 2 - lp * (lp - 1) // 2 - ln * (ln - 1) // 2:
	print(0)
else:
	k -= n * (n - 1) // 2 - lp * (lp - 1) // 2 - ln * (ln - 1) // 2
	(l, r) = (0, 10 ** 18)
	while r - l > 1:
		m = (l + r) // 2
		cnt = 0
		cur = ln - 1
		for i in range(ln):
			while cur and nega[cur] > m // nega[i]:
				cur -= 1
			if cur > i:
				cnt += cur - i
		cur2 = lp - 1
		for i in range(lp):
			while cur2 and posi[cur2] > m // posi[i]:
				cur2 -= 1
			if cur2 > i:
				cnt += cur2 - i
		if cnt >= k:
			r = m
		else:
			l = m
	print(r)


import sys

def f1(m):
	j = 0
	num = 0
	for x in ap[::-1]:
		while j < minus and x * am[j] < m:
			j += 1
		num += j
	return plus * minus - num

def f2(m):
	return f3(m, ap) + f3(m, am)

def f3(m, l):
	nagasa = len(l)
	if nagasa < 2:
		return 0
	j = nagasa - 1
	num = 0
	for i in range(nagasa):
		while j > -1 and l[i] * l[j] > m:
			j -= 1
		num += j + 1
		if i <= j:
			num -= 1
	return num // 2
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
ap = sorted([a[i] for i in range(n) if a[i] > 0])
am = sorted([-a[i] for i in range(n) if a[i] < 0])
az = sorted([a[i] for i in range(n) if a[i] == 0])
(plus, minus, zero) = (len(ap), len(am), len(az))
pz = plus * minus + zero * (zero - 1) // 2 + zero * (n - zero)
if plus * minus >= k:
	(h, l) = (0, 10 ** 18)
	while l - h > 1:
		md = (h + l) // 2
		p = f1(md)
		if p >= k:
			h = md
		else:
			l = md
	print(-h)
elif pz >= k:
	print(0)
else:
	k -= pz
	(h, l) = (10 ** 20, 0)
	while h - l > 1:
		md = (h + l) // 2
		p = f2(md)
		if p >= k:
			h = md
		else:
			l = md
	print(h)


import sys
input = sys.stdin.readline
from bisect import bisect
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
pos = N - bisect(A, 0)
zero = A.count(0)
neg = N - pos - zero

def is_ok(m):
	if m < 0:
		k = 0
		l = 1
		for i in range(neg):
			a = A[i]
			while a * A[l] > m:
				l += 1
				if l == N:
					break
			k += N - l
			if k >= K:
				return True
			if l == N:
				break
		return False
	else:
		k = diag = 0
		r = neg - 1
		for i in range(neg):
			a = A[i]
			while a * A[r] <= m:
				r -= 1
				if r == -1:
					break
			k += r + 1
			if r >= i:
				diag += 1
			if r == -1:
				break
		nz = neg + zero
		l = nz
		for i in range(N - 1, nz - 1, -1):
			a = A[i]
			while a * A[l] <= m:
				l += 1
				if l == N:
					break
			k += N - l
			if l <= i:
				diag += 1
			if l == N:
				break
		tmp = N * (N - 1) // 2 - (k - diag) // 2
		return tmp >= K
ng = -10 ** 18 - 1
ok = 10 ** 18 + 1
while ok - ng > 1:
	m = (ok + ng) // 2
	if is_ok(m):
		ok = m
	else:
		ng = m
print(ok)


import sys
import itertools
import time
import math
import heapq
from collections import defaultdict
sys.setrecursionlimit(10 ** 7)
INF = 10 ** 18
MOD = 10 ** 9 + 7
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
(N, K) = map(int, input().split())
A = list(sorted(map(int, input().split())))
left = -INF
right = INF
while right - left > 1:
	x = (left + right) // 2
	s = 0
	t = 0
	for a in A:
		if a > 0:
			l = -1
			r = N
			while r - l > 1:
				m = (l + r) // 2
				if A[m] * a <= x:
					l = m
				else:
					r = m
			s += r
		elif a < 0:
			l = -1
			r = N
			while r - l > 1:
				m = (l + r) // 2
				if A[m] * a <= x:
					r = m
				else:
					l = m
			s += N - r
		elif a == 0 and x >= 0:
			s += N
		if a * a <= x:
			t += 1
	count = (s - t) // 2
	if count >= K:
		right = x
	else:
		left = x
print(right)


import numpy as np
(N, K) = map(int, input().split())
A = np.array(sorted(list(map(int, input().split()))), np.int64)
n_zero = len(A[A == 0])
A_posi = A[A > 0]
A_nega = A[A < 0]

def n_pairs_less_than_or_equal_to_border(product_border):
	n_pairs = -np.sum(A * A <= product_border)
	n_pairs += n_zero * N * (product_border >= 0)
	n_pairs += np.searchsorted(A, product_border // A_posi, side='right').sum()
	n_pairs += (N - np.searchsorted(A, -(-product_border // A_nega), side='left')).sum()
	n_pairs //= 2
	return n_pairs
lower = -10 ** 18
upper = 10 ** 18
while lower <= upper:
	x = (lower + upper) // 2
	if n_pairs_less_than_or_equal_to_border(x) >= K:
		ans = x
		upper = x - 1
	else:
		lower = x + 1
print(ans)


import numpy as np

def count_pair(x):
	cnt = 0
	cnt += (n - np.searchsorted(A, x // A_nega, side='right')).sum()
	if x > 0:
		cnt += len(A_zero) * n
	cnt += np.searchsorted(A, -(-x // A_posi), side='left').sum()
	cnt = (cnt - (A ** 2 < x).sum()) // 2
	return cnt
(n, k) = list(map(int, input().split()))
(*A,) = list(map(int, input().split()))
A = np.array(A)
A = np.sort(A)
A_posi = A[A > 0]
A_zero = A[A == 0]
A_nega = A[A < 0]
inf = 10 ** 18 + 1
(l, r) = (-inf, inf)
while r - l > 1:
	c = (l + r) // 2
	if count_pair(c) < k:
		l = c
	else:
		r = c
print(l)


(N, K, *A) = map(int, open(0).read().split())
Ap = []
An = []
Az = []
for c in A:
	if c > 0:
		Ap.append(c)
	elif c < 0:
		An.append(c)
	else:
		Az.append(c)
l = -10 ** 20
r = 10 ** 20
Ap.sort(reverse=True)
An.sort()
while l + 1 < r:
	s = (l + r) // 2
	cnt = 0
	j = len(Ap) - 1
	for i in range(len(Ap)):
		while j > -1 and Ap[i] * Ap[j] < s:
			j -= 1
		cnt += len(Ap) - 1 - j
	for i in range(len(Ap)):
		if Ap[i] * Ap[i] < s:
			cnt -= 1
	j = len(An) - 1
	for i in range(len(An)):
		while j > -1 and An[i] * An[j] < s:
			j -= 1
		cnt += len(An) - 1 - j
	for i in range(len(An)):
		if An[i] * An[i] < s:
			cnt -= 1
	cnt //= 2
	if s > 0:
		cnt += len(Az) * (len(Az) - 1) // 2 + len(Az) * (len(Ap) + len(An)) + len(Ap) * len(An)
	else:
		j = 0
		for i in range(len(Ap) - 1, -1, -1):
			while j < len(An) and Ap[i] * An[j] < s:
				j += 1
			cnt += j
	if cnt >= K:
		r = s
	else:
		l = s
print(l)


(N, K) = map(int, input().split())
A = [int(c) for c in input().split()]
Ap = []
An = []
Az = []
for i in range(N):
	if A[i] > 0:
		Ap += [A[i]]
	elif A[i] < 0:
		An += [A[i]]
	else:
		Az += [A[i]]
lp = len(Ap)
ln = len(An)
lz = len(Az)
Ap.sort(reverse=True)
An.sort(reverse=True)

def f(m, B, C):
	cnt = 0
	j = 0
	lb = len(B)
	lc = len(C)
	for i in range(lc):
		while j < lb:
			if B[j] * C[i] >= m:
				cnt += j
				break
			j += 1
		else:
			cnt += j
	return cnt
if K <= lp * ln:
	r = 1
	l = -10 ** 18 + 10
	while l + 1 < r:
		n = (l + r) // 2
		if f(n, Ap, An) >= K:
			r = n
		else:
			l = n
	print(l)
	import sys
	sys.exit()
K -= lp * ln
if K <= lz * (lp + ln) + lz * (lz - 1) // 2:
	print(0)
	import sys
	sys.exit()
K -= lz * (lp + ln) + lz * (lz - 1) // 2
r = 10 ** 18 + 10
l = -1
while l + 1 < r:
	n = (l + r) // 2
	P = f(n, Ap[::-1], Ap)
	for i in range(lp):
		if Ap[lp - 1 - i] * Ap[lp - 1 - i] < n:
			P -= 1
		else:
			break
	P //= 2
	N = f(n, An, An[::-1])
	for i in range(ln):
		if An[i] * An[i] < n:
			N -= 1
		else:
			break
	N //= 2
	if P + N >= K:
		r = n
	else:
		l = n
print(l)


import bisect
import numpy as np
(N, K) = list(map(int, input().split()))
A = list(map(int, input().split()))

def simple():
	B = sorted([A[i] * A[j] for i in range(N) for j in range(i + 1, N)])
	return B[K - 1]

def solve():
	A.sort()
	iplus = bisect.bisect_right(A, 0)
	izeros = bisect.bisect_left(A, 0)
	pluss = np.array(A[iplus:]).astype(np.int64)
	zeros = A[izeros:iplus]
	minuss = np.array(A[:izeros]).astype(np.int64)
	nplus = len(pluss)
	nzero = len(zeros)
	nminus = len(minuss)
	npminus = nplus * nminus
	npzeros = nzero * (nplus + nminus) + nzero * (nzero - 1) // 2
	if npminus < K <= npminus + npzeros:
		return 0
	elif K <= npminus:
		mn = A[-1] * A[0] - 1
		mx = 0
		while mx - mn > 1:
			mid = (mn + mx) // 2
			xs = -(-mid // minuss)
			cnt = nplus * nminus
			cnt -= np.sum(np.searchsorted(pluss, xs, side='left'))
			if cnt >= K:
				mx = mid
			else:
				mn = mid
		return mx
	else:
		nK = K - npminus - npzeros
		pluss2 = (-minuss)[::-1]
		mn = -1
		mx = max(A[0] ** 2, A[-1] ** 2)
		pluss_p2 = pluss ** 2
		pluss2_p2 = pluss2 ** 2
		while mx - mn > 1:
			mid = (mn + mx) // 2
			cnt = 0
			xs = mid // pluss
			cnt += np.sum(np.searchsorted(pluss, xs, side='right'))
			cnt -= np.count_nonzero(pluss_p2 <= mid)
			xs2 = mid // pluss2
			cnt += np.sum(np.searchsorted(pluss2, xs2, side='right'))
			cnt -= np.count_nonzero(pluss2_p2 <= mid)
			cnt = cnt // 2
			if nK <= cnt:
				mx = mid
			else:
				mn = mid
		return mx
print(solve())


import sys
readline = sys.stdin.readline

def count(A, B, x):
	N = len(A)
	M = len(B)
	res = 0
	r = -1
	for l in range(N):
		a = A[l]
		while r < M - 1 and B[r + 1] * a <= x:
			r += 1
		res += r + 1
	return res

def count2(A, x):
	res = 0
	for a in A:
		if a * a <= x:
			res += 1
	return res
(N, K) = map(int, readline().split())
A = list(map(int, readline().split()))
Am = []
Ap = []
minus = 0
zero = 0
plus = 0
for a in A:
	if a < 0:
		minus += 1
		Am.append(-a)
	elif a == 0:
		zero += 1
	else:
		plus += 1
		Ap.append(a)
ms = minus * plus
zs = ms + zero * (minus + plus) + zero * (zero - 1) // 2
Am.sort()
Ap.sort()
Amr = Am[::-1]
Apr = Ap[::-1]
if K <= ms:
	K = ms + 1 - K
	ok = max(max(Am + [0]), max(Ap + [0])) ** 2
	ng = 0
	while abs(ok - ng) > 1:
		med = (ok + ng) // 2
		if count(Amr, Ap, med) >= K:
			ok = med
		else:
			ng = med
	ans = -ok
elif K <= zs:
	ans = 0
else:
	K -= zs
	ok = max(max(Am + [0]), max(Ap + [0])) ** 2
	ng = 0
	while abs(ok - ng) > 1:
		med = (ok + ng) // 2
		if (count(Amr, Am, med) + count(Apr, Ap, med) - count2(Am, med) - count2(Ap, med)) // 2 >= K:
			ok = med
		else:
			ng = med
	ans = ok
print(ans)


(n, k) = list(map(int, input().split()))
a = list(map(int, input().split()))
am = []
ap = []
zc = 0
for i in a:
	if i < 0:
		am.append(i)
	elif i > 0:
		ap.append(i)
	else:
		zc += 1
am.sort()
ap.sort()

def count(n, m, p, z):
	mx = -10 ** 20
	lm = len(m)
	lp = len(p)
	if n == 0:
		if z or (lm and lp):
			return (lm * lp + (lm + lp) * z + z * (z - 1) // 2, 0 if z else m[-1] * p[0])
		else:
			return (0, 0)
	elif n < 0:
		r = 0
		j = 0
		for i in m:
			while j < len(p) and i * p[j] > n:
				j += 1
			if j < len(p) and mx < i * p[j]:
				mx = i * p[j]
			r += len(p) - j
		return (r, mx)
	else:
		if z or (lm and lp):
			mx = 0 if z else m[-1] * p[0]
		r = lm * lp + (lm + lp) * z + z * (z - 1) // 2
		j = lp - 1
		for i in range(lp):
			while j > i and p[i] * p[j] > n:
				j -= 1
			if j > i and p[i] * p[j] > mx:
				mx = p[i] * p[j]
			r += j - i
			if i == j:
				break
		j = lm - 1
		for i in range(lm):
			while j > i and m[i] * m[j] <= n:
				j -= 1
			if i > j:
				j = i
			if j < lm - 1 and m[i] * m[j + 1] > mx:
				mx = m[i] * m[j + 1]
			r += lm - j - 1
		return (r, mx)
r = 10 ** 18
t = 0
s = set()
while True:
	ret = count(t, am, ap, zc)
	if ret[0] < k:
		s.add(t)
		t += r
		r = (r + 1) // 2
	elif ret[0] == k:
		print(ret[1])
		break
	else:
		if t in s:
			print(ret[1])
			break
		s.add(t)
		t -= r
		r = (r + 1) // 2


import numpy as np

def p(*args, **kargs):
	if DBG:
		print(*args, **kargs)
read = input
rn = lambda : list(map(int, read().split()))
debug = False

def sol(A):
	A = np.array(A, np.int64)
	A = np.sort(A)
	_A = np.sort(-A)
	pos = A[A > 0]
	neg = A[A < 0]
	zero = A[A == 0]

	def searchsorted(*args, **kargs):
		ret = np.searchsorted(*args, **kargs)
		return ret

	def f(x):
		ret = 0
		if x >= 0:
			ret += len(zero) * len(A)
			ret += searchsorted(A, x // pos, side='right').sum()
			ret += searchsorted(_A, x // -neg, side='right').sum()
		else:
			ret += searchsorted(A, x // pos, side='right').sum()
			ret += searchsorted(_A, x // -neg, side='right').sum()
		ret -= np.count_nonzero(A * A <= x)
		assert ret % 2 == 0
		return ret // 2
		if debug:
			print(pos, neg, zero)
	return f
f = sol([-4, -2, 3, 3])
assert f(-12) == 2
assert f(-6) == 4

def bs(A, index):
	A = np.array(A, np.int64)
	f = sol(A)
	max_ele = max(abs(A))
	right = max_ele * max_ele + 1
	left = -right
	while left + 1 < right:
		middle = (left + right) // 2
		m_index = f(middle)
		if debug:
			print(middle, m_index, left, right, sep='\t')
		if index <= m_index:
			right = middle
		else:
			left = middle
	return right
(n, index) = rn()
A = np.array(read().split(), np.int64)
print(bs(A, index))


import numpy as np
(N, K) = list(map(int, input().split()))
A = np.array(list(map(int, input().split())))
A.sort()
pos = A[A > 0]
neg = A[A < 0]
zero = A[A == 0]
l = -10 ** 18
r = 10 ** 18
while l + 1 < r:
	x = (l + r) // 2
	cnt = 0
	if x >= 0:
		cnt += N * len(zero)
	cnt += A.searchsorted(x // pos, side='right').sum()
	cnt += (N - A.searchsorted(-(-x // neg), side='left')).sum()
	cnt -= np.count_nonzero(A * A <= x)
	cnt //= 2
	if cnt >= K:
		r = x
	else:
		l = x
print(r)


from bisect import bisect_right, bisect_left
(N, K) = map(int, input().split())
A = sorted(map(int, input().split()))
t0 = bisect_left(A, 0)
t1 = bisect_right(A, 0)
pos = A[t1:]
neg = [-v for v in reversed(A[:t0])]
zeros = t1 - t0
offset_negative = len(pos) * len(neg)
offset_zero = zeros * (N - zeros) + zeros * (zeros - 1) // 2
offset = offset_zero + offset_negative

def bisect2(ng, ok, judge):
	while abs(ng - ok) > 1:
		m = (ng + ok) // 2
		if judge(m):
			ok = m
		else:
			ng = m
	return ok

def count1(l, n):
	j = len(l)
	cnt = 0
	for (i, a) in enumerate(l):
		v = n // a
		while j > i and l[j - 1] > v:
			j -= 1
		if j <= i:
			break
		else:
			cnt += j - i - 1
	return cnt

def count2(l1, l2, n):
	j = len(l2)
	cnt = 0
	for (i, a) in enumerate(l1):
		v = n // a
		while j > 0 and l2[j - 1] > v:
			j -= 1
		cnt += j
	return cnt

def cnt(n):
	if n > 0:
		cnt = count1(pos, n - 1) + count1(neg, n - 1) + offset
	else:
		cnt = offset_negative - count2(pos, neg, -n)
	return cnt
if offset_negative < K <= offset:
	print(0)
else:
	temp = max((abs(a) for a in A)) ** 2
	print(bisect2(temp, -temp, lambda n: cnt(n) <= K - 1))


import sys
input = sys.stdin.readline
(N, K) = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
mina = []
zera = []
plua = []
for x in a:
	if x > 0:
		plua.append(x)
	elif x == 0:
		zera.append(x)
	else:
		mina.append(x)
mlim = len(mina) * len(plua)
zlim = len(zera) * (len(mina) + len(plua)) + len(zera) * (len(zera) - 1) // 2 + mlim

def minacheck(x):
	res = 0
	j = 0
	for i in range(len(plua)):
		while j < len(mina) and plua[i] * mina[j] <= x:
			j += 1
		res += j
	return res >= K

def pluacheck(x):
	res = 0
	j = 0
	for i in range(len(mina) - 1, -1, -1):
		while j < len(mina) and mina[i] * mina[j] <= x:
			j += 1
		res += max(0, j - i - 1)
	j = 0
	for i in range(len(plua) - 1, -1, -1):
		while j < len(plua) and plua[i] * plua[j] <= x:
			j += 1
		res += max(0, j - i - 1)
	return res >= K - zlim
if K <= mlim:
	ng = -pow(10, 18)
	ok = 0
	while ok - ng > 1:
		m = (ok + ng) // 2
		if minacheck(m):
			ok = m
		else:
			ng = m
	print(ok)
elif K <= zlim:
	print(0)
else:
	for i in range(len(mina)):
		mina[i] = -mina[i]
	mina.reverse()
	ng = 0
	ok = pow(10, 18)
	while ok - ng > 1:
		m = (ok + ng) // 2
		if pluacheck(m):
			ok = m
		else:
			ng = m
	print(ok)


import numpy as np
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
a = np.array(a, dtype='int64')
a_minus = a[a < 0]
a_plus = a[a > 0]
a_zero = a[a == 0]
l = -10 ** 19
r = 10 ** 19
while r - l > 1:
	mid = (l + r) // 2
	cnt = 0
	cnt += a.searchsorted(mid // a_plus, side='right').sum()
	cnt += (n - a.searchsorted((-mid - 1) // -a_minus, side='right')).sum()
	cnt -= np.count_nonzero(a * a <= mid)
	cnt += len(a_zero) * n if mid >= 0 else 0
	cnt //= 2
	if cnt >= k:
		r = mid
	else:
		l = mid
print(r)


import numpy as np
(n, k) = map(int, input().split())
a = np.sort(np.array(input().split(), 'int64'))
plus = a[a > 0]
zeros = np.sum(a == 0)
minus = a[a < 0]

def counter(T):
	c = 0
	if T >= 0:
		c += zeros * n
	c += np.searchsorted(a, T // plus, side='right').sum()
	c += (n - np.searchsorted(a, (-T - 1) // -minus, side='right')).sum()
	c -= np.count_nonzero(a * a <= T)
	return c // 2
left = -10 ** 18
right = 10 ** 18
while abs(right - left) > 1:
	mid = (left + right) // 2
	if counter(mid) >= k:
		right = mid
	else:
		left = mid
print(right)


from bisect import bisect_right, bisect_left
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
(ap, an) = ([], [])
zeronum = 0
for i in range(n):
	if a[i] > 0:
		ap.append(a[i])
	elif a[i] < 0:
		an.append(-a[i])
	else:
		zeronum += 1
an.sort()
ap.sort()
(np, nn) = (len(ap), len(an))
if np * nn < k <= np * nn + zeronum * (zeronum - 1) // 2 + zeronum * (np + nn):
	print(0)
elif k <= np * nn:
	ng = 10 ** 18
	ok = 0
	while ng - ok > 1:
		mid = (ok + ng) // 2
		cnt = 0
		for i in range(nn):
			if mid % an[i] != 0:
				cnt += np - bisect_left(ap, mid // an[i] + 1)
			else:
				cnt += np - bisect_left(ap, mid // an[i])
		if cnt >= k:
			ok = mid
		else:
			ng = mid
	print(-ok)
else:
	k -= np * nn + zeronum * (zeronum - 1) // 2 + zeronum * (np + nn)
	ok = 10 ** 18
	ng = 0
	while ok - ng > 1:
		mid = (ok + ng) // 2
		(cnt1, cnt2) = (0, 0)
		if np >= 2:
			for i in range(np):
				cnt1 += bisect_right(ap, mid // ap[i])
				if ap[i] ** 2 <= mid:
					cnt1 -= 1
		if nn >= 2:
			for i in range(nn):
				cnt2 += bisect_right(an, mid // an[i])
				if an[i] ** 2 <= mid:
					cnt2 -= 1
		if cnt1 // 2 + cnt2 // 2 >= k:
			ok = mid
		else:
			ng = mid
	print(ok)


from bisect import bisect_left, bisect_right

def func(mn, zn, pn, am, ap, x):
	cnt = 0
	if x > 0:
		cnt += mn * pn
		cnt += zn * (n - 1 + n - zn) // 2
		cnt1 = 0
		for y in ap:
			cnt1 += bisect_left(ap, (x + y - 1) // y)
			if y ** 2 < x:
				cnt1 -= 1
		for y in am:
			cnt1 += bisect_left(am, (x + y - 1) // y)
			if y ** 2 < x:
				cnt1 -= 1
		cnt += cnt1 // 2
	elif x < 0:
		x = abs(x)
		for y in ap:
			cnt += mn - bisect_right(am, x // y)
	elif x == 0:
		cnt += mn * pn
	return cnt < k

def main(n, k, a):
	a.sort()
	mn = bisect_left(a, 0)
	zn = bisect_right(a, 0) - mn
	pn = n - mn - zn
	am = a[:mn]
	am = [-x for x in am[::-1]]
	ap = a[mn + zn:]
	if k <= mn * pn:
		(l, r) = (a[0] * a[-1] - 1, 0)
	elif k <= mn * pn + zn * (n - zn) + zn * (zn - 1) // 2:
		print(0)
		exit()
	else:
		(l, r) = (0, max(a[0] * a[1], a[-1] * a[-2]) + 1)
	while r - l > 1:
		x = (l + r) // 2
		if func(mn, zn, pn, am, ap, x):
			(l, r) = (x, r)
		else:
			(l, r) = (l, x)
	print(l)
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
main(n, k, a)


import numpy as np
(N, K) = map(int, input().split())
L = np.array(list(map(int, input().split())))
L = np.sort(L)
pos = L[0 < L]
neg = L[0 > L]
zero = len(L[L == 0])

def f(x):
	tmp = 0
	if x >= 0:
		tmp += zero * N
	tmp += np.searchsorted(L, x // pos, side='right').sum()
	tmp += (N - np.searchsorted(L, -(-x // neg), side='left')).sum()
	tmp -= np.count_nonzero(L * L <= x)
	return tmp // 2
(l, r) = (-10 ** 18, 10 ** 18)
while l < r - 1:
	m = (l + r) // 2
	count = f(m)
	if count >= K:
		r = m
	else:
		l = m
print(r)


import numpy as np
(n, k) = list(map(int, input().split()))
a = np.array(list(map(int, input().split())))
a.sort()
plus = a[a > 0]
minus = a[a < 0]
zero = a[a == 0]
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	x = (left + right) // 2
	cnt = 0
	if x >= 0:
		cnt += n * len(zero)
	cnt += a.searchsorted(x // plus, side='right').sum()
	cnt += (n - a.searchsorted(-(-x // minus), side='left')).sum()
	cnt -= np.count_nonzero(a * a <= x)
	cnt //= 2
	if cnt >= k:
		right = x
	else:
		left = x
print(right)


import sys
input = sys.stdin.readline
import numpy as np

def main():
	(N, K) = map(int, input().split())
	A = np.sort(np.array(list(map(int, input().split())), np.int64))
	z = A[A == 0]
	p = A[A > 0]
	n = A[A < 0]

	def count_func(x):
		cnt = 0
		if x >= 0:
			cnt += len(z) * N
		cnt += np.searchsorted(A, x // p, side='right').sum()
		cnt += (N - np.searchsorted(A, -(-x // n), side='left')).sum()
		cnt -= np.count_nonzero(A * A <= x)
		assert cnt % 2 == 0
		return cnt // 2
	l = -10 ** 18
	r = 10 ** 18
	while l + 1 < r:
		x = (l + r) // 2
		if count_func(x) >= K:
			r = x
		else:
			l = x
	print(r)

def __starting_point():
	main()
__starting_point()


import sys
input = sys.stdin.readline
(n, k) = map(int, input().split())
(a, b, c) = (0, 0, 0)
(L, R) = ([], [])
for p in map(int, input().split()):
	if p < 0:
		a += 1
		L.append(p)
	elif p == 0:
		b += 1
	else:
		c += 1
		R.append(p)
L.sort()
R.sort()
s = a * c
t = b * (b - 1) // 2 + (a + c) * b
if s < k <= s + t:
	ans = 0
else:
	if k <= s:
		ok = -1
		ng = -(10 ** 18 + 1)
		while ok - ng > 1:
			mid = (ok + ng) // 2
			now = 0
			temp = 0
			for l in L:
				while now < c and l * R[now] > mid:
					now += 1
				temp += c - now
			if temp >= k:
				ok = mid
			else:
				ng = mid
	else:
		ok = 10 ** 18
		ng = 0
		while ok - ng > 1:
			mid = (ok + ng) // 2
			now = c - 1
			temp = s + t
			for (i, r) in enumerate(R):
				if now <= i:
					break
				while now > i and r * R[now] > mid:
					now -= 1
				temp += now - i
			now = 0
			for i in range(a - 1, -1, -1):
				l = L[i]
				if now >= i:
					break
				while now < i and l * L[now] > mid:
					now += 1
				temp += i - now
			if temp >= k:
				ok = mid
			else:
				ng = mid
	ans = ok
print(ans)


(n, k) = map(int, input().split())
a = list(map(int, input().split()))
(plus, zero, minus) = ([], [], [])
for x in a:
	if x > 0:
		plus.append(x)
	elif x == 0:
		zero.append(x)
	else:
		minus.append(x)
(m, z, p) = (len(minus), len(zero), len(plus))
(mm, zz, pp) = (m * p, z * (m + p) + z * (z - 1) // 2, m * (m - 1) // 2 + p * (p - 1) // 2)
plus.sort()
plus2 = plus[::-1]
minus.sort()
minus2 = minus[::-1]
if mm + zz >= k and mm < k:
	print(0)
elif mm >= k:
	(ok, ng) = (-10 ** 19, 0)
	while ng - ok > 1:
		x = (ng + ok) // 2
		res = 0
		l = 0
		for c in plus:
			if l == m:
				res += m
			elif minus[l] * c >= x:
				res += l
			else:
				while minus[l] * c < x:
					l += 1
					if l == m:
						break
				res += l
		if res < k:
			ok = x
		else:
			ng = x
	print(ng - 1)
else:
	(ok, ng) = (0, 10 ** 19)
	while ng - ok > 1:
		x = (ng + ok) // 2
		(lm, lp) = (0, 0)
		res = 0
		for c in minus:
			if c * c < x:
				res -= 1
			if lm == m:
				res += m
			elif minus2[lm] * c >= x:
				res += lm
			else:
				while minus2[lm] * c < x:
					lm += 1
					if lm == m:
						break
				res += lm
		for c in plus2:
			if c * c < x:
				res -= 1
			if lp == p:
				res += p
			elif plus[lp] * c >= x:
				res += lp
			else:
				while plus[lp] * c < x:
					lp += 1
					if lp == p:
						break
				res += lp
		res //= 2
		res += zz + mm
		if res < k:
			ok = x
		else:
			ng = x
	print(ng - 1)


import sys
input = sys.stdin.readline
INF = 10 ** 19
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
pos = []
neg = []
for a in A:
	if a >= 0:
		pos.append(a)
	else:
		neg.append(a)
pos.sort()
neg.sort()
(p, n) = (len(pos), len(neg))
if K <= p * n:
	(lb, ub) = (-INF, INF)
	while ub - lb > 1:
		mid = (lb + ub) // 2
		cnt = 0
		(s, t) = (0, 0)
		while s < p:
			while t < n and pos[s] * neg[t] <= mid:
				t += 1
			cnt += t
			s += 1
		if cnt < K:
			lb = mid
		else:
			ub = mid
	print(ub)
else:
	K -= p * n
	neg = neg[::-1]
	(lb, ub) = (-INF, INF)
	while ub - lb > 1:
		mid = (lb + ub) // 2
		cnt = 0
		(s, t) = (p - 1, 0)
		while s >= 0:
			while t < s and pos[s] * pos[t] <= mid:
				t += 1
			cnt += min(s, t)
			s -= 1
		(s, t) = (n - 1, 0)
		while s >= 0:
			while t < s and neg[s] * neg[t] <= mid:
				t += 1
			cnt += min(s, t)
			s -= 1
		if cnt < K:
			lb = mid
		else:
			ub = mid
	print(ub)


import numpy as np
(N, K) = map(int, input().split())
a = np.array(input().split(), np.int64)
a = np.sort(a)
zero = a[a == 0]
pos = a[a > 0]
neg = a[a < 0]

def f(x):
	count = 0
	c = x // pos
	count += np.searchsorted(a, c, side='right').sum()
	count += N * len(zero) if x >= 0 else 0
	c = -(-x // neg)
	count += (N - np.searchsorted(a, c, side='left')).sum()
	count -= a[a * a <= x].size
	count //= 2
	return count
right = 10 ** 18
left = -10 ** 18
while right - left > 1:
	mid = (right + left) // 2
	if f(mid) < K:
		left = mid
	else:
		right = mid
print(right)


from bisect import bisect_left, bisect_right
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
inf = 10 ** 20
a.sort()
mc = zc = pc = 0
m = []
p = []
for i in a:
	if i < 0:
		mc += 1
		m.append(i)
	elif i == 0:
		zc += 1
	else:
		pc += 1
		p.append(i)
if mc * pc >= k:
	for i in range(len(m)):
		m[i] *= -1
	k = mc * pc - k + 1
	m = m[::-1]
	p = [0] + p
	ng = 0
	ok = 10 ** 19 + 7
	mi = 10 ** 19 + 7
	while ng + 1 != ok:
		ma = 0
		mid = (ng + ok) // 2
		co = 0
		j = len(p) - 1
		for i in m:
			while p[j] * i > mid:
				j -= 1
			co += j
			ma = max(ma, p[j] * i)
		if co < k:
			ng = mid
		else:
			ok = mid
			mi = min(mi, ma)
	print(-mi)
elif mc * pc + zc * (zc - 1) // 2 + zc * (pc + mc) >= k:
	print(0)
else:
	k -= mc * pc + zc * (zc - 1) // 2 + zc * (pc + mc)
	for i in range(len(m)):
		m[i] *= -1
	m = m[::-1]
	m = [0] + m
	p = [0] + p
	ng = 0
	ok = 10 ** 19 + 7
	mi = 10 ** 19 + 7
	while ng + 1 != ok:
		ma = 0
		mid = (ok + ng) // 2
		co = 0
		jjj = 0
		j = len(p) - 1
		pok = []
		for i in range(len(p)):
			if p[i] == 0:
				continue
			while p[j] * p[i] > mid:
				j -= 1
			co += max(0, j - i)
			ma = max(ma, p[j] * p[i])
		j = len(m) - 1
		for i in range(len(m)):
			if m[i] == 0:
				continue
			while m[j] * m[i] > mid:
				j -= 1
			co += max(0, j - i)
			ma = max(ma, m[j] * m[i])
		if co < k:
			ng = mid
		else:
			ok = mid
			mi = min(mi, ma)
	print(mi)


import sys
import numpy as np
INF = 10 ** 18 + 5
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 6)

def main():
	(n, k) = list(map(int, input().split()))
	a = list(map(int, input().split()))
	a = np.sort(a)
	ap = a[a > 0]
	an = a[a < 0]
	zc = n * (n - ap.size - an.size)
	l = -INF
	r = INF
	while l + 1 < r:
		x = (l + r) // 2
		total = (n - np.searchsorted(a, -(-x // an), side='left')).sum()
		if x >= 0:
			total += zc
		total += np.searchsorted(a, x // ap, side='right').sum()
		total -= a[a * a <= x].size
		total //= 2
		if total < k:
			l = x
		else:
			r = x
	print(r)
main()


import numpy as np
(n, k) = map(int, input().split())
a_list = np.array(list(map(int, input().split())))
a_list.sort()
zero_list = a_list[a_list == 0]
minus_list = a_list[a_list < 0]
plus_list = a_list[a_list > 0]

def index_count(x):
	cnt = 0
	if x >= 0:
		cnt += len(zero_list) * n
	cnt += np.searchsorted(a_list, x // plus_list, side='right').sum()
	cnt += (n - np.searchsorted(a_list, -(-x // minus_list), side='left')).sum()
	cnt -= np.count_nonzero(a_list * a_list <= x)
	assert cnt % 2 == 0
	return cnt // 2
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	mid = (left + right) // 2
	a = index_count(mid)
	if a >= k:
		right = mid
	else:
		left = mid
print(right)


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

def check(t):
	j = n - 1 if t > 0 else 0
	res = 0
	f = 1
	cond = lambda x, t, f: x <= t if f * t > 0 or (t == 0 and f == -1) else x > t
	shift = lambda x, t: x - 1 if t > 0 else x + 1
	count = lambda x, n, f: n - x if f == 1 else x
	for ai in a:
		if f == 1 and ai > 0:
			f = -1
			j = n - 1 if t > 0 else 0
		if ai:
			while j >= 0 and j < n and cond(ai * a[j], t, f):
				j = shift(j, t)
			if t > 0:
				res += count(j + 1, n, f)
			else:
				res += count(j, n, f)
		elif t >= 0:
			res += n
		if ai * ai <= t:
			res -= 1
	return res // 2
m = max(max(a) ** 2, min(a) ** 2)
l = -m
r = m
while r - l > 1:
	mid = (l + r) // 2
	if check(mid) < k:
		l = mid
	else:
		r = mid
if check(l) == k:
	print(l)
else:
	print(r)


(N, K) = map(int, input().split())
A = list(map(int, input().split()))
(m, p) = ([], [])
for a in A:
	if a < 0:
		m.append(a)
	elif a > 0:
		p.append(a)
(M, P) = (len(m), len(p))
Z = N - M - P
m.sort()
p.sort()
if M * P < K <= N * (N - 1) // 2 - M * (M - 1) // 2 - P * (P - 1) // 2:
	print(0)
elif K <= M * P:
	(l, r) = (-10 ** 18 - 1, 0)
	while l + 1 < r:
		t = (l + r) // 2
		x = 0
		mi = 0
		for pi in range(P):
			while mi < M and m[mi] * p[pi] <= t:
				mi += 1
			x += mi
		if K <= x:
			r = t
		else:
			l = t
	print(r)
else:
	(l, r) = (0, 10 ** 18 + 1)
	K -= M * P + Z * (Z - 1) // 2 + Z * (M + P)
	m.reverse()
	while l + 1 < r:
		t = (l + r) // 2
		x = 0
		(mi, pi) = (0, 0)
		for mj in range(M - 1, -1, -1):
			while mi < M and m[mi] * m[mj] <= t:
				mi += 1
			x += mi - (1 if mj < mi else 0)
		for pj in range(P - 1, -1, -1):
			while pi < P and p[pi] * p[pj] <= t:
				pi += 1
			x += pi - (1 if pj < pi else 0)
		if K <= x // 2:
			r = t
		else:
			l = t
	print(r)


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
plus = minus = zero = 0
ps = []
ms = []
for i in a:
	if i == 0:
		zero += 1
	elif i > 0:
		plus += 1
		ps.append(i)
	else:
		minus += 1
		ms.append(-i)
ps.sort()
ms.sort()

def check(m):
	if m == 0:
		return plus * minus + zero * (zero - 1) // 2 + zero * (plus + minus) >= k
	elif m > 0:
		tmp = plus * minus + zero * (zero - 1) // 2 + zero * (plus + minus)
		for l in [ps, ms]:
			X = len(l)
			cur = X - 1
			for i in range(X):
				while cur >= 0 and l[i] * l[cur] > m:
					cur -= 1
				if cur <= i:
					break
				tmp += cur - i
		return tmp >= k
	else:
		tmp = 0
		cur = 0
		for i in reversed(range(plus)):
			while cur < minus and ms[cur] * ps[i] < -m:
				cur += 1
			tmp += minus - cur
		return tmp >= k
left = -10 ** 20
right = 10 ** 20
while right - left > 1:
	mid = (right + left) // 2
	if check(mid):
		right = mid
	else:
		left = mid
print(right)


import numpy as np
from numba import njit

@njit
def main(I):
	(N, K) = (I[0], I[1])
	A = I[2:]
	A.sort()
	lb = -10 ** 18 - 1
	rb = 10 ** 18 + 1
	while rb - lb > 1:
		target = (rb + lb) // 2
		if 1:
			cnt = 0
			for (i, a) in enumerate(A):
				if a == 0:
					d = i if target >= 0 else 0
				elif a < 0:
					il = np.searchsorted(A, 0 - -target // a, side='left')
					d = max(i - il, 0)
				else:
					ir = np.searchsorted(A, target // a, side='right')
					d = min(ir, i)
				cnt += d
		if cnt >= K:
			rb = target
		else:
			lb = target
	return rb
I = np.array([int(_) for _ in open(0).read().split()], dtype=int)
print(main(I))


import sys
stdin = sys.stdin
ns = lambda : stdin.readline().rstrip()
ni = lambda : int(stdin.readline().rstrip())
nm = lambda : map(int, stdin.readline().split())
nl = lambda : list(map(int, stdin.readline().split()))
(n, k) = nm()
l = nl()
f = list(filter(lambda x: x > 0, l))
g = list(filter(lambda x: x < 0, l))
f.sort()
g.sort(reverse=True)
pl = len(f)
mi = len(g)
ze = n - pl - mi
tomi = pl * mi
if tomi >= k:

	def jud(z):
		ret = 0
		i = mi
		for x in f:
			while i and x * g[i - 1] <= z:
				i -= 1
			ret += mi - i
		return ret
	(ok, ng) = (0, max(f) * min(g) - 1)
	while ok - ng > 1:
		mid = (ok + ng) // 2
		if jud(mid) < k:
			ng = mid
		else:
			ok = mid
	print(ok)
	exit(0)
tomi += ze * (n - ze) + (ze - 1) * ze // 2
if tomi >= k:
	print(0)
	exit(0)
else:
	k -= tomi

	def jud2(z):
		ret = 0
		i = pl
		for (e, x) in enumerate(f):
			while i and f[i - 1] * x > z:
				i -= 1
			ret += i - (e <= i - 1)
		i = mi
		for (e, x) in enumerate(g):
			while i and g[i - 1] * x > z:
				i -= 1
			ret += i - (e <= i - 1)
		return ret // 2
	(ok, ng) = (0, max(max(f + [0]) ** 2, min(g + [0]) ** 2))
	while ng - ok > 1:
		mid = (ok + ng) // 2
		if jud2(mid) < k:
			ok = mid
		else:
			ng = mid
	print(ng)


import numpy as np
(N, K) = [int(i) for i in input().split(' ')]
A = np.array([int(i) for i in input().split(' ')])
A.sort()
zero = A[A == 0]
minus = A[A < 0]
plus = A[A > 0]

def index_count(x):
	cnt = 0
	if x >= 0:
		cnt += len(zero) * N
	cnt += np.searchsorted(A, x // plus, side='right').sum()
	cnt += (N - np.searchsorted(A, -(-x // minus), side='left')).sum()
	cnt -= np.count_nonzero(A * A <= x)
	assert cnt % 2 == 0
	return cnt // 2
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	mid = (left + right) // 2
	a = index_count(mid)
	if a >= K:
		right = mid
	else:
		left = mid
print(right)


(n, k) = map(int, input().split())
nums = list(map(int, input().split()))
neg_nums = []
pos_nums = []
nums.sort()
for num in nums:
	if num < 0:
		neg_nums.append(num)
	else:
		pos_nums.append(num)
l = -1231232132131232112213
r = 12312321321312312312

def cost_k(m):
	cur_k = 0
	(l_pos, r_pos) = (0, len(pos_nums) - 1)
	while l_pos < r_pos:
		if pos_nums[l_pos] * pos_nums[r_pos] <= m:
			cur_k += r_pos - l_pos
			l_pos += 1
		else:
			r_pos -= 1
	(l_neg, r_neg) = (0, len(neg_nums) - 1)
	while l_neg < r_neg:
		if neg_nums[l_neg] * neg_nums[r_neg] <= m:
			cur_k += r_neg - l_neg
			r_neg -= 1
		else:
			l_neg += 1
	(l_pos, l_neg) = (0, 0)
	while l_pos < len(pos_nums) and l_neg < len(neg_nums):
		if neg_nums[l_neg] * pos_nums[l_pos] <= m:
			cur_k += len(pos_nums) - l_pos
			l_neg += 1
		else:
			l_pos += 1
	return cur_k
while r - l > 1:
	m = (r + l) // 2
	cur_k = cost_k(m)
	if cur_k < k:
		l = m
	else:
		r = m
print(r)


(N, K) = map(int, input().split())
A = [int(i) for i in input().split()]
A = sorted(A)
B = []
C = []
D = []
for i in range(len(A)):
	if A[i] < 0:
		B.append(A[i])
	elif A[i] == 0:
		C.append(A[i])
	else:
		D.append(A[i])
b = len(B)
c = len(C)
d = len(D)

def f(n):
	if n < 0:
		i = 0
		j = 0
		k = 0
		while i < b and j < d:
			if B[i] * D[j] > n:
				j += 1
			else:
				i += 1
				k += d - j
		return k
	elif n == 0:
		return c * (c - 1) // 2 + b * c + b * d + c * d
	else:
		i = 0
		j = b - 1
		k = 0
		while i < b and j > -1:
			if B[i] * B[j] > n:
				i += 1
				k += j + 1
			else:
				j -= 1
		k = b ** 2 - k
		i = 0
		j = d - 1
		while i < d and j > -1:
			if D[i] * D[j] <= n:
				i += 1
				k += j + 1
			else:
				j -= 1
		l = 0
		for i in range(b):
			if B[i] ** 2 <= n:
				l += 1
		for i in range(d):
			if D[i] ** 2 <= n:
				l += 1
		return (k - l) // 2 + c * (c - 1) // 2 + b * c + b * d + c * d
l = -10 ** 18
h = 10 ** 18
while l + 1 < h:
	m = (l + h) // 2
	if f(m) >= K:
		h = m
	else:
		l = m
print(h)


import numpy as np
(n, k) = list(map(int, input().split()))
A = np.array(sorted(list(map(int, input().split()))), np.int64)
posA = A[A > 0]
negA = A[A < 0]
z = (A == 0).sum()
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	num = (left + right) // 2
	count = 0
	if num >= 0:
		count += z * n
	limit_pos = num // posA
	limit_idx = np.searchsorted(A, limit_pos, side='right')
	count += limit_idx.sum()
	limit_neg = -(-num // negA)
	limit_idx = n - np.searchsorted(A, limit_neg, side='left')
	count += limit_idx.sum()
	duplicate_cases = (A ** 2 <= num).sum()
	count -= duplicate_cases
	count //= 2
	if count >= k:
		right = num
	else:
		left = num
print(right)


import numpy as np
(N, K) = map(int, input().split())
A = np.array(list(map(int, input().split())))
A = np.sort(A)
G = A[A > 0]
Z = A[A == 0]
L = A[A < 0]
(l, r) = (10 ** 18, -10 ** 18)
while l - r > 1:
	m = (l + r) // 2
	Pk = np.searchsorted(A, m // G, side='right').sum()
	Nk = (N - np.searchsorted(A, (-m - 1) // -L, side='right')).sum()
	duplicate = np.count_nonzero(A * A <= m)
	Zk = 0
	if m >= 0:
		Zk += len(Z) * N
	k = Pk + Nk + Zk - duplicate
	k //= 2
	if k >= K:
		l = m
	else:
		r = m
print(l)


import sys
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
l = sys.maxsize * -1
r = sys.maxsize
while l + 1 < r:
	x = (l + r) // 2

	def isOk():
		tot = 0
		for i in range(n):
			if a[i] < 0:
				l = -1
				r = n
				while l + 1 < r:
					c = (l + r) // 2
					if a[c] * a[i] < x:
						r = c
					else:
						l = c
				tot += n - r
			else:
				l = -1
				r = n
				while l + 1 < r:
					c = (l + r) // 2
					if a[c] * a[i] < x:
						l = c
					else:
						r = c
				tot += r
			if a[i] * a[i] < x:
				tot -= 1
		tot /= 2
		return tot < k
	if isOk():
		l = x
	else:
		r = x
print(l)


(N, K, *A) = map(int, open(0).read().split())
neg = sorted([-a for a in A if a < 0])
pos = sorted([a for a in A if a >= 0])

def _count_pair_neg(x):
	x = -x
	res = 0
	MAX = len(pos)
	i = 0
	for n in reversed(neg):
		while i < MAX and n * pos[i] < x:
			i += 1
		res += MAX - i
	return res

def _count_pair_pos(x):
	res = 0
	i = 0
	MAX = len(neg)
	for n in reversed(neg):
		if n * n <= x:
			res -= 1
		while i < MAX and neg[i] * n <= x:
			i += 1
		res += i
	i = 0
	MAX = len(pos)
	for n in reversed(pos):
		if n * n <= x:
			res -= 1
		while i < MAX and pos[i] * n <= x:
			i += 1
		res += i
	res //= 2
	res += len(neg) * len(pos)
	return res

def count_pair(x):
	if x < 0:
		return _count_pair_neg(x)
	return _count_pair_pos(x)
lb = 0
ub = 2 * 10 ** 18 + 2
while ub - lb > 1:
	mid = (ub + lb) // 2
	if count_pair(mid - 10 ** 18 - 1) < K:
		lb = mid
	else:
		ub = mid
print(ub - 10 ** 18 - 1)


from bisect import bisect_left, bisect_right
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
neg_end = bisect_left(A, 0)
pos_start = bisect_right(A, 0)
pos_cnt = N - pos_start
neg_cnt = neg_end
zero_cnt = N - (pos_cnt + neg_cnt)
neg_pairs_cnt = pos_cnt * neg_cnt
zero_pairs_cnt = zero_cnt * (pos_cnt + neg_cnt) + zero_cnt * (zero_cnt - 1) // 2
if K <= neg_pairs_cnt:
	(ok, ng) = (0, -10 ** 18)
	while abs(ok - ng) > 1:
		X = (ok + ng) // 2
		(or_higher_cnt, r) = (0, pos_start)
		for l in range(neg_end):
			while r < N and A[l] * A[r] > X:
				r += 1
			or_higher_cnt += pos_cnt - (r - pos_start)
		if or_higher_cnt >= K:
			ok = X
		else:
			ng = X
	print(ok)
elif K <= neg_pairs_cnt + zero_pairs_cnt:
	print(0)
else:
	K -= neg_pairs_cnt + zero_pairs_cnt
	(ok, ng) = (10 ** 18, 0)
	while abs(ok - ng) > 1:
		X = (ok + ng) // 2
		or_higher_cnt = 0
		r = N - 1
		for l in range(pos_start, N):
			while r < N and A[l] * A[r] > X and (l < r):
				r -= 1
			or_higher_cnt += max(0, r - l)
		l = 0
		for r in range(neg_end - 1, -1, -1):
			while l < N and A[l] * A[r] > X and (l < r):
				l += 1
			or_higher_cnt += max(0, r - l)
		if or_higher_cnt >= K:
			ok = X
		else:
			ng = X
	print(ok)


from bisect import *
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
posi = 0
nega = 0
zero = 0
p = []
m = []
for i in range(n):
	if a[i] > 0:
		p.append(a[i])
		posi += 1
	elif a[i] < 0:
		nega += 1
		m.append(-a[i])
	else:
		zero += 1
p.sort()
m.sort()
if k <= posi * nega:
	l = 0
	r = 10 ** 18
	while r - l > 1:
		mid = l + (r - l) // 2
		count = k
		for i in range(len(p) - 1, -1, -1):
			count -= nega - bisect_left(m, (mid - 1) // p[i] + 1)
			if count <= 0:
				break
		if count <= 0:
			l = mid
		else:
			r = mid
	print(-l)
elif k <= posi * nega + zero * (zero - 1) // 2 + zero * (posi + nega):
	print(0)
else:
	k -= posi * nega + zero * (zero - 1) // 2 + zero * (posi + nega)
	l = 0
	r = 10 ** 18
	while r - l > 1:
		mid = l + (r - l) // 2
		count = k
		for i in range(len(p)):
			count -= max(bisect_right(p, mid // p[i]) - i - 1, 0)
			if count < 0:
				break
		for i in range(len(m)):
			count -= max(bisect_right(m, mid // m[i]) - i - 1, 0)
			if count < 0:
				break
		if count > 0:
			l = mid
		else:
			r = mid
	print(r)


MAX = 10 ** 18
MIN = -MAX

def main():
	(n, k) = map(int, input().strip().split())
	As = list(map(int, input().strip().split()))
	As.sort()
	(Ans, Aps, Azs) = ([], [], [])
	for A in As:
		if A > 0:
			Aps.append(A)
		elif A == 0:
			Azs.append(A)
		else:
			Ans.append(A)

	def count(xs, ys, ub):
		c = 0
		r = len(ys) - 1
		for l in range(len(xs)):
			while r >= 0 and xs[l] * ys[r] > ub:
				r -= 1
			c += r + 1
		return c

	def bs(l, r):
		while True:
			mid = (l + r) // 2
			if r - l <= 1:
				return r
			tot = 0
			tot += count(Aps, Aps, mid) - sum([1 for A in Aps if A ** 2 <= mid])
			tot += count(Ans[::-1], Ans[::-1], mid) - sum([1 for A in Ans if A ** 2 <= mid])
			tot //= 2
			if mid >= 0:
				tot += (len(Aps) + len(Ans)) * len(Azs) + len(Azs) * (len(Azs) - 1) // 2
			tot += count(Aps[::-1], Ans, mid)
			if tot < k:
				l = mid
			else:
				r = mid
	print(bs(MIN - 1, MAX + 1))
main()


import sys
input = sys.stdin.readline
(n, k) = map(int, input().split())
A = list(map(int, input().split()))
minus = 0
for i in range(n):
	if A[i] < 0:
		minus += 1
zplus = n - minus
B = []
C = []
for i in range(n):
	if A[i] < 0:
		C.append(A[i])
	else:
		B.append(A[i])
B.sort(reverse=True)
C.sort()
if k <= minus * zplus:
	ok = 1
	ng = -10 ** 20
	m = (ok + ng) // 2
	while abs(ng - ok) > 1:
		co = 0
		j = len(C) - 1
		for i in range(len(B)):
			while j >= 0 and B[i] * C[j] > m:
				j -= 1
			co += j + 1
		if co >= k:
			ok = m
		else:
			ng = m
		m = (ok + ng) // 2
	print(ok)
else:
	k -= minus * zplus
	ok = 10 ** 20
	ng = -1
	m = (ok + ng) // 2
	while abs(ng - ok) > 1:
		co = 0
		j = len(C) - 1
		for i in range(len(C)):
			while j > i and C[i] * C[j] <= m:
				j -= 1
			co += len(C) - 1 - j
			j = max(j, i + 1)
		j = len(B) - 1
		for i in range(len(B)):
			while j > i and B[i] * B[j] <= m:
				j -= 1
			co += len(B) - 1 - j
			j = max(j, i + 1)
		if co >= k:
			ok = m
		else:
			ng = m
		m = (ok + ng) // 2
	print(ok)


def main():
	(n, k) = map(int, input().split())
	A = list(map(int, input().split()))
	Neg = [-a for a in A if a < 0]
	Pos = [a for a in A if a >= 0]
	Neg.sort()
	Pos.sort()
	(ln, lp) = (len(Neg), len(Pos))

	def cnt(x):
		ret = 0
		if x < 0:
			x = -x
			pos_idx = 0
			for num in Neg[::-1]:
				while pos_idx < lp and Pos[pos_idx] * num < x:
					pos_idx += 1
				ret += lp - pos_idx
				if pos_idx == lp:
					break
			return ret
		idx = 0
		for num in Neg[::-1]:
			if num ** 2 <= x:
				ret -= 1
			while idx < ln and Neg[idx] * num <= x:
				idx += 1
			ret += idx
		idx = 0
		for num in Pos[::-1]:
			if num ** 2 <= x:
				ret -= 1
			while idx < lp and Pos[idx] * num <= x:
				idx += 1
			ret += idx
		ret //= 2
		ret += ln * lp
		return ret
	(l, r) = (-(10 ** 18 + 1), 10 ** 18 + 1)
	while r - l > 1:
		m = (l + r) // 2
		if cnt(m) < k:
			l = m
		else:
			r = m
	print(r)
main()


def main():
	import numpy as np
	from bisect import bisect_left, bisect_right
	(N, K) = map(int, input().split())
	A = list(map(int, input().split()))
	A.sort()
	n = bisect_left(A, 0)
	p = bisect_right(A, 0)
	Negative = np.array(A[:n], dtype=np.int64)
	Positive = np.array(A[p:], dtype=np.int64)
	Number_Negative = len(Negative) * len(Positive)
	Number_Positive = len(Negative) * (len(Negative) - 1) // 2 + len(Positive) * (len(Positive) - 1) // 2
	Number_Zero = N * (N - 1) // 2 - Number_Negative - Number_Positive

	def Ncount(x):
		tmp = 0
		for a in Negative:
			tmp += len(Positive) - bisect_left(Positive, (x + a + 1) // a)
		return tmp

	def Ncount1(x):
		tmp = (len(Positive) - np.searchsorted(Positive, (-x - 1) // -Negative, side='right')).sum()
		return tmp

	def Pcount(x):
		tmp = 0
		for (index, a) in enumerate(Positive):
			tmp += bisect_right(Positive[index + 1:], x // a)
		for (index, b) in enumerate(Negative):
			tmp += len(Negative[index + 1:]) - bisect_left(Negative[index + 1:], (x + b + 1) // b)
		return tmp

	def Pcount1(x):
		tmp = 0
		tmp += np.searchsorted(Positive, x // Positive, side='right').sum()
		tmp += (len(Negative) - np.searchsorted(Negative, (-x - 1) // -Negative, side='rigth')).sum()
		tmp -= np.count_nonzero(Positive * Positive <= x)
		tmp -= np.count_nonzero(Negative * Negative <= x)
		return tmp // 2
	if Number_Negative >= K:
		l = -10 ** 18
		r = 0
		while r - l > 1:
			mid = (l + r) // 2
			if K <= Ncount1(mid):
				r = mid
			else:
				l = mid
		print(r)
		return
	elif Number_Negative < K <= Number_Negative + Number_Zero:
		print(0)
		return
	else:
		l = 0
		r = 10 ** 18
		K -= Number_Negative + Number_Zero
		while r - l > 1:
			mid = (l + r) // 2
			if K <= Pcount1(mid):
				r = mid
			else:
				l = mid
		print(r)

def __starting_point():
	main()
__starting_point()


import sys
input = sys.stdin.readline
from bisect import bisect_left, bisect_right
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
A.sort()
neg = bisect_left(A, 0)
pos = bisect_right(A, 0)

def less(x):
	res = 0
	b = 0
	for i in range(0, neg):
		while b != N and A[i] * A[b] >= x:
			b += 1
		while b != 0 and A[i] * A[b - 1] < x:
			b -= 1
		res += max(i - b, 0)
	for i in range(neg, pos):
		if x > 0:
			res += i
	for i in range(pos, N):
		while b != N and A[i] * A[b] < x:
			b += 1
		while b != 0 and A[i] * A[b - 1] >= x:
			b -= 1
		res += min(b, i)
	return res
l = -(10 ** 18 + 1)
r = -l
while l + 1 < r:
	m = (l + r) // 2
	if less(m) < K:
		l = m
	else:
		r = m
print(l)


import sys
import numpy as np
TEST_INPUT = ['\n    4 3\n    3 3 -4 -2\n    ', '\n    10 40\n    5 4 3 2 -1 0 0 0 0 0\n    ', '\n    30 413\n    -170202098 -268409015 537203564 983211703 21608710 -443999067 -937727165 -97596546 -372334013 398994917 -972141167 798607104 -949068442 -959948616 37909651 0 886627544 -20098238 0 -948955241 0 -214720580 277222296 -18897162 834475626 0 -425610555 110117526 663621752 0\n    ']
ANSWER = ['-6', '6', '448283280358331064']

class InputHandler:

	def __init__(self, text_lines='', is_test=False):
		self.data = list(text_lines.split('\n'))
		self.index = 0
		self.is_test = is_test

	def input(self):
		if self.is_test:
			self.index += 1
			return self.data[self.index].strip()
		else:
			return sys.stdin.readline().rstrip()

def query(a, n, a_arr_p, a_arr_n, n_zeros, k):
	if a >= 0:
		res = len(a_arr_p) * len(a_arr_n)
		res += n_zeros * (n - n_zeros) + n_zeros * (n_zeros - 1) // 2
		res_pp = np.searchsorted(a_arr_p, a // a_arr_p, side='right').sum()
		res_pp -= (a_arr_p * a_arr_p <= a).sum()
		res += res_pp // 2
		res_nn = np.searchsorted(a_arr_n, a // a_arr_n, side='right').sum()
		res_nn -= (a_arr_n * a_arr_n <= a).sum()
		res += res_nn // 2
	else:
		res = len(a_arr_p) * len(a_arr_n) - np.searchsorted(a_arr_n, (a_arr_p - a - 1) // a_arr_p, side='left').sum()
	if res >= k:
		return True
	else:
		return False

def solve(n, k, a_list):
	left = -10 ** 18 - 1
	right = 10 ** 18 + 1
	center = 0
	a_arr = np.array(a_list)
	a_arr_p = a_arr[a_arr > 0]
	a_arr_n = -a_arr[a_arr < 0]
	n_zeros = (a_arr == 0).sum()
	a_arr_p.sort()
	a_arr_n.sort()
	while left < right:
		center = (left + right) // 2
		if query(center, n, a_arr_p, a_arr_n, n_zeros, k):
			right = center
		else:
			left = center + 1
	return right

def input_and_solve(ih):
	(n, k) = list(map(int, ih.input().split()))
	a_list = list(map(int, ih.input().split()))
	res = solve(n, k, a_list)
	return res

def main():
	ih = InputHandler()
	res = input_and_solve(ih)
	print(res)

def test():
	for (test_input, ans) in zip(TEST_INPUT, ANSWER):
		ih = InputHandler(test_input, True)
		res = input_and_solve(ih)
		assert str(res) == str(ans)

def __starting_point():
	main()
__starting_point()


from numpy import *
(N, K) = map(int, input().split())
A = array(sorted(list(map(int, input().split()))))
nega = A[A < 0]
zera = A[A == 0]
posa = A[0 < A]

def cnt(x):
	y = 0
	if x >= 0:
		y += N * len(zera)
	y += searchsorted(A, x // posa, side='right').sum()
	y += N * len(nega) - searchsorted(A, -(-x // nega)).sum()
	y -= len(A[A * A <= x])
	return y // 2
r = 10 ** 18
l = -r - 1
while r - l > 1:
	c = (r + l) // 2
	if K <= cnt(c):
		r = c
	else:
		l = c
print(r)


import bisect
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
N = []
Z = []
P = []
for i in range(n):
	if a[i] < 0:
		N.append(a[i])
	elif a[i] == 0:
		Z.append(a[i])
	else:
		P.append(a[i])
if k <= len(N) * len(P):
	for i in range(len(N)):
		N[i] *= -1
	N.sort()
	P.sort()
	Nr = list(reversed(N))
	L = 0
	R = 10 ** 18 + 1
	while R - L > 1:
		x = (L + R) // 2
		ct = 0
		ct2 = 0
		for j in range(len(Nr)):
			if ct2 != len(P):
				while Nr[j] * P[ct2] < x:
					ct2 += 1
					if ct2 == len(P):
						break
			ct += len(P) - ct2
		if ct < k:
			R = x
		else:
			L = x
	print(-L)
elif k <= len(N) * len(P) + len(Z) * (len(Z) - 1) // 2 + len(Z) * (len(N) + len(P)):
	print(0)
else:
	y = len(N) * len(P) + len(Z) * (len(Z) - 1) // 2 + len(Z) * (len(N) + len(P))
	for i in range(len(N)):
		N[i] *= -1
	N.sort()
	P.sort()
	L = 0
	R = 10 ** 18 + 1
	Nr = list(reversed(N))
	Pr = list(reversed(P))
	while R - L > 1:
		x = (L + R) // 2
		ct = 0
		ct2 = 0
		for j in range(len(Nr)):
			if ct2 != len(N):
				while Nr[j] * N[ct2] <= x:
					ct2 += 1
					if ct2 == len(N):
						break
			ct += min(ct2, len(N) - 1 - j)
		ct3 = 0
		for j in range(len(Pr)):
			if ct3 != len(P):
				while Pr[j] * P[ct3] <= x:
					ct3 += 1
					if ct3 == len(P):
						break
			ct += min(ct3, len(P) - 1 - j)
		if ct < k - y:
			L = x
		else:
			R = x
	print(R)


def resolve():

	def counts(x):
		ans = 0
		if x < 0:
			x = -x
			r = 0
			for mi in minus[::-1]:
				while r < len(plus) and plus[r] * mi < x:
					r += 1
				ans += len(plus) - r
			return ans
		r = 0
		for l in minus[::-1]:
			if l * l <= x:
				ans -= 1
			while r < len(minus) and minus[r] * l <= x:
				r += 1
			ans += r
		r = 0
		for l in plus[::-1]:
			if l * l <= x:
				ans -= 1
			while r < len(plus) and plus[r] * l <= x:
				r += 1
			ans += r
		ans //= 2
		ans += len(minus) * len(plus)
		return ans
	(N, K) = map(int, input().split())
	A = list(map(int, input().split()))
	minus = [-x for x in A if x < 0]
	plus = [x for x in A if x >= 0]
	minus.sort()
	plus.sort()
	low = -10 ** 18 - 1
	high = 10 ** 18 + 1
	while high - low > 1:
		mid = (high + low) // 2
		if counts(mid) < K:
			low = mid
		else:
			high = mid
	print(high)
resolve()


import bisect
import numpy as npy
(n, k) = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
(n0, np, nn) = (0, 0, 0)
for i in a:
	if i > 0:
		np += 1
	elif i == 0:
		n0 += 1
	else:
		nn += 1
kp = (np ** 2 - np + nn ** 2 - nn) // 2
k0 = n0 * (n - n0) + (n0 ** 2 - n0) // 2
kn = nn * np
if kn < k <= kn + k0:
	print(0)
	return
nls = []
pls = []
for i in range(n):
	if a[i] < 0:
		nls.append(a[i])
	elif a[i] > 0:
		pls.append(a[i])
ln = len(nls)
lp = len(pls)
nls = npy.array(nls, dtype=npy.int64)
pls = npy.array(pls, dtype=npy.int64)
if k <= kn:
	l = a[0] * a[-1] - 1
	r = 0
	while l + 1 < r:
		m = (l + r) // 2
		mls = m // nls
		tmp = npy.searchsorted(pls, mls, side='right').sum()
		if tmp > kn - k:
			l = m
		else:
			r = m
	print(l)
else:
	nls = -nls
	nls = nls[::-1]
	k -= kn + k0
	l = 0
	r = max(a[0] ** 2, a[-1] ** 2) + 1
	while l + 1 < r:
		m = (l + r) // 2
		tmp = npy.searchsorted(nls, m // nls, side='right').sum()
		tmp += npy.searchsorted(pls, m // pls, side='right').sum()
		tmp -= npy.searchsorted(nls ** 2, m, side='left')
		tmp -= npy.searchsorted(pls ** 2, m, side='left')
		if tmp >= 2 * k:
			r = m
		else:
			l = m
	print(r)


import numpy as np
(n, k) = list(map(int, input().split()))
A = np.array(input().split(), np.int64)
A.sort()
posA = A[A > 0]
negA = A[A < 0]
zeros = (A == 0).sum()
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	num = (left + right) // 2
	less_count = 0
	if num >= 0:
		less_count += zeros * n
	limit_pair_for_pos = num // posA
	limit_idxs = np.searchsorted(A, limit_pair_for_pos, side='right')
	less_count += limit_idxs.sum()
	limit_pair_for_neg = -(num // -negA)
	limit_idxs = n - np.searchsorted(A, limit_pair_for_neg, side='left')
	less_count += limit_idxs.sum()
	duplicate_cases = (A ** 2 <= num).sum()
	less_count -= duplicate_cases
	less_count //= 2
	if less_count >= k:
		right = num
	else:
		left = num
print(right)


(N, K) = map(int, input().split())
A_s = list(map(int, input().split()))
minus = [-x for x in A_s if x < 0]
plus = [x for x in A_s if x >= 0]
minus.sort()
plus.sort()

def cnt(x):
	ans = 0
	if x < 0:
		r = 0
		x = -x
		for num in minus[::-1]:
			while r < len(plus) and plus[r] * num < x:
				r += 1
			ans += len(plus) - r
		return ans
	r = 0
	for num in minus[::-1]:
		if num * num <= x:
			ans -= 1
		while r < len(minus) and minus[r] * num <= x:
			r += 1
		ans += r
	r = 0
	for num in plus[::-1]:
		if num * num <= x:
			ans -= 1
		while r < len(plus) and plus[r] * num <= x:
			r += 1
		ans += r
	ans //= 2
	ans += len(minus) * len(plus)
	return ans
top = 2 * 10 ** 18 + 2
bottom = 0
while top - bottom > 1:
	mid = (top + bottom) // 2
	if cnt(mid - 10 ** 18 - 1) < K:
		bottom = mid
	else:
		top = mid
print(int(top - 10 ** 18 - 1))


f = lambda : map(int, input().split())
(n, k) = f()
(lm, lp) = ([], [])
for i in f():
	if i < 0:
		lm.append(-i)
	else:
		lp.append(i)
lm.sort()
lp.sort()
cm = len(lm)
cp = len(lp)

def cnt(x):
	c = 0
	if x < 0:
		r = cp
		for i in lm:
			while r and i * lp[r - 1] >= -x:
				r -= 1
			c += cp - r
		return c
	r = cm
	for i in lm:
		while r and i * lm[r - 1] > x:
			r -= 1
		c += r
		if i * i <= x:
			c -= 1
	r = cp
	for i in lp:
		while r and i * lp[r - 1] > x:
			r -= 1
		c += r
		if i * i <= x:
			c -= 1
	return cm * cp + c // 2
INF = 10 ** 18 + 1
(l, r) = (-INF, INF)
while r - l > 1:
	m = l + r >> 1
	if cnt(m) < k:
		l = m
	else:
		r = m
print(r)


import numpy as np
(N, K) = list(map(int, input().split()))
A = np.array(list(map(int, input().split())))
A.sort()
posi = A[A > 0]
zero = A[A == 0]
nega = A[A < 0]

def check(x):
	count = 0
	if x >= 0:
		count += len(zero) * N
	count += np.searchsorted(A, x // posi, side='right').sum()
	count += (N - np.searchsorted(A, (-x - 1) // -nega, side='right')).sum()
	count -= np.count_nonzero(A * A <= x)
	return count // 2
low = -10 ** 18
high = 10 ** 18
while low + 1 < high:
	mid = (low + high) // 2
	if check(mid) < K:
		low = mid
	else:
		high = mid
print(high)


from bisect import *
from math import ceil
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
Ap = []
Am = []
for a in A:
	if a >= 0:
		Ap.append(a)
	elif a < 0:
		Am.append(a)
p = len(Ap)
m = len(Am)
Ap.sort()
Am.sort(reverse=True)
U = 10 ** 18
L = -10 ** 18
while U - L > 1:
	mid = (U + L) // 2
	cnt = 0
	if mid >= 0:
		cnt += p * m
		i = p
		t = 0
		for a in Ap:
			while i and Ap[i - 1] * a > mid:
				i -= 1
			t += i
			if a * a <= mid:
				t -= 1
		cnt += t // 2
		i = m
		t = 0
		for a in Am:
			while i and Am[i - 1] * a > mid:
				i -= 1
			t += i
			if a * a <= mid:
				t -= 1
		cnt += t // 2
	else:
		i = m
		for a in Ap:
			while i and Am[i - 1] * a <= mid:
				i -= 1
			cnt += m - i
	if cnt < K:
		L = mid
	else:
		U = mid
print(U)


def abc155_d():
	(n, k) = map(int, input().split())
	A = list(map(int, input().split()))
	A.sort()
	from bisect import bisect_left, bisect_right
	lower = -10 ** 18
	upper = 10 ** 18
	while upper - lower > 1:
		x = (upper + lower) // 2
		cnt = 0
		for i in range(n - 1):
			a = A[i]
			if a < 0:
				idx = bisect_left(A, (x + a + 1) // a)
				cnt += n - max(idx, i + 1)
			elif a > 0:
				idx = bisect_right(A, x // a)
				cnt += max(0, idx - i - 1)
			elif x >= 0:
				cnt += n - i - 1
			if cnt >= k:
				break
		if cnt >= k:
			upper = x
		else:
			lower = x
	print(upper)
abc155_d()


(N, K) = map(int, input().split())
A = sorted([int(a) for a in input().split()])
pos = 0
zer = 0
neg = 0
for a in A:
	if a > 0:
		pos += 1
	elif a < 0:
		neg += 1
	else:
		zer += 1
B = [a for a in A if a > 0]
C = [-a for a in A if a < 0][::-1]
b = len(B)
c = len(C)

def cnt(x):
	if x >= 0:
		re = pos * neg + zer * (pos + neg) + zer * (zer - 1) // 2
		j = b - 1
		for i in range(b):
			while j >= 0 and B[i] * B[j] > x:
				j -= 1
			re += max(j - i, 0)
		j = c - 1
		for i in range(c):
			while j >= 0 and C[i] * C[j] > x:
				j -= 1
			re += max(j - i, 0)
		return re
	re = 0
	j = 0
	y = -x
	for i in range(b)[::-1]:
		while j < c and B[i] * C[j] < y:
			j += 1
		re += c - j
	return re
(l, r) = (-(1 << 60), 1 << 60)
while r - l > 1:
	m = (l + r) // 2
	if cnt(m) >= K:
		r = m
	else:
		l = m
print(r)


(n, k) = map(int, input().split())
A = list(map(int, input().split()))
pos = []
neg = []
zeros = 0
for a in A:
	if a > 0:
		pos.append(a)
	elif a < 0:
		neg.append(a)
	else:
		zeros += 1
pos.sort()
neg.sort(reverse=True)
minus_pattern = len(pos) * len(neg)
zero_pattern = zeros * (len(pos) + len(neg)) + zeros * (zeros - 1) // 2
pos_length = len(pos)
neg_length = len(neg)
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	num = (left + right) // 2
	less_count = 0
	if num >= 0:
		pos_idx = pos_length - 1
		for p in pos:
			while pos_idx >= 0 and p * pos[pos_idx] > num:
				pos_idx -= 1
			less_count += pos_idx + 1
			if p ** 2 <= num:
				less_count -= 1
		neg_idx = neg_length - 1
		for m in neg:
			while neg_idx >= 0 and m * neg[neg_idx] > num:
				neg_idx -= 1
			less_count += neg_idx + 1
			if m ** 2 <= num:
				less_count -= 1
		less_count //= 2
		less_count += minus_pattern + zero_pattern
	elif num < 0:
		pos_idx = 0
		for m in neg[::-1]:
			while pos_idx < pos_length and m * pos[pos_idx] > num:
				pos_idx += 1
			less_count += pos_length - pos_idx
	if less_count >= k:
		right = num
	else:
		left = num
print(right)


from bisect import *
from collections import *
from fractions import gcd
from math import factorial
from itertools import *
from heapq import *
import copy
(N, K) = map(int, input().split())
A = list(map(int, input().split()))
minas = []
plus = []
zero = []
for a in A:
	if a < 0:
		minas.append(-a)
	else:
		plus.append(a)
minas.sort()
plus.sort()
st = -10 ** 18 - 1
ed = 10 ** 18 + 1
len_minas = len(minas)
len_plus = len(plus)
len_zero = len(zero)
zero1 = len_plus * len_minas
zero2 = len_zero * (len_minas + len_plus) + len_zero * (len_zero - 1) // 2
while ed - st > 1:
	mid = (st + ed) // 2
	if mid < 0:
		j = 0
		i = 0
		for m in range(len(minas) - 1, -1, -1):
			while i < len(plus) and plus[i] * minas[m] < -mid:
				i += 1
			j += len(plus) - i
	else:
		j = zero1
		i = len(minas) - 1
		for m in range(len(minas) - 1):
			while m < i and minas[i] * minas[m] > mid:
				i -= 1
			j += max(i - m, 0)
		i = len(plus) - 1
		for m in range(len(plus) - 1):
			while m < i and plus[i] * plus[m] > mid:
				i -= 1
			j += max(i - m, 0)
	if j < K:
		st = mid
	else:
		ed = mid
print(ed)


import numpy as np

def check(mid):
	cnt = 0
	if mid >= 0:
		cnt += len(zero) * N
	cnt += np.searchsorted(A, mid // pos, side='right').sum()
	cnt += (N - np.searchsorted(A, (-mid - 1) // -neg, side='right')).sum()
	cnt -= np.count_nonzero(A * A <= mid)
	return cnt // 2
(N, K) = map(int, input().split())
A = np.array(sorted(map(int, input().split())))
pos = A[A > 0]
zero = A[A == 0]
neg = A[A < 0]
high = 10 ** 18
low = -10 ** 18
while low + 1 < high:
	mid = (high + low) // 2
	if check(mid) >= K:
		high = mid
	else:
		low = mid
print(high)


(n, k) = map(int, input().split())
a = [int(x) for x in input().split()]
an = []
az = []
ap = []
for i in range(n):
	if a[i] < 0:
		an.append(a[i])
	elif a[i] == 0:
		az.append(a[i])
	else:
		ap.append(a[i])
an = sorted(an)
ap = sorted(ap)
an_rev = sorted(an, reverse=True)

def count(x):
	cnt = 0
	if x < 0:
		r = 0
		for t in ap:
			while r < len(an) and t * an[r] <= x:
				r += 1
			cnt += r
	elif x == 0:
		cnt += len(az) * (len(az) - 1) // 2 + len(az) * (n - len(az)) + len(ap) * len(an)
	else:
		r = 0
		for t in ap[::-1]:
			while r < len(ap) and t * ap[r] <= x:
				r += 1
			cnt += r
			if t * t <= x:
				cnt -= 1
		r = 0
		for t in an:
			while r < len(an) and t * an_rev[r] <= x:
				r += 1
			cnt += r
			if t * t <= x:
				cnt -= 1
		cnt //= 2
		cnt += len(az) * (len(az) - 1) // 2 + len(az) * (n - len(az)) + len(ap) * len(an)
	return cnt
bottom = -10 ** 18 - 1
top = 10 ** 18 + 1
while top - bottom > 1:
	mid = (top + bottom) // 2
	if count(mid) >= k:
		top = mid
	else:
		bottom = mid
print(top)


import numpy as np
(n, k) = map(int, input().split())
a = np.array(input().split(), np.int64)
a = np.sort(a)
zero = a[a == 0]
pos = a[a > 0]
neg = a[a < 0]

def f(x):
	cnt_tpl = 0
	if x >= 0:
		cnt_tpl += len(zero) * n
	cnt_tpl += np.searchsorted(a, x // pos, side='right').sum()
	cnt_tpl += (n - np.searchsorted(a, (-x - 1) // -neg, side='right')).sum()
	cnt_tpl -= np.count_nonzero(a * a <= x)
	assert cnt_tpl % 2 == 0
	return cnt_tpl // 2
left = -10 ** 18
right = 10 ** 18
while left + 1 < right:
	x = (left + right) // 2
	if f(x) >= k:
		right = x
	else:
		left = x
print(right)


import sys
input = sys.stdin.readline
(N, K) = map(int, input().split())
A = [int(i) for i in input().split()]
p = []
m = []
zero = 0
for i in range(N):
	if A[i] > 0:
		p.append(A[i])
	elif A[i] < 0:
		m.append(-A[i])
	else:
		zero += 1
p.sort()
m.sort()
(ng, ok) = (-10 ** 18 - 1, 10 ** 18 + 1)
while ok - ng > 1:
	mid = (ok + ng) // 2
	s = 0
	if mid < 0:
		j = 0
		for i in range(len(m) - 1, -1, -1):
			while j < len(p) and m[i] * p[j] < -mid:
				j += 1
			s += len(p) - j
	else:
		j = len(p) - 1
		for i in range(len(p)):
			while j >= 0 and p[i] * p[j] > mid:
				j -= 1
			s += max(0, j - i)
		j = len(m) - 1
		for i in range(len(m)):
			while j >= 0 and m[i] * m[j] > mid:
				j -= 1
			s += max(0, j - i)
		s += (len(p) + len(m)) * zero + len(p) * len(m) + zero * (zero - 1) // 2
	if s < K:
		ng = mid
	else:
		ok = mid
print(ok)


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

def main():
	import sys
	import numpy as np
	inf = 10 ** 18 + 1
	input = sys.stdin.readline
	(N, K) = list(map(int, input().split()))
	A = np.array(input().split(), dtype=np.int64)
	A.sort()
	zero = A[A == 0]
	pos = A[A > 0]
	neg = A[A < 0]

	def count(x):
		cnt = 0
		if x >= 0:
			cnt += zero.size * N
		cnt += np.searchsorted(a=A, v=x // pos, side='right').sum()
		cnt += (N - np.searchsorted(a=A, v=(-x - 1) // -neg, side='right')).sum()
		cnt -= (A * A <= x).sum()
		assert cnt % 2 == 0
		return cnt // 2
	ans = binary_search(ng=-inf, ok=inf, func=lambda x: count(x) >= K)
	print(ans)

def __starting_point():
	main()
__starting_point()