1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

long long N;

bool IsProductValid(const long long a, const long long b, long long *prod) {
  if (N / a < b) return false;
  *prod = a * b;
  return true;
}

class Multiplier {
 public:
  Multiplier(const vector<long long>& v1, const vector<long long>& v2, const int factor) : v1_(v1), v2_(v2), factor_(factor), pos_(v1_.size()) {
    for (int i = 0; i < v1_.size(); ++i) {
      if (factor_ == 1) {
        long long p;
        if (!IsProductValid(v1_[i], v2_[0], &p)) {
          int good = v2_.size() - 1;
          int bad = 0;
          while (bad + 1 < good) {
            int mid = (good + bad) / 2;
            if (IsProductValid(v1_[i], v2_[mid], &p)) good = mid; else bad = mid;
          }
          pos_[i] = good;
        }
      }
      EnqueueIfNotDone(i);
    }
  }

  void Advance() {
    int i = q_.top().second;
    q_.pop();
    ++pos_[i];
    EnqueueIfNotDone(i);
  }

  bool Done() const { return q_.empty(); }

  long long Get() const { return factor_ * q_.top().first; }

 private:
  void EnqueueIfNotDone(const int i) {
    if (pos_[i] >= v2_.size()) return;
    long long p;
    if (!IsProductValid(v1_[i], v2_[pos_[i]], &p)) {
      if (factor_ == -1) return;
      ++pos_[i];
      while (pos_[i] < v2_.size() && !IsProductValid(v1_[i], v2_[pos_[i]], &p)) ++pos_[i];
    }
    if (pos_[i] < v2_.size()) q_.push(make_pair(factor_ * p, i));
  }

  const vector<long long>& v1_;
  const vector<long long>& v2_;
  int factor_;
  priority_queue<pair<long long, int> > q_;
  vector<int> pos_;
};

void Extend(const long long f, vector<long long>* v) {
  int s = v->size();
  for (int i = 0; i < s; ++i) {
    long long a = (*v)[i];
    long long p;
    while (IsProductValid(a, f, &p)) {
      a = p;
      v->push_back(a);
    }
  }
}

int main() {
  vector<vector<long long> > v(4, vector<long long>(1, 1));
  int k;
  scanf("%d%lld", &k, &N);

  vector<int> p(k);
  for (int i = 0; i < k; ++i) scanf("%d", &p[i]);
  sort(p.begin(), p.end());

  for (int i = 0; i < k; ++i) {
    int s = min(min(v[0].size(), v[1].size()), min(v[2].size(), v[3].size()));
    for (int j = 0; j < 4; ++j) if (s == v[j].size()) {
      Extend(p[i], &v[j]);
      break;
    }
  }

  // for (int i = 0; i < 4; ++i) cerr << v[i].size() << endl;

  sort(v[0]. begin(), v[0]. end());
  sort(v[1]. begin(), v[1]. end());
  sort(v[2].rbegin(), v[2].rend());
  sort(v[3].rbegin(), v[3].rend());

  Multiplier m_inc(v[0], v[1], -1);
  Multiplier m_dec(v[2], v[3],  1);

  long long ret = 1;
  while (!m_inc.Done() && !m_dec.Done()) {
    long long curr;
    if (!IsProductValid(m_inc.Get(), m_dec.Get(), &curr)) {
      m_dec.Advance();
    } else {
      ret = max(ret, curr);
      m_inc.Advance();
    }
  }

  printf("%lld\n", ret);

  return 0;
}