/*
Author: Racer5x
 ***************************************   UNAUTHORISED COPYING OF CODE PROHIBITED   **********************************
*/
 
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
 
#include<bits/stdc++.h>
#define int         long long
#define double      long double
#define pb          emplace_back
#define pf          emplace_front
#define pii         pair<int,int>
#define vi          vector<int>
#define vii         vector<pii>
#define mi          map<int,int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define rall(a)     (a).rbegin(),(a).rend()
#define x           first
#define y           second
#define endl        '\n'
#define hell        998244353 
#define PI          3.141592653589
#define tezz        ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define MAX         2000000000000000000
#define M           1000000007
using namespace std;

vi pos, neg, zero;
int n, k;

int check(int x){
    int k = 0;

    if(x >= 0){
        //getting positive from positive array itself
        int i = 0, j = pos.size() - 1; // 2 pointer to find numbers less than x

        while(i < j){
            if(pos[i] * pos[j] <= x){
                k += j - i;
                i++;
            }
            else j--;
        }

        //for zeroes
        k += zero.size() * pos.size() + zero.size() * neg.size() + (zero.size() * (zero.size() - 1))/2;

        //getting positive from negative and negative
        i = 0, j = neg.size() - 1;
        
        while(i < j){
            if(neg[i] * neg[j] <= x){
                k += j - i;
                j--;
            }
            else i++;
        }

        //all negative
        k += pos.size() * neg.size();
    }
    else{
        //getting it from positive and negative
        int i = 0, j = 0;

        while(i < neg.size() && j < pos.size()){
            if(neg[i] * pos[j] <= x){
                k += pos.size() - j;
                i++;
            }
            else j++;
        }

        // for(int i=0;i<neg.size();i++){
        //     int lo = 0, hi = pos.size() - 1;
        //     int ans = -1;

        //     while(lo <= hi){
        //         int mid = lo + (hi - lo)/2;

        //         if(neg[i] * pos[mid] <= x){
        //             ans = max(ans, mid);
        //             lo = mid + 1;
        //         }
        //         else hi = mid - 1;
        //     }

        //     k += ans;
        // }
    }

  return k;
}
 
signed main()
{
    tezz

    cin>>n>>k;

    for(int i=0;i<n;i++){
        int x;
        cin>>x;

        if(x > 0) pos.pb(x);
        else if(x < 0) neg.pb(x);
        else zero.pb(x);
    }
    sort(all(neg));
    sort(all(pos));

    //binary searching for such x, which is the kth element
    int hi = MAX, lo = -MAX;
    int ans = MAX;

    while(lo <= hi){
        int mid = lo + (hi - lo)/2;

        // cout<<mid<<" --> "<<check(mid)<<endl;

        if(check(mid) < k){
            lo = mid + 1;
        }
        else{
            ans = min(ans,  mid);
            hi = mid - 1;
        }
    }

    cout<<ans;
} 

Measured memory_bytes: 2548