#include using namespace std; using ll = long long; template istream& operator >> (istream& is, vector& vec) { for(T& x : vec) is >> x; return is; } template ostream& operator << (ostream& os, const vector& vec) { if(vec.empty()) return os; os << vec[0]; for(auto it = vec.begin(); ++it != vec.end(); ) os << ' ' << *it; return os; } template struct prime_modint { using mint = prime_modint; unsigned int v; prime_modint() : v(0) {} prime_modint(unsigned int a) { a %= MOD; v = a; } prime_modint(unsigned long long a) { a %= MOD; v = a; } prime_modint(int a) { a %= (int)(MOD); if(a < 0)a += MOD; v = a; } prime_modint(long long a) { a %= (int)(MOD); if(a < 0)a += MOD; v = a; } static constexpr int mod() { return MOD; } mint& operator++() {v++; if(v == MOD)v = 0; return *this;} mint& operator--() {if(v == 0)v = MOD; v--; return *this;} mint operator++(int) { mint result = *this; ++*this; return result; } mint operator--(int) { mint result = *this; --*this; return result; } mint& operator+=(const mint& rhs) { v += rhs.v; if(v >= MOD) v -= MOD; return *this; } mint& operator-=(const mint& rhs) { if(v < rhs.v) v += MOD; v -= rhs.v; return *this; } mint& operator*=(const mint& rhs) { v = (unsigned int)((unsigned long long)(v) * rhs.v % MOD); return *this; } mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); } mint operator+() const { return *this; } mint operator-() const { return mint() - *this; } mint pow(long long n) const { assert(0 <= n); mint r = 1, x = *this; while (n) { if (n & 1) r *= x; x *= x; n >>= 1; } return r; } mint inv() const { assert(v); return pow(MOD - 2); } friend mint operator+(const mint& lhs, const mint& rhs) { return mint(lhs) += rhs; } friend mint operator-(const mint& lhs, const mint& rhs) { return mint(lhs) -= rhs; } friend mint operator*(const mint& lhs, const mint& rhs) { return mint(lhs) *= rhs; } friend mint operator/(const mint& lhs, const mint& rhs) { return mint(lhs) /= rhs; } friend bool operator==(const mint& lhs, const mint& rhs) { return (lhs.v == rhs.v); } friend bool operator!=(const mint& lhs, const mint& rhs) { return (lhs.v != rhs.v); } friend std::ostream& operator << (std::ostream &os, const mint& rhs) noexcept { return os << rhs.v; } }; using mint = prime_modint<1000000007>; using mint2 = prime_modint<1000000006>; //using mint = prime_modint<998244353>; struct osa_k{ int n; vector osak_calc; osa_k(int n = 1000001) { osak_calc.resize(n, -1); int d; for(int i = 2; i < n; i += 2) osak_calc[i] = 2; for(int i = 3; i < n; i += 2){ if(osak_calc[i] != -1)continue; d = i << 1; for(int j = i; j < n; j += d){ if(osak_calc[j] != -1)continue; osak_calc[j] = i; } } } bool is_Prime(int x){ return (osak_calc[x] == x); } vector> prime_factor(int x){ vector> ret; if(x <= 1)return ret; ret.emplace_back(osak_calc[x], 1); x /= osak_calc[x]; while(osak_calc[x] != -1){ if(osak_calc[x] == ret.back().first){ ret.back().second++; }else{ ret.emplace_back(osak_calc[x], 1); } x /= osak_calc[x]; } return ret; } //最小公倍数の数列を返す vector> array_lcm(vector a){ map Map; for(int i = 0; i < (int)a.size(); i++){ vector> b = prime_factor(a[i]); for(int j=0;j<(int)b.size();j++){ if(Map.count(b[j].first)){ if(b[j].second>Map[b[j].first])Map[b[j].first]=b[j].second; }else{ Map[b[j].first]=b[j].second; } } } vector> ret; for(auto v:Map)ret.emplace_back(v.first,v.second); return ret; } }; int main(){ ios::sync_with_stdio(false); cin.tie(0); ll n, k; cin >> n >> k; int m = 2 * n; vector> tb(m + 1); vector c(m + 1); iota(c.begin(), c.end(), 0); for(int i = 2; i <= m; i++){ if(c[i] == 1) continue; const int v = c[i]; for(int j = i; j <= m; j += i){ tb[j].emplace_back(v); c[j] /= v; } } map mp; int mx = -1; for(auto &&v : tb[n]){ mp[v]++; mx = max(mx, v); } while(k && mx >= 5){ k--; int mx2 = -1; map mp2; for(auto &&pa : mp){ for(auto &&v : tb[pa.first + 1]){ mp2[v] += pa.second; mx2 = max(mx2, v); } } swap(mp, mp2); swap(mx, mx2); } mint ans = 1; if(k == 0){ for(auto &&pa : mp){ ans *= mint(pa.first).pow(pa.second.v); } }else if(k % 2 == 0){ if(mp[2].v >= 1){ ans *= mint(2).pow((mp[2] * mint2(2).pow(k / 2)).v); } if(mp[3].v >= 1){ ans *= mint(3).pow((mp[3] * mint2(2).pow(k / 2)).v); } }else{ if(mp[2].v >= 1){ ans *= mint(3).pow((mp[2] * mint2(2).pow(k / 2)).v); } if(mp[3].v >= 1){ ans *= mint(2).pow((mp[3] * mint2(2).pow((k + 1) / 2)).v); } } cout << ans << '\n'; }