#include #define rep(i, p, n) for (ll i = p; i < (ll)(n); i++) #define rep2(i, p, n) for (ll i = p; i >= (ll)(n); i--) using namespace std; using ll = long long; using ld = long double; const double pi = 3.141592653589793; const long long inf = 2 * 1e9; const long long linf = 4 * 1e18; const ll mod1 = 1000000007; const ll mod2 = 998244353; template inline bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; } template inline bool chmin(T &a, T b) { if (a > b) { a = b; return 1; } return 0; } // atcoder #include using namespace atcoder; using mint1 = modint1000000007; using mint2 = modint998244353; vector> base = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 行列A, Bについて、A*Bを返す vector> prodMat(vector> &A, vector> &B, ll mod) { ll N = A.size(); ll P = A.at(0).size(); ll M = B.at(0).size(); vector> res(N, vector(N)); rep(i, 0, N) { rep(j, 0, M) { rep(k, 0, P) { res.at(i).at(j) += A.at(i).at(k) * B.at(k).at(j); res.at(i).at(j) %= mod; } } } return res; } // GのX乗 vector> powMat(vector> &G, ll X, ll mod) { ll N = G.size(); vector>> rui(61, vector>(N, vector(N))); vector> res(N, vector(N)); rep(i, 0, N) { rep(j, 0, N) { rui.at(0).at(i).at(j) = G.at(i).at(j); } } rep(i, 1, 61) { rui.at(i) = prodMat(rui.at(i - 1), rui.at(i - 1), mod); } rep(i, 0, N) { res.at(i).at(i) = 1; } ll now = 1; rep(i, 0, 61) { if (now & X) { res = prodMat(res, rui.at(i), mod); } now *= 2; } return res; } int main() { ////////////////// ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); ////////////////// ll N, M; cin >> N >> M; set st; rep(i, 0, sqrt(M)) { if (M%(i+1)==0) { st.insert(i + 1); } } queue Q; for(ll c:st) { Q.push(M / c); } while(Q.size()) { st.insert(Q.front()); Q.pop(); } vector li; while(st.size()) { li.push_back(*begin(st)); st.erase(*begin(st)); } vector> G(li.size(), vector(li.size())); rep(i, 0, li.size()) { rep(j, 0, li.size()) { if (M % li.at(i)==0 && (M / li.at(i)) % li.at(j) == 0) { G.at(i).at(j) = 1; } // cout << G.at(i).at(j) << " "; } // cout << endl; } auto ans=powMat(G, N - 1, mod1); mint1 temp=0; rep(i, 0, ans.size()) { rep(j, 0, ans.size()) { temp += ans.at(i).at(j); } } cout << temp.val() << endl; return 0; }