#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FOR(i,k,n) for (int (i)=(k); (i)<(n); ++(i)) #define rep(i,n) FOR(i,0,n) #define pb push_back #define eb emplace_back #define all(v) begin(v), end(v) #define debug(x) cerr<< #x <<": "< i_i; typedef pair p_i; typedef vector vi; typedef vector > vvi; typedef vector vll; typedef vector > vvll; typedef vector vc; typedef vector > vvc; typedef vector vd; typedef vector > vvd; template using vv=vector >; typedef deque di; typedef deque > ddi; // cout vector template ostream& operator<<(ostream& s, const vector& v) { int len = v.size(); for (int i = 0; i < len; ++i) { s << v[i]; if (i < len - 1) s << "\t"; } return s; } // cout 2-dimentional vector template ostream& operator<<(ostream& s, const vector< vector >& vv) { int len = vv.size(); for (int i = 0; i < len; ++i) { s << vv[i] << endl; } return s; } int MAX_PRIME; // in this problem up to 10^4.5 deque isprime; vector primes; void init_prime() { isprime[0] = isprime[1] = false; for(int i = 2; i <= MAX_PRIME; i++) { if (isprime[i]) { primes.push_back(i); for(int j = i*2; j <= MAX_PRIME; j += i) isprime[j] = false; } } } template struct ModInt { long long x; ModInt() : x(0) {} ModInt(long long y) : x(y >= 0 ? y % M : M - (-y) % M) {} ModInt &operator += (const ModInt &rhs){ if((x += rhs.x) >= M) x -= M; return *this; } ModInt &operator -= (const ModInt &rhs){ if((x += M - rhs.x) >= M) x -= M; return *this; } ModInt &operator *= (const ModInt &rhs){ x = 1LL*x*rhs.x % M; return *this; } ModInt &operator /= (const ModInt &rhs){ x = (1LL*x*rhs.inv().x) % M; return *this; } ModInt operator - () const { return ModInt(-x); } ModInt operator + (const ModInt &rhs) const { return ModInt(*this) += rhs; } ModInt operator - (const ModInt &rhs) const { return ModInt(*this) -= rhs; } ModInt operator * (const ModInt &rhs) const { return ModInt(*this) *= rhs; } ModInt operator / (const ModInt &rhs) const { return ModInt(*this) /= rhs; } bool operator < (const ModInt &rhs) const { return x < rhs.x; } ModInt inv() const { long long a = x, b = M, u = 1, v = 0, t; while(b){ t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } return ModInt(u); } ModInt pow(long long t) const { ModInt e = *this, res = 1; for(; t; e *= e, t>>=1) if(t&1) res *= e; return res; } }; template ostream &operator << (ostream &os, const ModInt &rhs){ return os << rhs.x; } template istream &operator >> (istream &is, ModInt &rhs){ long long s; is >> s; rhs = ModInt(s); return is; }; int pow_mod(ll x, ll n, ll m) { ll res = 1; for (; n > 0; n >>= 1) { if (n & 1) res = (res * x) % m; x = (x * x) % m; } return res; } int main() { MAX_PRIME = sqrt(1000000000); isprime.resize(MAX_PRIME+1, true); init_prime(); int n, k; cin >> n >> k; vi a(n); vvi factors(primes.size()); map big_primes; rep (i, n) { cin >> a[i]; } rep (i, n) { rep (j, primes.size()) { // if ( primes[j] * primes[j] > a[i] ) { // break; // } int cnt = 0; while ( a[i] % primes[j] == 0 ) { a[i] /= primes[j]; cnt += 1; } factors[j].pb(cnt); if ( a[i] == 1 ) { break; } } if ( a[i] > 1 ) { big_primes[a[i]] += 1; debug(i); } } rep (i, factors.size()) { sort(all(factors[i]), [](int x, int y) { return x > y; }); if ( factors[i].size() > k ) { factors[i].erase(begin(factors[i])+k, end(factors[i])); } } const ll mod = 1000000007; ModInt ans(1); // small primes rep (i, factors.size()) { int cnt = 0; rep (j, factors[i].size()) { cnt += factors[i][j]; } ans *= pow_mod(primes[i], cnt, mod); } // big primes for (auto bp : big_primes) { ans *= pow_mod(bp.first, min(k, bp.second), mod); } printf("%lld\n", ans.x); return 0; }