Buggy python submission (verdict: Time Limit Exceeded):
import bisect

def updiv(x,y):
    if x % y == 0:
        return x // y
    else:
        return x // y + 1

def wantA(m):

    ret = 0

    for l in L:

        if m % l == 0:
            B = m // l
        else:
            B = m // l + 1

        ret += len(R) - bisect.bisect_left(R,B)

        if ret >= K:
            return ret

    return ret

def wantB(m):

    ret = 0

    for i in range(len(R)):

        i = len(R) - 1 - i

        if R[i] == 0:
            ret += i
            continue

        if m % R[i] == 0:
            B = m // R[i]
        else:
            B = m // R[i]
 
        ret += min(i , bisect.bisect_right(R , B))

        if ret >= K:
            return ret

    
    for i in range(len(L2)):

        i = len(L2)-1-i

        if m % L2[i] == 0:
            B = m // L2[i]
        else:
            B = m // L2[i]
 
        ret += min(i , bisect.bisect_right(L2 , B))

        if ret >= K:
            return ret

    return ret
        

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

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

L = []
L2 = []
R = [] #0以上

for i in range(N):

    if A[i] < 0:
        L.append(A[i])
        L2.append(-1 * A[i])
    else:
        R.append(A[i])

L.sort()
R.sort()
L2.sort()

if K <= len(L) * len(R):

    l = L[0] * R[-1] - 1
    r = L[-1] * R[0] + 1

    while r - l != 1:

        m = (l+r) // 2

        num = wantA(m)

        if num >= K:
            r = m
        else:
            l = m

    print (r)

else:

    l = -1
    r = 1
    if len(R) > 0:
        r = max(r , R[-1] ** 2)
    if len(L2) > 0:
        r = max(r , L2[-1] ** 2)

    K -= len(L) * len(R)

    while r-l != 1:

        m = (l+r)//2

        num = wantB(m)
        #print (m , num)


        if num >= K:
            r = m
        else:
            l = m

        #print (l,r)

    print (r)


Fixed submission:

import sys

def wantA(m):

    ind = len(Pl)
    ret = 0

    for i in Mi:

        while ind > 0 and Pl[ind-1] * i > m:
            ind -= 1

        ret += ind

    return ret

def wantB(m):

    ans = 0
    ret = 0

    ind = len(Pl)

    for i in Pl:

        while ind > 0 and Pl[ind-1] * i > m:
            ind -= 1

        ret += ind

        if i ** 2 <= m:
            ret -= 1

    ans += ret // 2

    ret = 0

    ind = len(Mi)

    for i in Mi:

        while ind > 0 and Mi[ind-1] * i > m:
            ind -= 1

        ret += ind

        if i ** 2 <= m:
            ret -= 1

    ans += ret // 2

    return ans
   


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

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

Mi = []
znum = 0
Pl = []

for i in A:

    if i < 0:
        Mi.append(-1 * i)
    elif i == 0:
        znum += 1
    else:
        Pl.append(i)

Mi.sort()
Pl.sort()

if len(Mi) * len(Pl) >= K:

    #小さい方からMi*Pl-K+1番目を求める
    K = len(Mi) * len(Pl) - K + 1

    l = Mi[0] * Pl[0] - 1
    r = Mi[-1] * Pl[-1]

    while r - l != 1:

        m = (r + l) // 2

        num = wantA(m)

        if num >= K:
            r = m
        else:
            l = m

    print (-1 * r)
    sys.exit()


K -= len(Mi) * len(Pl)

K -= znum * (len(Pl) + len(Mi) ) + znum * (znum-1) // 2

if K <= 0:
    print (0)
    sys.exit()



#小さい方からK番目を求める

l = 0
r = 10 ** 18 + 1

while r - l != 1:

    m = (r + l) // 2

    num = wantB(m)

    #print (m,num)

    if num >= K:
        r = m
    else:
        l = m

print (r)

Buggy python submission (verdict: Time Limit Exceeded):
import bisect

def updiv(x,y):
    if x % y == 0:
        return x // y
    else:
        return x // y + 1

def wantA(m):

    ret = 0

    for l in L:

        if m % l == 0:
            B = m // l
        else:
            B = m // l + 1

        ret += len(R) - bisect.bisect_left(R,B)

        if ret >= K:
            return ret

    return ret

def wantB(m):

    ret = 0

    for i in range(len(R)):

        i = len(R) - 1 - i

        if R[i] == 0:
            ret += i
            continue

        if m % R[i] == 0:
            B = m // R[i]
        else:
            B = m // R[i]
 
        ret += min(i , bisect.bisect_right(R , B))

        if ret >= K:
            return ret

    
    for i in range(len(L2)):

        i = len(L2)-1-i

        if m % L2[i] == 0:
            B = m // L2[i]
        else:
            B = m // L2[i]
 
        ret += min(i , bisect.bisect_right(L2 , B))

        if ret >= K:
            return ret

    return ret
        

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

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

L = []
L2 = []
R = [] #0以上

for i in range(N):

    if A[i] < 0:
        L.append(A[i])
        L2.append(-1 * A[i])
    else:
        R.append(A[i])

L.sort()
R.sort()
L2.sort()

if K <= len(L) * len(R):

    l = L[0] * R[-1] - 1
    r = L[-1] * R[0] + 1

    while r - l != 1:

        m = (l+r) // 2

        num = wantA(m)

        if num >= K:
            r = m
        else:
            l = m

    print (r)

else:

    l = -1
    r = 1
    if len(R) > 0:
        r = max(r , R[-1] ** 2)
    if len(L2) > 0:
        r = max(r , L2[-1] ** 2)

    K -= len(L) * len(R)

    while r-l != 1:

        m = (l+r)//2

        num = wantB(m)
        #print (m , num)


        if num >= K:
            r = m
        else:
            l = m

        #print (l,r)

    print (r)

Fixed submission:

import sys

def wantA(m):

    ind = len(Pl)
    ret = 0

    for i in Mi:

        while ind > 0 and Pl[ind-1] * i > m:
            ind -= 1

        ret += ind

    return ret

def wantB(m):

    ans = 0
    ret = 0

    ind = len(Pl)

    for i in Pl:

        while ind > 0 and Pl[ind-1] * i > m:
            ind -= 1

        ret += ind

        if i ** 2 <= m:
            ret -= 1

    ans += ret // 2

    ret = 0

    ind = len(Mi)

    for i in Mi:

        while ind > 0 and Mi[ind-1] * i > m:
            ind -= 1

        ret += ind

        if i ** 2 <= m:
            ret -= 1

    ans += ret // 2

    return ans
   


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

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

Mi = []
znum = 0
Pl = []

for i in A:

    if i < 0:
        Mi.append(-1 * i)
    elif i == 0:
        znum += 1
    else:
        Pl.append(i)

Mi.sort()
Pl.sort()

if len(Mi) * len(Pl) >= K:

    #小さい方からMi*Pl-K+1番目を求める
    K = len(Mi) * len(Pl) - K + 1

    l = Mi[0] * Pl[0] - 1
    r = Mi[-1] * Pl[-1]

    while r - l != 1:

        m = (r + l) // 2

        num = wantA(m)

        if num >= K:
            r = m
        else:
            l = m

    print (-1 * r)
    sys.exit()


K -= len(Mi) * len(Pl)

K -= znum * (len(Pl) + len(Mi) ) + znum * (znum-1) // 2

if K <= 0:
    print (0)
    sys.exit()



#小さい方からK番目を求める

l = 0
r = 10 ** 18 + 1

while r - l != 1:

    m = (r + l) // 2

    num = wantB(m)

    #print (m,num)

    if num >= K:
        r = m
    else:
        l = m

print (r)

Buggy python submission (verdict: Time Limit Exceeded):
import bisect

def updiv(x,y):
    if x % y == 0:
        return x // y
    else:
        return x // y + 1

def wantA(m):

    ret = 0

    for l in L:

        if m % l == 0:
            B = m // l
        else:
            B = m // l + 1

        ret += len(R) - bisect.bisect_left(R,B)

        if ret >= K:
            return ret

    return ret

def wantB(m):

    ret = 0

    for i in range(len(R)):

        if R[i] == 0:
            ret += i
            continue

        if m % R[i] == 0:
            B = m // R[i]
        else:
            B = m // R[i]
 
        ret += min(i , bisect.bisect_right(R , B))

        if ret >= K:
            return ret

    
    for i in range(len(L2)):

        if m % L2[i] == 0:
            B = m // L2[i]
        else:
            B = m // L2[i]
 
        ret += min(i , bisect.bisect_right(L2 , B))

        if ret >= K:
            return ret

    return ret
        

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

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

L = []
L2 = []
R = [] #0以上

for i in range(N):

    if A[i] < 0:
        L.append(A[i])
        L2.append(-1 * A[i])
    else:
        R.append(A[i])

L.sort()
R.sort()
L2.sort()

if K <= len(L) * len(R):

    l = L[0] * R[-1] - 1
    r = L[-1] * R[0] + 1

    while r - l != 1:

        m = (l+r) // 2

        num = wantA(m)

        if num >= K:
            r = m
        else:
            l = m

    print (r)

else:

    l = -1
    r = 10 ** 18 + 1

    K -= len(L) * len(R)

    while r-l != 1:

        m = (l+r)//2

        num = wantB(m)
        #print (m , num)


        if num >= K:
            r = m
        else:
            l = m

        #print (l,r)

    print (r)

Fixed submission:

import sys

def wantA(m):

    ind = len(Pl)
    ret = 0

    for i in Mi:

        while ind > 0 and Pl[ind-1] * i > m:
            ind -= 1

        ret += ind

    return ret

def wantB(m):

    ans = 0
    ret = 0

    ind = len(Pl)

    for i in Pl:

        while ind > 0 and Pl[ind-1] * i > m:
            ind -= 1

        ret += ind

        if i ** 2 <= m:
            ret -= 1

    ans += ret // 2

    ret = 0

    ind = len(Mi)

    for i in Mi:

        while ind > 0 and Mi[ind-1] * i > m:
            ind -= 1

        ret += ind

        if i ** 2 <= m:
            ret -= 1

    ans += ret // 2

    return ans
   


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

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

Mi = []
znum = 0
Pl = []

for i in A:

    if i < 0:
        Mi.append(-1 * i)
    elif i == 0:
        znum += 1
    else:
        Pl.append(i)

Mi.sort()
Pl.sort()

if len(Mi) * len(Pl) >= K:

    #小さい方からMi*Pl-K+1番目を求める
    K = len(Mi) * len(Pl) - K + 1

    l = Mi[0] * Pl[0] - 1
    r = Mi[-1] * Pl[-1]

    while r - l != 1:

        m = (r + l) // 2

        num = wantA(m)

        if num >= K:
            r = m
        else:
            l = m

    print (-1 * r)
    sys.exit()


K -= len(Mi) * len(Pl)

K -= znum * (len(Pl) + len(Mi) ) + znum * (znum-1) // 2

if K <= 0:
    print (0)
    sys.exit()



#小さい方からK番目を求める

l = 0
r = 10 ** 18 + 1

while r - l != 1:

    m = (r + l) // 2

    num = wantB(m)

    #print (m,num)

    if num >= K:
        r = m
    else:
        l = m

print (r)