#include <bits/stdc++.h>
using namespace std;
typedef long long ll;


ll count_neg(vector<ll>&neg, vector<ll> &pos, ll x){
    //x以下の組み合わせを数え上げる
    ll cnt = 0;
    for (const auto&val : pos){
        ll ng = -1;
        ll ok = neg.size();
        auto isOK = [&](ll mid) { return val *neg[mid] > x; };
        while (abs(ok - ng) > 1) {
            ll mid = (ok + ng) / 2;
            if (isOK(mid)) ok = mid;
            else ng = mid;
        }
        cnt+= ng+1;
    }    
    return cnt;
}


void negative_routine(vector<ll> &neg,vector<ll> &pos,ll K ){
    ll right = 0;
    ll left = neg.front() * pos.back()-1;
    while(left+1<right){
        ll cand = (left+right)/2;
        ll ret = count_neg(neg,pos,cand);
        //cand以下の個数がK個より大きければ　
        if (ret>=K){
            right = cand;
        }else {
            left = cand;
        }
    }
    // x 以下の組み合わせがK個以上である　を始めてみたすxがright
    // x 以下の組み合わせが1個以上であるを　初めて満たすのは -12 
    printf("%lld\n",right);
}

ll count_pos(vector<ll>&neg, vector<ll> &pos, ll x){
    //x以下のものをカウントする
    ll cnt = 0;
    for (const auto&val : pos){
        //ng側に val*pos <= xを集めたい
        ll ng = -1;
        ll ok = pos.size();
        auto isOK = [&](ll key) { return val *pos[key] > x; };
        while (abs(ok - ng) > 1) {
            ll mid = (ok + ng) / 2;
            if (isOK(mid)) ok = mid;
            else ng = mid;
        }
        if (ng >=0 &&pos[ng]>=val) cnt -=1; 
        cnt+= ng+1;
    }    

    for (const auto&val :neg){
        ll ng = -1;
        ll ok = neg.size();
        auto isOK = [&](ll key) { return val *neg[key] <= x; };
        while (abs(ok - ng) > 1) {
            ll mid = (ok + ng) / 2;
            if (isOK(mid)) ok = mid;
            else ng = mid;
        }
        if (ok<neg.size() && neg[ok]<=val) cnt-=1;
        //okなものが存在して、val以下のモノがあったら重複が出ている　-3, -2, -1のならびで neg[ok]が-2 valが-1ならと考えると
        // ok は -2,-1で -1 含んでおり neg[ok]<= val = -1
        cnt+= neg.size()-ok;
    }
    return cnt/2;
}



void positive_routine(vector<ll>&neg, vector<ll> &pos,ll K){
    ll cand2 = (neg.size()>0) ? neg.front()*neg.front()+1 :1;
    ll cand1 = (pos.size()>0) ? pos.back() * pos.back()+1 :1;
    ll right = max(cand1, cand2);
    ll left = 0;
    while(left+1<right){
        ll cand = (left+right)/2;
        ll ret = count_pos(neg,pos,cand);
        if (ret>=K){
            right = cand;
        }else {
            left = cand;
        }
    }
    printf("%lld\n",right);
}



// Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
int main(){
    ll N,K;
    cin >> N >> K;

    vector<int> A(N);
    for (int i=0;i<N;i++){
        scanf("%d",&A[i]);
    }
    sort(A.begin(),A.end());
    vector<ll> neg;
    vector<ll> zeros;
    vector<ll> pos;
    for (const auto &val: A){
        if (val<0) neg.push_back(val);
        else if (val == 0) zeros.push_back(0);
        else pos.push_back(val);
    }
    ll negative_count = neg.size() * pos.size();
    ll zero_count = zeros.size() * (N-zeros.size()) + (zeros.size()-1)*zeros.size()/2;
    if (K<=negative_count){
        negative_routine(neg,pos,K);
    }else if(K<=negative_count+zero_count){
        printf("0\n");
    }else{
        positive_routine(neg,pos,K-negative_count-zero_count);
    }

    return 0;
}


Measured memory_bytes: 3572