#include <cstdio>
#include <vector>
#include <tuple>
#include <algorithm>


constexpr long  long int inf = 1e18 + 334 + 810 + 1919;

namespace MyInputAndOutput{
    // 入力関係 (cin)
    class user_input{
    public:
        inline const user_input& operator >> (int& int_arg) const {
            scanf("%d", &int_arg); return *this;
        }
        inline const user_input& operator >> (long long int& llint_arg) const {
            scanf("%lld", &llint_arg); return *this;
        }
        inline const user_input& operator >> (unsigned int& uint_arg) const {
            scanf("%u", &uint_arg); return *this;
        }
        inline const user_input& operator >> (unsigned long long int& ullint_arg) const {
            scanf("%llu", &ullint_arg); return *this;
        }
        inline const user_input& operator >> (unsigned long& ullint_arg) const {
            scanf("%lu", &ullint_arg); return *this;
        }
        inline const user_input& operator >> (char* str_arg) const {
            scanf("%s", str_arg); return *this;
        }
        inline const user_input& operator >> (char& char_arg) const {
            scanf("%*c%c", &char_arg); return *this;
        }
        template <typename S, typename T>
        inline const user_input& operator >>(std::pair<S, T>& pair_arg) const{
            (*this) >> pair_arg.first >> pair_arg.second; return *this;
        }
        template <typename T>
        inline const user_input& operator >>(std::vector<T>& vec) const {
            for(T& ele : vec) (*this) >> ele; return *this;
        }
    } cin;

    // 出力関係 (cout)
    class user_output{
    public:
        user_output(void){}
        inline const user_output& operator << (const int int_arg) const{
            printf("%d", int_arg); return *this;
        }
        inline const user_output& operator << (const unsigned int uint_arg) const{
            printf("%u", uint_arg); return *this;
        }
        inline const user_output& operator << (const long long int llint_arg) const {
            printf("%lld", llint_arg); return *this;
        }
        inline const user_output& operator << (const unsigned long long int ullint_arg) const {
            printf("%llu", ullint_arg); return *this;
        }
        inline const user_output& operator << (const unsigned long ulint_arg) const {
            printf("%lu", ulint_arg); return *this;
        }
        inline const user_output& operator << (const double ld_arg) const {
            printf("%.16lf", ld_arg); return *this;
        }
        inline const user_output& operator << (const long double ld_arg) const {
            printf("%.16Lf", ld_arg); return *this;
        }
        inline const user_output& operator << (const char char_arg) const {
            putchar(char_arg); return *this;
        }
        inline const user_output& operator << (const unsigned char uchar_arg) const {
            putchar(uchar_arg); return *this;
        }
        inline const user_output& operator << (const char* str_arg) const {
            fputs(str_arg, stdout); return *this;
        }
        template <typename S, typename T>
        inline const user_output& operator <<(const std::pair<S, T>& pair_arg) const{
            (*this) << pair_arg.first << ' ' << pair_arg.second; return *this;
        }
        template <typename Tp_name>
        inline const user_output& operator << (const std::vector<Tp_name>& vec) const {
            const size_t size_of_vec = vec.size();
            if(size_of_vec <= 0) return *this;
            (*this) << vec[0]; 
            for(size_t index = 1; index < size_of_vec; ++index) (*this) << ' ' << vec[index];
            return *this;
        }
    } cout;

    // その他出力関数
    void binary_output(int64_t value, size_t length = 64){
        char out[length + 1];
        for(size_t i = 0; i < length; ++i) out[length - 1 - i] = ((value >> i) & 1) ? '1' : '0';
        out[length] = '\0'; puts(out);
    }
    template <typename InputType>
    void print(InputType first, InputType last, const char separate_c = ' ', const char end_c = '\n'){
        InputType it = first;
        while(true){
            MyInputAndOutput::cout << *it;
            if(++it == last){MyInputAndOutput::cout << end_c; return;}
            MyInputAndOutput::cout << separate_c;  
        }
    }
}; namespace MIO = MyInputAndOutput;

// 大小関係のある配列について, 個数を数える | クエリ形式の場合はクエリ先読みBITを使え
template <typename element_type> class CountingVector{
private:
    unsigned int size_of_vec;             // 座圧済み配列の長さ
    const unsigned int size_of_arg_vec;   // 元の引数の配列の長さ | = counter[size_of_vec-1] 
    std::vector<element_type> vec;        // ソート & 座標圧縮 済み配列
    std::vector<unsigned int> counter;    // 累積和 counter[i] = vec[0, i)の数

    using const_itr_type = typename std::vector<element_type>::const_iterator;
public:
    // コンストラクタ : 破壊的操作を行うので引数はコピー
    template <typename element_type_castable>
    CountingVector(std::vector<element_type_castable> arg_vec): size_of_arg_vec(arg_vec.size()){
        const unsigned int arg_size = arg_vec.size();
        counter.reserve(arg_size + 1); counter.push_back(0);
        vec.reserve(arg_size);
        std::sort(arg_vec.begin(), arg_vec.end());
        unsigned int idx = 0;
        while(idx < arg_size){
            unsigned int cnt = 1;
            vec.push_back(arg_vec[idx]);
            while(idx + cnt < arg_size and arg_vec[idx] == arg_vec[idx + cnt]) cnt++;
            unsigned int p = counter.back() + cnt; counter.push_back(p);
            idx += cnt;
        }
        size_of_vec = vec.size();
    }

    // arg_vec[i] < val なる i の個数を数える
    inline unsigned int count_smallerThan(const element_type& val) const noexcept {
        unsigned int idx = std::lower_bound(vec.begin(), vec.end(), val) - vec.begin();
        return counter[idx];
    }
    inline unsigned int count_smallerThan(const const_itr_type& itr) const noexcept {
        unsigned int idx = itr - vec.cbegin(); return counter[idx];
    }

    // arg_vec[i] ≤ val なる i の個数を数える
    inline unsigned int count_notGreaterThan(const element_type& val) const noexcept {
        unsigned int idx = std::upper_bound(vec.begin(), vec.end(), val) - vec.begin();
        return counter[idx];
    }
    inline unsigned int count_notGreaterThan(const const_itr_type& itr) const noexcept {
        unsigned int idx = itr - vec.cbegin(); return counter[idx + 1];
    }

    // arg_vec[i] > val なる i の個数を数える
    inline unsigned int count_greaterThan(const element_type& val) const noexcept {
        unsigned int idx = std::upper_bound(vec.begin(), vec.end(), val) - vec.begin();
        return size_of_arg_vec - counter[idx];
    }
    inline unsigned int count_greaterThan(const const_itr_type& itr) const noexcept {
        unsigned int idx = itr - vec.cbegin(); return size_of_arg_vec - counter[idx + 1];
    }

    // arg_vec[i] ≥ val なる i の個数を数える
    inline unsigned int count_notSmallerThan(const element_type& val) const noexcept {
        unsigned int idx = std::lower_bound(vec.begin(), vec.end(), val) - vec.begin();
        return size_of_arg_vec - counter[idx];
    }
    inline unsigned int count_notSmallerThan(const const_itr_type& itr) const noexcept {
        unsigned int idx = itr - vec.cbegin(); return size_of_arg_vec - counter[idx];
    }

    // vec[idx] = val なる idx を返す (存在しない場合は -1を返す)
    inline int key(const element_type& val) const noexcept {
        int idx = std::lower_bound(vec.begin(), vec.end(), val) - vec.begin();
        return (vec[idx] == val) ? idx : -1;
    }
    inline int key(const const_itr_type& itr) const noexcept { return itr - vec.cbegin(); }

    // arg_vec[i] = val なる i の個数を数える (存在しないなら 0)
    inline unsigned int count(const element_type& val) const noexcept {
        unsigned int idx = std::lower_bound(vec.begin(), vec.end(), val) - vec.begin();
        return (vec[idx] == val) ? counter[idx + 1] - counter[idx] : 0;
    }
    inline unsigned int count(const const_itr_type& itr) const noexcept {
        unsigned int idx = itr - vec.cbegin(); return counter[idx+1] - counter[idx];
    }

    // lower_bound, upper_bound
    inline const_itr_type lower_bound(const element_type& val) const noexcept {
        return std::lower_bound(vec.cbegin(), vec.cend(), val);
    }
    inline const_itr_type upper_bound(const element_type& val) const noexcept {
        return std::upper_bound(vec.cbegin(), vec.cend(), val);
    }

    // イテレーター関係
    const_itr_type cbegin(void) const noexcept{ return vec.cbegin(); }
    const_itr_type cend(void)   const noexcept{ return vec.cend(); }
};


int main(void){
    int n; long long int k; MIO::cin >> n >> k;
    std::vector<int> Pos, Neg; Pos.reserve(n); Neg.reserve(n);
    unsigned long long zero = 0;
    for(int i = 0; i < n; ++i) {
        int a; MIO::cin >> a;
        if(a < 0) Neg.push_back(-a);
        else if(a == 0) zero++;
        else Pos.push_back(a);
    }
    CountingVector<long long int> CNeg(Neg), CPos(Pos);

    unsigned long long pos = Pos.size(), neg = Neg.size();
    if(k <= pos * neg){
        long long int ok = 0, ng = inf;
        while(ng - ok > 1){
            long long int num = (ok + ng) / 2;
            long long int cnt = 0;
            // Ai * (-Aj) ≤ -num -> Ai * Aj ≥ num
            for(auto itr = CPos.cbegin(); itr != CPos.cend(); ++itr){
                long long int need = num / *itr; if(num % (*itr) != 0) need++;
                cnt += CNeg.count_notSmallerThan(need) * CPos.count(itr);
                if(cnt >= k) break;
            }
            if(cnt >= k) ok = num; else ng = num;
        }
        MIO::cout << -ok << '\n'; 
        return 0;
    }
    k -= pos * neg;
    if(k <= (pos + neg) * zero + zero * (zero - 1) / 2){ MIO::cout << "0\n"; return 0; }
    k -= (pos + neg) * zero + zero * (zero - 1) / 2;


    long long int ok = inf, ng = 0;
    while(ok - ng > 1){
        long long int num = (ok + ng) / 2;
        long long int cnt = 0;

        // ai * aj ≤ num : ai ≤ (num / aj)
        for(auto itr = CNeg.cbegin(); itr != CNeg.cend(); ++itr){
            long long int need = num / *itr;
            long long int kazu = CNeg.count(itr);
            const auto itr2 = CNeg.upper_bound(need);
            if(itr < itr2){
                cnt += CNeg.count_smallerThan(itr) * kazu;
                cnt += kazu * (kazu - 1) / 2;
            }
            else cnt += CNeg.count_smallerThan(itr2) * kazu;
            if(cnt >= k) break;
        }
        for(auto itr = CPos.cbegin(); itr != CPos.cend(); ++itr){
            long long int need = num / *itr;
            long long int kazu = CPos.count(itr);
            const auto itr2 = CPos.upper_bound(need);
            if(itr < itr2){
                cnt += CPos.count_smallerThan(itr) * kazu;
                cnt += kazu * (kazu - 1) / 2;
            }
            else cnt += CPos.count_smallerThan(itr2) * kazu;
            if(cnt >= k) break;
        }
        if(cnt >= k) ok = num; else ng = num;
    }
    MIO::cout << ok << '\n';
    return 0;
}

Measured memory_bytes: 3712