#include "bits/stdc++.h"
using namespace std;

// GNU C Compiler
//template<class T> inline string toString(T x) { ostringstream sout; sout << x; return sout.str(); }


/*
--------------------------------------------

	type

--------------------------------------------
*/
using ll = int_fast64_t;
using LL = long long;
using ULL = unsigned long long;
using PII = pair<int, int>;
//using pair<T1, T2> = p12;

/*
--------------------------------------------

	container

--------------------------------------------
*/
#define PB emplace_back
#define MP make_pair 
#define SZ(a) int((a).size())
#define ALL(v) v.begin(),v.end()

/*
--------------------------------------------

	repetition

--------------------------------------------
*/
#define REP(n) for(int i=0; i<n; i++)
#define REPj(n) for(int j=0; j<n; j++)
#define REPinit(a,n) for(int i=a; i<n; i++)
#define REPinitj(a,n) for(int j=a; j<n; j++)

//algorithm
//#define SORT(c) sort((c).begin(),(c).end())

/*
--------------------------------------------

	constant

--------------------------------------------
*/
//clear memory
#define CLR(a) memset((a), 0 ,sizeof(a))

/*
--------------------------------------------

	Optimizer

--------------------------------------------
*/
//#pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

/*
--------------------------------------------
 
	Utility Algorithm

-------------------------------------------- 
*/

template <typename T>
void swapAlgorithm(T& a, T& b) {
    T tmp = a;
    a = b;
    b = tmp;
}
 
template <typename T1>
T1 euclideanAlgorithm(T1 a, T1 b) {
    T1 a_tmp = a;
    T1 b_tmp = b;
 
    if (a_tmp > b_tmp) {
        swapAlgorithm<T1>(a_tmp, b_tmp);
    }
 
    T1 r = a_tmp % b_tmp;
    while (r != 0) {
        a_tmp = b_tmp;
        b_tmp = r;
        r = a_tmp % b_tmp;
    }
    return b_tmp;    
}

template <typename T2>
T2 getLCM(T2 a, T2 b) {
    return (a * b)/(euclideanAlgorithm(a, b));
}

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template <std::uint_fast64_t Modulus> class modint {
  using u64 = std::uint_fast64_t;

public:
  u64 a;

  constexpr modint(const u64 x = 0) noexcept : a(x % Modulus) {}
  constexpr u64 &value() noexcept { return a; }
  constexpr const u64 &value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint &operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if (a >= Modulus) {
      a -= Modulus;
    }
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if (a < rhs.a) {
      a += Modulus;
    }
    a -= rhs.a;
    return *this;
  }
  constexpr modint &operator*=(const modint rhs) noexcept {
    a = a * rhs.a % Modulus;
    return *this;
  }
  constexpr modint &operator/=(modint rhs) noexcept {
    u64 exp = Modulus - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

void binsearch(ll& ok,ll& ng, function<bool(ll)>f){
  while(abs(ok-ng)>1){ ll m=(ok+ng)/2; if (f(m))ok=m; else ng=m;}
}

int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ll N,K;
    cin >> N >> K;

    ll ok=-1000000000000000001LL;
    ll ng=1000000000000000001LL;

    vector<ll> A(N);
    for(ll i=0; i<N; i++) cin >> A[i];

    sort(ALL(A));

    // reference
    // https://atcoder.jp/contests/abc155/submissions/10149397

    // OKからNG領域で二分探索（x未満がk個未満となるxを探索）
    binsearch(ok, ng, [&](ll a){
      ll cnt = 0;
      // Aiのペアとなる数との積でx未満となるか判定
      for(ll i=0; i<N; i++){
        if(A[i]>=0){
          // 正数であれば自分〜Nまで探せば良い
          ll ok = i;
          ll ng = N;
          binsearch(ok,ng,[&](ll b){
            // インデックスokからngまででa(=探したいx)よりも少なくなるインデックスはどこか
            return A[i]*A[b]<a;
          });
          // i ..(A[i]*A[j]<a).. ok ..(A[i]*A[j]>=a).. N
          cnt+=ok-(i);
        }
        else {
          ll ok=N;
          ll ng=i;
          binsearch(ok,ng,[&](ll b){
            // インデックスokからngまででa(=探したいx)よりも少なくなるインデックスはどこか
            // ただし負数の場合はソート済配列Aの右側から探していく（インデックスが小さいほど積が大きくなるため）
            return A[i]*A[b]<a;
          });
          cnt+=N-ok;
        }
      }
      return cnt<K;
    });
    cout << ok << endl;
    return 0;
}


Measured memory_bytes: 1792