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

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


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

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


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


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


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


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