#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <math.h>
#include <assert.h>

using namespace std;

typedef long long int ll;

void c()
{
    string s, t;
    cin >> s >> t;
    vector<int> st(26, 0);
    vector<int> tt(26, 0);
    for (int i = 0; i < s.size(); ++i) {
        st[s[i] - 'a']++;
        tt[t[i] - 'a']++;
    }
    sort(st.begin(), st.end());
    sort(tt.begin(), tt.end());
    bool flag = true;
    for (int i = 0; i < 26; ++i) {
        if(st[i] != tt[i])
        {
            flag = false;
        }
    }
    if(!flag)
    {
        cout << "No" << endl;
    }else{
        vector<int> st2(s.size(), 0);
        vector<int> tt2(t.size(), 0);
        st2[0] = 1;
        tt2[0] = 1;
        for(int i = 1; i < s.size(); i++)
        {
            if(s[i - 1] == s[i])
            {
                st2[i] = st2[i - 1] + 1;
            }else{
                st2[i] = 1;
            }
            if(t[i - 1] == t[i])
            {
                tt2[i] = tt2[i - 1] + 1;
            }else{
               tt2[i]  = 1;
            }
        }
        bool flag2 = true;
        for (int i = 0; i < s.size(); ++i) {
            if(st2[i] != tt2[i])
            {
                flag2 = false;
            }
        }
        if(flag2)
        {
            cout << "Yes" << endl;
        }else{
            cout << "No" << endl;
        }
    }
}

//エラトステネスの篩
vector<int> sieve_of_eratosthenes(int n){
    vector<int> cand(n + 1, 1);
    vector<int> result;
    for (int i = 2; i < n + 1; ++i) {
        if(cand[i] == 0) continue;
        result.push_back(i);
        for (int j = 2; j * i < n + 1; ++j) {
            cand[j * i] = 0;
        }
    }
    return result;
}

//拡張ユークリッドの互除法
//ax + by = cとなるようなc=gcd(a,b)をxをペアにして返す
//firstがx,secondがc
template <typename number>
pair<number, number> extended_euclid(number a, number b)
{
    number r0, r1, a0, a1, b0, b1;
    r0 = a; r1 = b;
    a0 = 1; a1 = 0;
    b0 = 0; b1 = 1;
    while (r1>0) {
        number q1 = r0 / r1;
        number r2 = r0 % r1;
        number a2 = a0 - q1 * a1;
        number b2 = b0 - q1 * b1;
        r0 = r1 ; r1 = r2;
        a0 = a1 ; a1 = a2;
        b0 = b1 ; b1 = b2;
    }
    number c = r0;
    a = a0; //x
    b = b0; //y
    return  {a, c};
}

//Nを法とした逆元を求める関数
template  <typename number>
number inverse_N(number a, number N)
{
    pair<number, number> result = extended_euclid(a, N);
    if(result.first < 0)
    {
        result.first = result.first + N;
    }
    return result.first;
}

int main() {
    int n, m;
    ll mod = 1000000000 + 7;
    cin >> n >> m;

    //素因数分解 各要素で何回割り切れるか試す
    vector<int> dividable_count;
    int max_count = 0;
    for (int i = 2; i * i <= m; ++i) {
        if(m % i == 0)
        {
            int count = 0;
            while (m % i == 0)
            {
                count++;
                m /= i;
            }
            dividable_count.push_back(count);
            max_count = max(max_count, count);
        }
    }
    if(m != 1)
    {
        dividable_count.push_back(1);
        max_count = max(max_count, 1);
    }

    //組み合わせを計算
    //各素因子の数をN個に振り分ける組み合わせ(重複組合せ)
    //////////////////////////////////////////
    //最初に階乗を計算した配列を用意
    vector<ll> factorials(n + max_count);
    vector<ll> factorials_inverse(n + max_count);
    factorials[0] = 1ll;
    factorials_inverse[0] = inverse_N(1ll, mod);
    for (ll i = 1ll; i < factorials.size(); ++i) {
        factorials[i] = (factorials[i - 1] * i) % mod;
    }
    for (ll i = 1ll; i < factorials_inverse.size(); ++i) {
        factorials_inverse[i] = inverse_N(factorials[i], mod);
    }
    ll result = 1ll;
    for(auto e : dividable_count)
    {
        ll temp = (factorials[n - 1 + e] * factorials_inverse[e]) % mod;
        temp = (temp * factorials_inverse[n - 1]) % mod;
        result *= temp;
        result %= mod;
    }
    cout << result << endl;
    return 0;
}



Measured memory_bytes: 1792