#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using VI = vector<int>;
using VL = vector<ll>;
#define FOR(i,a,n) for(int (i)=(a);(i)<(n);(i)++)
#define eFOR(i,a,n) for(int (i)=(a);(i)<=(n);(i)++)
#define rFOR(i,a,n) for(int (i)=(n)-1;(i)>=(a);(i)--)
#define erFOR(i,a,n) for(int (i)=(n);(i)>=(a);(i)--)
#define SORT(i) sort((i).begin(),(i).end())
#define rSORT(i,a) sort((i).begin(),(i).end(),(a))
#define all(i) (i).begin(),(i).end()
constexpr ll INF = 1000000000;
constexpr ll LLINF = 1LL << 60;
constexpr ll mod = 1000000007;
constexpr ll MOD = 998244353;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; }return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; }return 0; }
inline void init() { cin.tie(nullptr); cout.tie(nullptr); cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }

template<int mod> struct ModInt {
    int x;

    ModInt() : x(0) {}
    ModInt(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

    ModInt& operator+=(const ModInt& p) {
        if ((x += p.x) >= mod) x -= mod;
        return *this;
    }
    ModInt& operator-=(const ModInt& p) {
        if ((x += mod - p.x) >= mod) x -= mod;
        return *this;
    }
    ModInt& operator*=(const ModInt& p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }
    ModInt& operator/=(const ModInt& p) {
        *this *= p.inverse();
        return *this;
    }

    ModInt operator-() const { return ModInt(-x); }
    ModInt operator+(const ModInt& p) const { return ModInt(*this) += p; }
    ModInt operator-(const ModInt& p) const { return ModInt(*this) -= p; }
    ModInt operator*(const ModInt& p) const { return ModInt(*this) *= p; }
    ModInt operator/(const ModInt& p) const { return ModInt(*this) /= p; }

    bool operator==(const ModInt& p) const { return x == p.x; }
    bool operator!=(const ModInt& p) const { return x != p.x; }

    ModInt inverse() const {
        int a = x, b = mod, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            swap(a, b);
            u -= t * v;
            swap(u, v);
        }
        return ModInt(u);
    }

    ModInt pow(int e) {
        long long a = 1, p = x;
        while (e > 0) {
            if (e % 2 == 0) { p = (p * p) % mod; e /= 2; }
            else { a = (a * p) % mod; e--; }
        }
        return ModInt(a);
    }

    friend ostream& operator<<(ostream& os, const ModInt<mod>& p) {
        return os << p.x;
    }
    friend istream& operator>>(istream& is, ModInt<mod>& a) {
        long long x;
        is >> x;
        a = ModInt<mod>(x);
        return (is);
    }
};
using modint = ModInt<mod>;

const int nCk_MAX = 510000;
ll fac[nCk_MAX], finv[nCk_MAX], inv[nCk_MAX];
bool Preparation = true;
void cominit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < nCk_MAX; i++) {
        fac[i] = fac[i - 1] * i % mod;
        inv[i] = mod - inv[mod % i] * (mod / i) % mod;
        finv[i] = finv[i - 1] * inv[i] % mod;
    }
}
ll com(int n, int k) {
    if (Preparation) {
        cominit();
        Preparation = false;
    }
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % mod) % mod;
}

int main() {
    init();

    int n, m;
    cin >> n >> m;

    map<ll, ll> pri;
    for (ll i = 2; i * i <= m; i++) {
        while (m % i == 0) {
            pri[i]++;
            m /= i;
        }
    }
    if (m != 1) pri[m] = 1;

    modint ans = 1;
    for (auto i : pri) {
        ans *= com(i.second + n - 1, i.second);
    }
    cout << ans << "\n";
}


Measured memory_bytes: 12160