#include <bits/stdc++.h>
#define ll long long
#define MODV 1000000007
#define INFLL LLONG_MAX // 9223372036854775807
#define EPS 1e-9
#define rep(i, n) for(ll i=0, i##_len=(ll)(n); i<i##_len; i++)
#define repf(i, n) for(ll i=1, i##_len=(ll)(n+1); i<i##_len; i++)
#define all(v) v.begin(), v.end()
#define endl "\n"
#define vi vector<ll>
#define vvi vector<vector<ll>>
#define Yes() cout << "Yes" << endl
#define YES() cout << "YES" << endl
#define No() cout << "No" << endl
#define NO() cout << "NO" << endl
#define Init() std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout<<fixed<<setprecision(15);
template<class T>bool chmax(T &a, const T &b){ if(a<b){ a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b){ if(b<a){ a=b; return 1; } return 0; }
using namespace std;

// BinomialCoefficient; 二項係数
// ：BiCoef<mint> bc(xxxx)で初期化、bc.com(n, k)でnCkを計算
template<class T> struct BiCoef{
    vector<T> fact_, inv_, finv_;
    constexpr BiCoef(){}
    constexpr BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1){ init(n); }
    constexpr void init(int n) noexcept{
        fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
        int MOD=fact_[0].getmod();
        for(int i=2; i<n; i++){ fact_[i]=fact_[i-1]*i; inv_[i]=-inv_[MOD%i]*(MOD/i); finv_[i]=finv_[i-1]*inv_[i]; }}
    constexpr T com(int n, int k) const noexcept{ if(n<k||n<0||k<0) return 0; return fact_[n]*finv_[k]*finv_[n-k]; }
    constexpr T fact(int n) const noexcept{ if(n<0) return 0; return fact_[n]; }
    constexpr T inv(int n) const noexcept{ if(n<0) return 0; return inv_[n]; }
    constexpr T finv(int n) const noexcept{ if(n<0) return 0; return finv_[n]; }
};

template<int MOD> struct Fp{
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD){ if(val<0) v += MOD; }
    constexpr int getmod(){ return MOD; }
    constexpr Fp operator - () const noexcept{ return val ? MOD - val : 0; }
    constexpr Fp operator + (const Fp& r) const noexcept{ return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept{ return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept{ return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept{ return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept{ val += r.val; if(val>=MOD) val -= MOD; return *this; }
    constexpr Fp& operator -= (const Fp& r) noexcept{ val -= r.val; if(val<0) val += MOD; return *this; }
    constexpr Fp& operator *= (const Fp& r) noexcept{ val = val*r.val%MOD; return *this; }
    constexpr Fp& operator /= (const Fp& r) noexcept{
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) { long long t = a/b; a -= t*b; swap(a, b); u -= t*v; swap(u, v); }
        val = val*u%MOD; if(val<0) val += MOD; return *this; }
    constexpr bool operator == (const Fp& r) const noexcept{ return this->val == r.val; }
    constexpr bool operator != (const Fp& r) const noexcept{ return this->val != r.val; }
    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept{ return os << x.val; }
    friend constexpr istream& operator >> (istream &is, Fp<MOD>& x) noexcept{ return is >> x.val; }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept{
        if (n == 0) return 1; auto t = modpow(a, n/2); t = t*t; if(n & 1) t = t*a; return t; }
};
const int MOD = MODV;
using mint = Fp<MOD>;

// 素因数分解：nの素因数分解を{素数, 指数}の形で昇順に返す。
vector<pair<long long, long long>> primeFactorize(long long n){
    vector<pair<long long, long long>> ret;
    for(long long i=2; i*i<=n; i++){
        if(n%i != 0) continue;
        long long ex = 0;
        while(n%i == 0){ ex++; n /= i; }
        ret.push_back({i, ex});
    }
    if(n != 1) ret.push_back({n, 1});
    return ret;
}

int main(){
    Init();
    ll n, m; cin >> n >> m;
    BiCoef<mint> bc(2000000);

    auto pFac = primeFactorize(m);
    mint ans = 1;
    for(auto p: pFac) ans *= bc.com(p.second+n-1, p.second);
    cout << ans << endl;

}

Measured memory_bytes: 50184