#include <bits/stdc++.h>

using namespace std;

#define N_TIMES(i, n)     for ( uint64_t i = 0;     i <  n; ++i )
#define N_TIMES_REV(i, n) for (  int64_t i = n - 1; i >= 0; --i )

template<typename T> using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

#ifdef __DEBUG__

template<typename T, typename U>
std::ostream& operator<<(std::ostream &os, const std::pair<T, U> &pair)
{
  os << '(' << pair.first << ", " << pair.second << ')';
  return os;
}

template<typename T>
std::ostream& id_ostream(std::ostream &os, const T &x) { os << x; return os; }

template<typename T, typename ForwardIterator>
std::ostream& _iterator_to_display(
  std::ostream &os,
  ForwardIterator begin, ForwardIterator end,
  const std::string &delim = ", ",
  std::function<std::ostream&(std::ostream&, const T&)> func = id_ostream<T>
)
{
  auto itr = begin;
  while (itr != end) {
    func(os, *itr);
    ++itr;
    if (itr != end) os << delim;
  }
  return os;
}

template<typename T, std::size_t N>
std::ostream& operator<<(std::ostream &os, const std::array<T, N> &array)
{
  os << '[';
  _iterator_to_display<T>(os, array.cbegin(), array.cend());
  os << ']';
  return os;
}

template<typename T>
std::ostream& operator<<(std::ostream &os, const std::list<T> &list)
{
  os << '[';
  _iterator_to_display<T>(os, list.cbegin(), list.cend());
  os << ']';
  return os;
}

template<typename T>
std::ostream& operator<<(std::ostream &os, const std::vector<T> &vector)
{
  os << '[';
  _iterator_to_display<T>(os, vector.cbegin(), vector.cend());
  os << ']';
  return os;
}

template<typename T, class C=std::less<T>>
std::ostream& operator<<(std::ostream &os, const std::set<T> &set)
{
  os << '{';
  _iterator_to_display<T>(os, set.cbegin(), set.cend());
  os << '}';
  return os;
}

template<typename T, class C=std::less<T>>
std::ostream& operator<<(std::ostream &os, const std::multiset<T> &set)
{
  os << '{';
  _iterator_to_display<T>(os, set.cbegin(), set.cend());
  os << '}';
  return os;
}

template<typename T, typename U>
std::ostream& map_pair(std::ostream &os, const std::pair<T, U> &pair)
{
  os << pair.first << ": " << pair.second;
  return os;
}

template<typename T, typename U, class C=std::less<T>>
std::ostream& operator<<(std::ostream &os, const std::map<T, U> &map)
{
  os << '{';
  _iterator_to_display<std::pair<T, U>>(os, map.cbegin(), map.cend(), ", ", map_pair<T, U>);
  os << '}';
  return os;
}

template<typename T, typename U, class C=std::less<T>>
std::ostream& operator<<(std::ostream &os, const std::multimap<T, U> &map)
{
  os << '{';
  _iterator_to_display<std::pair<T, U>>(os, map.cbegin(), map.cend(), ", ", map_pair<T, U>);
  os << '}';
  return os;
}

#define debug(var) std::cerr << #var" = " << (var) << std::endl

#endif /* __DEBUG__ */

int judge(uint64_t N, uint64_t K, const vector<int64_t> &A, uint64_t P, uint64_t Q)
{
  uint64_t neg = P, pos = N - Q;

  auto f = [](uint64_t x) { return (x * (x - 1)) >> 1; };
  uint64_t mneg = neg * pos;
  uint64_t mpos = f(neg) + f(pos);
  uint64_t mzero = f(N) - (mneg + mpos);

  if (K <= mneg) {
    return -1;
  } else if (K <= (mneg + mzero)) {
    return 0;
  } else {
    return +1;
  }
}

int64_t solve_negative(uint64_t N, uint64_t K, const vector<int64_t> &A, uint64_t P, uint64_t Q)
{
  auto end = A.begin();
  advance(end, P);

  auto judge = [&](int64_t x)
  {
    uint64_t T = 0;
    for (uint64_t i = Q; i < N; ++i) {
      int64_t y = (x / A[i]) - (x % A[i] == 0 ? 0 : 1);
      uint64_t t = distance(A.begin(), upper_bound(A.begin(), end, y));
      T += t;
    }
    return T < K;
  };

  int64_t lo = A[0] * A[N - 1] - 1 , hi = A[P - 1] * A[Q] + 1;
  while (hi - lo > 1) {
    int64_t mid = (hi + lo) / 2;
    if (judge(mid)) {
      lo = mid;
    } else {
      hi = mid;
    }    
  }

  return hi;
}

int64_t solve_positive(uint64_t N, uint64_t K, const vector<int64_t> &A, uint64_t P, uint64_t Q)
{
  uint64_t neg = P, pos = N - Q;

  auto f = [](uint64_t x) { return (x * (x - 1)) >> 1; };
  uint64_t mneg = neg * pos;
  uint64_t mpos = f(neg) + f(pos);
  uint64_t mzero = f(N) - (mneg + mpos);

  uint64_t M = K - (mneg + mzero);
  
  auto n_begin = A.rbegin(), n_end = A.rend();
  auto p_begin = A.begin(),  p_end = A.end();
  advance(n_begin, N - P);
  advance(p_begin, Q);
  
  vector<int64_t> B(n_begin, n_end);
  vector<int64_t> C(p_begin, p_end);
  N_TIMES(i, P) { B[i] *= -1; }

  auto judge = [&](int64_t x) {
    uint64_t T1 = 0;
    N_TIMES(i, B.size()) {
      int64_t y = (x / B[i]) + (x % B[i] == 0 ? 0 : 1);

      int64_t t = distance(B.begin(), lower_bound(B.begin(), B.end(), y));
      if (B[i] * B[i] < x) { --t; }

      T1 += t;
    }

    uint64_t T2 = 0;
    N_TIMES(i, C.size()) {
      int64_t z = (x / C[i]) + (x % C[i] == 0 ? 0 : 1);

      int64_t t = distance(C.begin(), lower_bound(C.begin(), C.end(), z));
      if (C[i] * C[i] < x) { --t; }

      T2 += t;
    }

    return (T1 + T2) < (M << 1);
  };

  int64_t lo = 0, hi = 1e+18;
  while (hi - lo > 1) {
    int64_t mid = (hi + lo) >> 1;
    if (judge(mid)) {
      lo = mid;
    } else {
      hi = mid;
    }
  }

  return lo;
}

int main()
{
  uint64_t N, K;
  cin >> N >> K;
  
  vector<int64_t> A(N);
  N_TIMES(n, N) { cin >> A[n]; }
  sort(A.begin(), A.end());

  uint64_t P = distance(A.begin(), lower_bound(A.begin(), A.end(), 0));
  uint64_t Q = distance(A.begin(), lower_bound(A.begin(), A.end(), 1));

  int x = judge(N, K, A, P, Q);
  if (x == 0) {
    cout << 0 << endl;
    return 0;
  }

  if (x < 0) {
    cout << solve_negative(N, K, A, P, Q) << endl;
  } else {
    cout << solve_positive(N, K, A, P, Q) << endl;
  }

  return 0;
}

Measured memory_bytes: 3200