#ifdef INCLUDED_MAIN const int mod = mod2; using mint = ModInt; // 階乗・組合せの逆元 class FactorialMod { void calc_inverse() { inverse[0] = 0; inverse[1] = 1; for (int i = 2; i < max_num + 1; i++) { inverse[i] = mod - ((mod / i) * inverse[mod % i] % mod); } } void calc_factorial_inverse() { factorial[0] = factorial_inverse[0] = 1; for (int i = 1; i < max_num + 1; i++) { factorial[i] = (factorial[i - 1] * i) % mod; factorial_inverse[i] = (factorial_inverse[i - 1] * inverse[i]) % mod; } } public: int max_num; int mod; vector inverse; vector factorial; // % mod vector factorial_inverse; FactorialMod(int _max_num, const int& _mod) { max_num = _max_num; // n mod = _mod; inverse = vector(max_num + 1); factorial = vector(max_num + 1); factorial_inverse = vll(max_num + 1); calc_inverse(); calc_factorial_inverse(); } // nHk ll conbination_mod(int n, int k) { if (min(n, k) < 0 || max(n, k) > max_num || k > n) return 0; return (((factorial[n] * factorial_inverse[k]) % mod) * factorial_inverse[n - k]) % mod; } // nHk 重複組合せ ll multi_choose_mod(int n, int k) { return conbination_mod(n + k - 1, k); } }; int main() { charm(); ll n, p; cin >> n >> p; mint cnt = 0; ll q = p; while (n >= q) { cnt += n / q; q *= p; } FactorialMod a(n, mod); mint b = a.factorial[n]; print(cnt * b.power(b.x)); return 0; } /* * */ #else //#define _GLIBCXX_DEBUG //#include "typename.hpp" #include "bits/stdc++.h" #define overload4(_1, _2, _3, _4, name, ...) name #define each1(i, a) for (auto&& i : a) #define each2(i, j, a) for (auto&& [i, j] : a) #define each3(i, j, k, a) for (auto&& [i, j, k] : a) #define each(...) overload4(__VA_ARGS__, each3, each2, each1)(__VA_ARGS__) #define all1(v) (v).begin(), (v).end() #define all2(v, b) (v).begin(), (v).begin() + b #define all3(v, a, b) (v).begin() + a, (v).begin() + b #define all4(v, a, b, c) (v).begin() + a, (v).begin() + b, c #define all(...) overload4(__VA_ARGS__, all4, all3, all2, all1)(__VA_ARGS__) #define rall(v) (v).rbegin(), (v).rend() #define rep(i, j, n) for (ll i = j; i < (ll)(n) ; i++) #define rrep(i, j, n) for (ll i = ll(n) - 1; j <= i; i--) using namespace std; template using V = vector; template using VV = V>; template using P = pair; template using PQ = priority_queue; template using PQgre = priority_queue, greater>; using ll = long long; using ld = long double; //using LL = __int128; using pii = pair; using psi = pair; using pll = pair; using pil = pair; using pli = pair; using vb = V; using vi = V; using vd = V; using vc = V; using vs = V; using vvb = V; using vll = V; using vld = V; using vvi = V; using vvd = V; using vvll = V; using vvld = V; using vvc = V; using vpii = V; using vpll = V; using vpil = V; using vpli = V; const int inf = 1ll << 30; const ll infl = 1ll << 60; const double pi = acos(-1.0); const int mod1 = 998244353; const int mod2 = 1000000007; const int mod3 = 1000000009; const vector dx = { 1, 1, 0, -1, -1, -1, 0, 1 }; const vector dy = { 0, 1, 1, 1, 0, -1, -1, -1 }; //const vector> delta = { { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 }, { 0, -1 }, { 1, -1 } }; // prototype template istream& operator>>(istream& is, pair& p); template istream& operator>>(istream& is, vector& v); template istream& operator>>(istream& is, vector>& v); //istream& operator>>(istream& is, __int128& x); template void input(T& a); template void input(T& a, Ts&... b); template istream& operator>>(istream& is, pair& p) { is >> p.first >> p.second; return is; } template istream& operator>>(istream& is, vector& v) { for (auto&& c : v) is >> c; return is; } template istream& operator>>(istream& is, vector>& v) { for (auto&& c : v) is >> c; return is; } /* istream& operator>>(istream& is, __int128& x) { x = 0; string s; is >> s; bool res = s[0] == '-'; for (size_t i = (res ? 1 : 0); i < s.size(); i++) { x *= 10; x += s[i] - '0'; } if (res) x = -x; return is; } */ template void input(T& a) { cin >> a; } template void input(T& a, Ts&... b) { cin >> a; input(b...); } // prototype template ostream& operator<<(ostream& os, const pair& p); template ostream& operator<<(ostream& os, const vector& v); template ostream& operator<<(ostream& os, const vector>& v); template ostream& operator<<(ostream& os, const map& mp); template ostream& operator<<(ostream& os, const set& s); template ostream& operator<<(ostream& os, const multiset& ms); template void printTuple(ostream& os, const T& tp, index_sequence, size_t n); template void forTuple(ostream& os, const T& tp); template ostream& operator<<(ostream& os, const tuple& tp); //ostream& operator<<(ostream& os, const __int128& x); void print(); template void print(const T& a); template void print(const T& a, const Ts&... b); template ostream& operator<<(ostream& os, const pair& p) { os << "{ " << p.first << ", " << p.second << " }"; return os; } template ostream& operator<<(ostream& os, const vector& v) { os << "[ "; for (size_t i = 0; i < v.size(); i++) { os << v[i] << (i == v.size() - 1 ? "" : ", "); } return os << " ]"; } template ostream& operator<<(ostream& os, const vector>& v) { os << "[\n"; for (size_t i = 0; i < v.size(); i++) { os << "[ "; for (size_t j = 0; j < v[i].size(); j++) { os << v[i][j] << (j == v[i].size() - 1 ? "" : ", "); } os << " ]"; os << (i == v.size() - 1 ? "" : "\n"); } return os << "\n]"; } template ostream& operator<<(ostream& os, const map& mp) { os << "{ "; auto it = mp.begin(); while (it != mp.end()) { os << (it == mp.begin() ? "" : ", ") << *it; it++; } return os << " }"; } template ostream& operator<<(ostream& os, const set& s) { os << "{ "; auto itr = s.begin(); while (itr != s.end()) { os << (itr == s.begin() ? "" : ", ") << *itr; itr++; } return os << " }"; } template ostream& operator<<(ostream& os, const multiset& ms) { os << "{ "; auto itr = ms.begin(); while (itr != ms.end()) { os << (itr == ms.begin() ? "" : ", ") << *itr; itr++; } return os << " }"; } template void printTuple(ostream& os, const T& tp, index_sequence, size_t n) { using swallow = vector; (void)swallow { (os << get(tp) << (index == n - 1 ? "" : ", "), 0)... }; } template void forTuple(ostream& os, const T& tp) { constexpr size_t n = tuple_size_v; printTuple(os, tp, make_index_sequence{}, n); } template ostream& operator<<(ostream& os, const tuple& tp) { os << "{ "; forTuple(os, tp); return os << " }"; } /* ostream& operator<<(ostream& os, const __int128& x) { __int128 tmp = x; if (tmp == 0) return os << 0; if (tmp < 0) { os << '-'; tmp = -tmp; } vector ret; while (tmp) { ret.emplace_back(tmp % 10); tmp /= 10; } reverse(ret.begin(), ret.end()); for (auto&& i : ret) os << i; return os; } */ void print() { cout << '\n'; } template void print(const T& a) { cout << a << '\n'; } template void print(const T& a, const Ts&... b) { cout << a; (cout << ... << (cout << ' ', b)); cout << '\n'; //{ cout << a << ' '; print(b...); } } void charm() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); } template bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } return false; } template bool chmin(T& a, const T& b) { if (a > b) { a = b; return true; } return false; } template vector> zip(vector& v) { vector> vt(v.size()); for (size_t i = 0; i < v.size(); i++) vt[i] = make_tuple(v[i]); return vt; } template auto zip(vector& v, Ts&&... vs) { auto vt = zip(v); auto vts = zip(vs...); size_t m = min(vt.size(), vts.size()); auto te = decltype(vt)(1)[0]; auto tse = decltype(vts)(1)[0]; vector res(m, tuple_cat(te, tse)); for (size_t i = 0; i < m; i++) res[i] = tuple_cat(vt[i], vts[i]); return res; } ll power(ll n, ll k) { ll res = 1; while (k) { if (k & 1) res *= n; n *= n; k >>= 1; } return res; } ll powerMod(ll n, ll k, ll mod) { ll res = 1; while (k) { if (k & 1) res = res * n % mod; n = n * n % mod; k >>= 1; } return res; } template struct ModInt { ll x; constexpr ModInt(ll a = 0) noexcept : x(a >= 0 ? a % mod : (a % mod + mod)) {}; constexpr ModInt& operator+=(const ModInt& r) noexcept { x += r.x; if (x >= mod) x -= mod; return *this; } constexpr ModInt& operator-=(const ModInt& r) noexcept { x -= r.x; if (x < 0) x += mod; return *this; } constexpr ModInt& operator*=(const ModInt& r) noexcept { x = x * r.x % mod; return *this; } constexpr ModInt& operator/=(const ModInt& r) noexcept { return *this *= r.inverse(); } constexpr ModInt operator+(const ModInt& r) const noexcept { return ModInt(*this) += r; } constexpr ModInt operator-(const ModInt& r) const noexcept { return ModInt(*this) -= r; } constexpr ModInt operator*(const ModInt& r) const noexcept { return ModInt(*this) *= r; } constexpr ModInt operator/(const ModInt& r) const noexcept { return ModInt(*this) /= r; } constexpr ModInt operator-() const noexcept { return ModInt(-x); }; constexpr bool operator==(const ModInt& r) const noexcept { return x == r.x; } constexpr bool operator!=(const ModInt& r) const noexcept { return x != r.x; } constexpr ModInt& operator++() noexcept { (*this) += 1; return *this; } constexpr ModInt& operator--() noexcept { (*this) -= 1; return *this; } constexpr ModInt operator++(int) noexcept { ModInt tmp(*this); ++(*this); return tmp; } constexpr ModInt operator--(int) noexcept { ModInt tmp(*this); --(*this); return tmp; } constexpr ModInt inverse() const noexcept { ll xx = 1, u = 0, s = x, t = mod; ll k; while (t) { k = s / t; swap(s -= k * t, t); swap(xx -= k * u, u); } return ModInt(xx); } constexpr ModInt power(ll k) const noexcept { ModInt res = 1, y = x; while (k) { if (k & 1) res *= y; y *= y; k >>= 1; } return res; } friend istream& operator>>(istream& is, ModInt& r) { ll s; is >> s; r = ModInt(s); return is; } friend ostream& operator<<(ostream& os, const ModInt& r) { return os << r.x; } }; vector> graph(int n, int m, bool directed = 0, int origin = 1) { vector> g(n); while (m--) { int u, v; cin >> u >> v; u -= origin, v -= origin; g[u].emplace_back(v); if (!directed) g[v].emplace_back(u); } return g; } auto weightedGraph(int n, int m, bool directed = 0, int origin = 1) { struct Edge { int to; ll w; Edge(int to, ll w) : to(to), w(w) {} }; vector> g(n); while (m--) { int u, v; ll w; cin >> u >> v >> w; u -= origin, v -= origin; g[u].emplace_back(Edge(v, w)); if (!directed) g[v].emplace_back(Edge(u, w)); } return g; } #define INCLUDED_MAIN #include __FILE__ #endif