#include <bits/stdc++.h>
using namespace std;
#define INF 1145141919810893364
//INFはすくなくとも10^18は必要

int main(void){
    long long N,K,a;
    vector<long long> A;
    cin >> N >> K;
    for(int i=0;i<N;i++){
        cin >> a;
        A.push_back(a);
    }
    
    //まず、Aの要素を正、負、０に分ける
    vector<long long> Posi,Nega,Zero;
    for(int i=0;i<N;i++){
        if(A[i]>0){
            Posi.push_back(A[i]);
        }else if(A[i]<0){
            Nega.push_back(A[i]);
        }else{
            Zero.push_back(A[i]);
            //Zeroの要素は0のみなのであえてvectorで持つ必要はないが、あえてこうする
        }
    }
    
    //二分探索のイメージがしやすくなるよう、Negaの要素を正にしておく
    for(int i=0;i<Nega.size();i++){
        Nega[i]*=-1;
    }
    
    
    //二分探索できるよう、ソートしておく
    sort(Posi.begin(),Posi.end());
    sort(Nega.begin(),Nega.end());
    
    //次に、N(N-1)/2個ある積のうち、正であるものの個数を求める
    //負であるもの、０であるものも同様に求める
    
    //積が正になるもの：ともに正かともに負
    //積が負になるもの：正と負の組み合わせ
    //積が０になるもの　どちらかが０
    
    long long P_posi=0,P_nega=0,P_zero=0;
    P_posi += (Posi.size())*(Posi.size()-1)/2;
    P_posi += (Nega.size())*(Nega.size()-1)/2;
    
    P_nega += (Posi.size())*(Nega.size());
    
    P_zero += (Zero.size())*(Zero.size()-1)/2;
    P_zero += (Zero.size())*(Posi.size());
    P_zero += (Zero.size())*(Nega.size());
    
    //P_posi,nega,zeroの情報から、K番目の値が正負０のどれであるかを特定することができる
    //K<=P_negaなら答えは負、K<=P_nega+P_zeroなら答えは０、それ以上なら正
    int sign;
    if(K<=P_nega){
        sign=-1;
    }else if(K<=P_nega+P_zero){
        sign=0;
    }else{
        sign=1;
    }
    //signの値によって処理が微妙に異なる
    
    //sign=0の場合　解は必ず０
    if(sign==0){
        cout << 0 << endl;
        return 0;
    }
    
    //sign=-1の場合　解は負
    if(sign==-1){
        long long l=-INF,r=-1,mid;
        while(abs(r-l)>1){
            mid=(l+r)/2;
            //midより同じか小さい数はいくつ？？
            //midより同じか小さい数はmidより絶対値が真に大きい数
            //なのでまずは絶対値が同じか小さい数を数え、総数から引きます
            long long num=0;
            for(int i=0;i<Nega.size();i++){
                auto it=std::upper_bound(Posi.begin(), Posi.end(), -mid/Nega[i]);
                num+=it-Posi.begin();
            }
            num=P_nega-num;
            
            //midより同じか小さい数がK個より少なかったらmidが小さすぎる
            if(num<K){
                l=mid;
            }else{
                r=mid;
            }
            
        }
        cout << l << endl;
        return 0;
    }
    
    
    //sign=1の場合　解は正
    if(sign==1){
        long long l=1,r=INF,mid;
        while(abs(r-l)>1){
            mid=(l+r)/2;
            //基本的には負の場合と同様の処理をする
            //しかし、正の場合はPosi*Posi,Nega*Negaなので重複をケアする必要がある
            //以下のように処理することでケアができる(図解すると理解が早い)
            //また総数から引くことなく、midと同じか小さい数を直接求められる
            long long num=0;
            for(int i=0;i<Posi.size();i++){
                auto it = std::upper_bound(Posi.begin(), Posi.end(), mid/Posi[i]);
                long long temp=(it-Posi.begin());
                num+=max(0ll,temp-i-1);
            }
            for(int i=0;i<Nega.size();i++){
                auto it = std::upper_bound(Nega.begin(), Nega.end(), mid/Nega[i]);
                long long temp=(it-Nega.begin());
                num+=max(0ll,temp-i-1);
            }
            
            //midより同じか小さい数(負、０も含む)がK個より少なかったらmidが小さすぎる
            if(P_nega+P_zero+num<K){
                l=mid;
            }else{
                r=mid;
            }
            
        }
        cout << r << endl;
        return 0;
        
    }
    
    return 0;
}



Measured memory_bytes: 5232