stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define ull unsigned long long

#define mp make_pair

typedef pair<int,int> pii;

ll a[200009];

ll n;ll k;

int main()

{

    scanf("%d%lld",&n,&k);

    for(int i=0;i<n;i++)scanf("%lld",&a[i]);

    sort(a,a+n);

    ll l=-1e18,r=1e18;

    ll answer;

    while(l<=r)

    {

        ll mid=(l+r)/2;ll cnt=0;

        for(int i=0;i<n;i++)

        {

            if(a[i]>0){

                cnt+=upper_bound(a,a+n,(long double)mid/a[i])-a;

            }

            else if(a[i]<0){

                cnt+=n-(lower_bound(a,a+n,(long double)mid/a[i])-a);

            }

            else if(mid>=0)cnt+=n;

            if(a[i]*a[i]<=mid)cnt--;

        }

        if(cnt>=k*2)answer=mid,r=mid-1;

        else l=mid+1;

    }

    cout<<answer<<endl;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1161470736216668x):
#include <iostream>

#include <cstdio>

#include <fstream>

#include <algorithm>

#include <cmath>

#include <deque>

#include <vector>

#include <queue>

#include <string>

#include <cstring>

#include <map>

#include <stack>

#include <set>

#include <sstream>

#define IOS ios_base::sync_with_stdio(0); cin.tie(0);

#define ll long long

#define INF 0x3f3f3f3f 

#define MEM(x,y) memset(x,y,sizeof(x))

#define int long long

#define rep(i , a , b) for(int i = a ; i <= b ; i ++)

#define P pair<int,int>

#define  sc(a) scanf("%lld",&a)

#define pf(a) printf("%lld ",a)

using namespace std;

int a[200005];

signed main()

{       

   int q,w;

    sc(q);

    sc(w);

    for (int i = 0; i < q; i++)

        sc(a[i]);

    sort(a, a + q);

    int  l1 = -1e18 - 10;

    int r1 = 1e18 + 10;

    while (r1-l1>1) {

        int mid1 = (l1 + r1) / 2;

        int temp = 0;

        for (int i = 0; i < q; i++)

        {

            if (a[i] < 0) {

                int l = i, r = q;

                while (r-l>1)

                {

                    int mid = (l + r) / 2;

                    if (a[i] * a[mid] <= mid1) r = mid;

                    else l = mid;

                }

                temp += q - r;

            }

            else {

                int l = i, r = q;

                while (r-l>1)

                {

                    int mid = (l + r) / 2;

                    if (a[i] * a[mid] <= mid1) l = mid;

                    else r = mid;

                }

                temp += l - i;

            }

        }

        if (temp < w) l1 = mid1;

        else r1 = mid1;

    }

    pf(r1);



}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define ull unsigned long long

#define mp make_pair

typedef pair<int,int> pii;

ll a[200009];

ll n;ll k;

int main()

{

    scanf("%d%lld",&n,&k);

    for(int i=0;i<n;i++)scanf("%lld",&a[i]);

    sort(a,a+n);

    ll l=-1e18,r=1e18;

    ll answer;

    while(l<=r)

    {

        ll mid=(l+r)/2;ll cnt=0;

        for(int i=0;i<n;i++)

        {

            if(a[i]>0){

                cnt+=upper_bound(a,a+n,(long double)mid/a[i])-a;

            }

            else if(a[i]<0){

                cnt+=n-(lower_bound(a,a+n,(long double)mid/a[i])-a);

            }

            else if(mid>=0)cnt+=n;

            if(a[i]*a[i]<=mid)cnt--;

        }

        if(cnt>=k*2)answer=mid,r=mid-1;

        else l=mid+1;

    }

    cout<<answer<<endl;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1076696564011423x):
#include<iostream>

#include<algorithm>

using namespace std;



const int N = 2e5+10;

long long int v[N];

long long int n, k;

long long int INF = 1e18+10;



long long int bb_p(long long int l, long long int r, long long int index, long long int query){

	if(l > r) return r;

	long long int mid = (l+r)/2ll;

	long long int value = v[mid] * v[index];

	if(value <= query) return bb_p(mid+1ll, r, index, query);

	else return bb_p(l, mid-1ll, index, query);

}



long long int bb_n(long long int l, long long int r, long long int index, long long int query){

	if(l > r) return l;

	long long int mid = (l+r)/2ll;

	long long int value = v[mid] * v[index];

	if(value <= query) return bb_n(l, mid-1ll, index, query);

	else return bb_n(mid+1ll, r, index, query);

}



bool check(long long int query){

	long long int ans = 0;

	for(long long int i=0; i < n-1ll; i++){

		if(v[i] >= 0ll) ans += bb_p(i+1ll, n-1ll, i, query) - i;

		else ans += n - bb_n(i+1ll, n-1ll, i, query);

	}

	return k <= ans;

}



long long int solve(long long int l, long long int r){

	if(l > r) return l;

	long long int query = (l+r)/2ll;

	if(check(query)) return solve(l, query-1ll);

	else return solve(query+1ll, r);

}





int main(){

	cin >> n >> k;

	for(long long int i=0; i < n; i++) cin >> v[i];

	sort(v, v+n);

	cout << solve(-INF, INF) << endl;

}
// Slower C++ solution:
//#include<bits/stdc++.h>

#include<string>

#include<cstring>

#include<iostream>

#include<cstdio>

#include<queue>

#include<algorithm>

#define IOS ios::sync_with_stdio(false);cin.tie(0)

#define ll long long

//#define ll unsigned long long

#define inf 0x3f3f3f3f

#define mod 1000000007

#define eps 1e-6

#define pi acos(-1)

#define mysetit set<ll>::iterator

#define mymsetit multiset<ll>::iterator

#define mymapit map<ll,ll>::iterator

#define all(x) (x).begin(),(x).end()

#define fi first

#define se second

#define lowbit(x) (x&(-x))

#define mp make_pair

#define pb push_back

#define si size()

#define E exp(1.0)

#define fixed cout.setf(ios::fixed)

#define fixeds(x) setprecision(x)

using namespace std;

inline ll read(){ll s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}

while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}

void put1(){puts("YES");}void put2(){puts("NO");}void put3(){puts("-1"); }

ll qpf(ll a,ll b,ll p){ll ret=0;while(b){if(b&1)ret=(ret+a)%p;a=(a+a)%p;b>>=1;}return ret%p;}

ll qp(ll a,ll n,ll p){ll ret=1;while(n){if(n&1)ret=qpf(ret,a,p);a=qpf(a,a,p);n>>=1;}return ret%p;}

using namespace std;

const int manx=1e6+5;



ll a[manx];

int main(){

    ll n=read(),k=read();

    for(int i=1;i<=n;i++) a[i]=read();

    sort(a+1,a+1+n);

    ll L=-1e18,R=1e18;

    while(L+1!=R){  //这里枚举的就是答案

        ll M=(L+R)/2,cnt=0;

        for(int i=1;i<=n;i++){

            ll l=i,r=n+1;

            if(a[i]<0){

                while(l+1!=r){ //这里是二分下标

                    ll m=(l+r)/2;

                    if(a[i]*a[m]<=M) r=m;//因为a[i}<0所以向下枚举答案

                    else l=m;

                }

        //a[i]<0枚举答案所以要向下枚举 找到第一个不满足条件的

        //那么就有 n-r+1 个数 * a[i]<=M

                cnt+=n+1-r;

            }

            else{ //a[i]>0枚举答案所以要向上枚举

                while(l+1!=r){

                    ll m=(l+r)/2;

                    if(a[i]*a[m]<=M) l=m;

                    else r=m;

                }//找到第一个不满足条件  那么满足条件的就有l-i

                cnt+=l-i;

            }

        }

        if(cnt<k) L=M;

        else R=M;

    }

    printf("%lld",R);

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 4.734932223559264x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

using namespace std;

typedef long long ll;

ll N,K;

ll arr[1000010];

 

bool judge(ll x){

    ll cnt = 0;

    for(int i = 1;i<N;i++){

        if(arr[i]>=0){

            ll l = i+1,r = N,mid;

            if(arr[i]*arr[l]>=x) continue;//二分中无解的情况

            while(l<r){

                mid = (l+r+1)>>1;

                if(arr[i]*arr[mid] < x) l = mid;

                else r = mid-1;

            }

            cnt += l-i;

        }else{ //和负数乘会变号，情况和上面相反

            ll l = i+1,r = N,mid;

            if(arr[i]*arr[N] >= x) continue;//二分中无解的情况

            if(arr[i]*arr[l]<x){//特殊情况

                cnt += N-l+1;

                continue;

            }

            while(l<r){

                mid = (l+r+1)>>1;

                if(arr[i]*arr[mid] >= x) l = mid;

                else r = mid-1;

            }

            cnt += N-l;

        }

    }

    return cnt < K;

}

 

int main(){

    cin>>N>>K;

    for(int i = 1;i<=N;i++) scanf("%lld",&arr[i]);

    sort(arr+1,arr+N+1);

    ll l = -1e18-10,r = 1e18+10,mid;

    while(l<r){

        mid = (l+r+1)>>1;

        if(judge(mid)) l = mid;

        else r = mid-1;

    }

    cout<<l<<endl;

    return 0;



}

// Faster C++ solution for the same problem (measured speedup: 4.791355722879074x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}
// Slower C++ solution:
#include<iostream>

//#include<bits/stdc++.h>

#include<cstring>

#include<vector>

#include<string>

#include<stack>

#include<queue>

#include<cmath>

#include<cstdio>

#include<vector>

#include<set>

#include<map>

#include<algorithm>

using namespace std;

typedef long long ll;





const ll mod = 1e9;



vector<ll> q,p;



bool ok(ll x,ll n,ll k)

{

    ll ans = 0;

    sort(q.begin(),q.end(),greater<ll>());

    sort(p.begin(),p.end());

    int s1 = q.size(),s2 = p.size();

    for(int i = 0; i < s1; ++i)

    {

        int l = i,r = s1-1;

        while(l < r)

        {

            int mid = l + r +1 >>1;

            if(q[i]*q[mid] <= x) l = mid;

            else r = mid - 1;

        }

        if(l > i) ans += l -i ;

    }

    for(int i = 0; i < s2; ++i)

    {

        int l = i,r = s2 - 1;

        while(l < r)

        {

            int mid = l + r + 1 >> 1;

            if(p[i]*p[mid] <= x) l = mid;

            else r = mid - 1;

        }

        if(l > i) ans += l - i ;

    }

    if(ans >= k) return 1;

    reverse(q.begin(),q.end());

    reverse(p.begin(),p.end());

    for(int i = 0; i < s1; ++i)

    {

        int l = -1,r = s2-1;

        while(l < r)

        {

            int mid = l + r + 1>>1;

            if(q[i] * p[mid] <=  x) l = mid;

            else r = mid - 1;

        }

        if(l != -1) ans += l + 1;

    }

    return ans >= k;





}

int main()

{

    ll n,k,a;

    scanf("%lld%lld",&n,&k);



    for(int i = 1; i <= n; ++i)

    {

        scanf("%lld",&a);

        if(a<0) q.push_back(a);

        else  p.push_back(a);

    }

    ll l = - mod * mod ,r = mod *mod;

    while(l < r)

    {

        ll mid = l + r >>1;

        if(ok(mid,n,k)) r = mid;

        else l = mid + 1;

    }

    cout << r;

}








// Faster C++ solution for the same problem (measured speedup: 4.90236895835824x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}
// Slower C++ solution:
#include<iostream>

//#include<bits/stdc++.h>

#include<cstring>

#include<vector>

#include<string>

#include<stack>

#include<queue>

#include<cmath>

#include<cstdio>

#include<vector>

#include<set>

#include<map>

#include<algorithm>

using namespace std;

typedef long long ll;





const ll mod = 1e9;



vector<ll> q,p;



bool ok(ll x,ll n,ll k)

{

    ll ans = 0;

    sort(q.begin(),q.end(),greater<ll>());

    sort(p.begin(),p.end());

    int s1 = q.size(),s2 = p.size();

    for(int i = 0; i < s1; ++i)

    {

        int l = i,r = s1-1;

        while(l < r)

        {

            int mid = l + r +1 >>1;

            if(q[i]*q[mid] <= x) l = mid;

            else r = mid - 1;

        }

        if(l > i) ans += l -i ;

    }

    for(int i = 0; i < s2; ++i)

    {

        int l = i,r = s2 - 1;

        while(l < r)

        {

            int mid = l + r + 1 >> 1;

            if(p[i]*p[mid] <= x) l = mid;

            else r = mid - 1;

        }

        if(l > i) ans += l - i ;

    }

    if(ans >= k) return 1;

   // reverse(q.begin(),q.end());

    reverse(p.begin(),p.end());

    for(int i = 0; i < s1; ++i)

    {

        int l = -1,r = s2-1;

        while(l < r)

        {

            int mid = l + r + 1>>1;

            if(q[i] * p[mid] <=  x) l = mid;

            else r = mid - 1;

        }

        if(l != -1) ans += l + 1;

    }

    return ans >= k;





}

int main()

{

    ll n,k,a;

    scanf("%lld%lld",&n,&k);



    for(int i = 1; i <= n; ++i)

    {

        scanf("%lld",&a);

        if(a<0) q.push_back(a);

        else  p.push_back(a);

    }

    ll l = - mod * mod ,r = mod *mod;

    while(l < r)

    {

        ll mid = l + r >>1;

        if(ok(mid,n,k)) r = mid;

        else l = mid + 1;

    }

    cout << r;

}








// Faster C++ solution for the same problem (measured speedup: 4.884691095128116x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define ull unsigned long long

#define mp make_pair

typedef pair<int,int> pii;

ll a[200009];

ll n;ll k;

int main()

{

    scanf("%d%lld",&n,&k);

    for(int i=0;i<n;i++)scanf("%lld",&a[i]);

    sort(a,a+n);

    ll l=-1e18,r=1e18;

    ll answer;

    while(l<=r)

    {

        ll mid=(l+r)/2;ll cnt=0;

        for(int i=0;i<n;i++)

        {

            if(a[i]>0){

                cnt+=upper_bound(a,a+n,(long double)mid/a[i])-a;

            }

            else if(a[i]<0){

                cnt+=n-(lower_bound(a,a+n,(long double)mid/a[i])-a);

            }

            else if(mid>=0)cnt+=n;

            if(a[i]*a[i]<=mid)cnt--;

        }

        if(cnt>=k*2)answer=mid,r=mid-1;

        else l=mid+1;

    }

    cout<<answer<<endl;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 5.3493766719687805x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <algorithm>

#include <vector>

#define int long long

using namespace std;



int n, k;

vector<int > a[3];



int crank(int x) {

	if(!x) return a[0].size() * a[2].size() + 1;

	int ret = 1;

	vector<int > tmp;

	if(x > 0) {

		for(int i = 0; i < 3; i += 2) {

			for(auto j : a[i]) {

				ret += distance(tmp.begin(), lower_bound(tmp.begin(), tmp.end(), (x + j - 1) / j));

				tmp.push_back(j);

			}

			tmp.clear();

		}

		ret += (a[1].size() * (a[1].size() - 1)) / 2 + a[0].size() * a[2].size() + a[1].size() * (a[0].size() + a[2].size());

	}

	else for(auto i : a[0]) ret += a[2].size() - distance(a[2].begin(), upper_bound(a[2].begin(), a[2].end(), -x / i));

	return ret;

}



signed main() {

    cin >> n >> k;

    for(int i = 1; i <= n; ++i) {

        int x;

        cin >> x;

        if(x > 0) a[0].push_back(x);

        else if(!x) a[1].push_back(x);

        else a[2].push_back(-x);

    }

    for(int i = 0; i < 3; ++i)

        sort(a[i].begin(), a[i].end());

    int l = -1e18, r = 1e18, ans;

    while(l <= r) {

        int mid = (l + r) >> 1;

        int rk = crank(mid);

		if(rk <= k) ans = mid, l = mid + 1;

		else r = mid - 1;

    }

	cout << ans << endl;

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.990014991629193x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <fstream>

#include <algorithm>

#include <cmath>

#include <deque>

#include <vector>

#include <queue>

#include <string>

#include <cstring>

#include <map>

#include <stack>

#include <set>

#include <sstream>

#define IOS ios_base::sync_with_stdio(0); cin.tie(0);

#define ll long long

#define INF 0x3f3f3f3f 

#define MEM(x,y) memset(x,y,sizeof(x))

#define int long long

#define rep(i , a , b) for(int i = a ; i <= b ; i ++)

#define P pair<int,int>

#define  sc(a) scanf("%lld",&a)

#define pf(a) printf("%lld ",a)

using namespace std;

int a[200005];

signed main()

{       

   int q,w;

    sc(q);

    sc(w);

    for (int i = 0; i < q; i++)

        sc(a[i]);

    sort(a, a + q);

    int  l1 = -1e18 - 10;

    int r1 = 1e18 + 10;

    while (r1-l1>1) {

        int mid1 = (l1 + r1) / 2;

        int temp = 0;

        for (int i = 0; i < q; i++)

        {

            if (a[i] < 0) {

                int l = i, r = q;

                while (r-l>1)

                {

                    int mid = (l + r) / 2;

                    if (a[i] * a[mid] <= mid1) r = mid;

                    else l = mid;

                }

                temp += q - r;

            }

            else {

                int l = i, r = q;

                while (r-l>1)

                {

                    int mid = (l + r) / 2;

                    if (a[i] * a[mid] <= mid1) l = mid;

                    else r = mid;

                }

                temp += l - i;

            }

        }

        if (temp < w) l1 = mid1;

        else r1 = mid1;

    }

    pf(r1);



}


// Faster C++ solution for the same problem (measured speedup: 4.792716657502096x):
#include <cstdio>

#include <algorithm>

#define ll long long

using namespace std;

const ll inf=1e18+10;

ll n,k,ans,a[200005];

ll find1(int now,ll x){

	int l=now+1,r=n,best=now;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			l=mid+1;

			best=mid;

		}

		else r=mid-1;

	}

	return best;

}

ll find2(int now,ll x){

	int l=now+1,r=n,best=n+1;

	while(l<=r){

		int mid=l+r>>1;

		if(a[now]*a[mid]<=x){

			r=mid-1;

			best=mid;

		}

		else l=mid+1;

	}

	return best;

}

bool check(ll x){

	ll cnt=0;   //找比 x 小的积 

	for(int i=1;i<n;i++){

		if(a[i]>=0) cnt+=find1(i,x)-i;

		else cnt+=n-find2(i,x)+1;

	}

	return cnt>=k;

}

int main(){

	scanf("%lld%lld",&n,&k);

	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);

	sort(a+1,a+n+1);

	ll l=-inf,r=inf;

	while(l<=r){

		ll mid=l+r>>1;

		if(check(mid)){

			ans=mid;

			r=mid-1;

		}

		else l=mid+1;

	}

	printf("%lld",ans);

	return 0;

}