#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
#include <cmath>

using namespace std;

template <int mod>
class ModInt {
public:
    ModInt() {};
    ModInt(long long int n) {num = n % mod;}

    ModInt& operator+=(const ModInt& x) {num += x.num; num %= mod; return *this;}
    ModInt& operator-=(const ModInt& x) {num += mod - x.num; num %= mod; return *this;}
    ModInt& operator*=(const ModInt& x) {num *= x.num; num %= mod; return *this;}
    ModInt& operator/=(const ModInt& x) {return *this *= inv(x);}
    friend ModInt operator+(const ModInt& lhs, const ModInt& rhs) {return lhs.num + rhs.num;}
    friend ModInt operator-(const ModInt& lhs, const ModInt& rhs) {return lhs.num - rhs.num + mod;}
    friend ModInt operator*(const ModInt& lhs, const ModInt& rhs) {return lhs.num * rhs.num;}
    friend ModInt operator/(const ModInt& lhs, const ModInt& rhs) {return lhs * inv(rhs);}

    friend ostream& operator<<(ostream& os, const ModInt& x) {os << x.num; return os;}
    friend istream& operator>>(istream& is, ModInt& x) {
        long long int tmp;
        is >> tmp;
        x.num = tmp % mod;
        return is;
    }

    explicit operator int() const {return num;}

    static ModInt pow(const ModInt& x, long long int n) {
        ModInt ret = 1;
        ModInt digit = x;
        while (n) {
            if (n & 1) ret *= digit; 
            digit *= digit;
            n >>= 1;
        }
        return ret;
    }

    static ModInt inv(const ModInt& x) {
        if (x.num <= 0) return -1;
        if (x.num < tsize) return (long long int)factt[x.num] * finvt[x.num-1];
        return pow(x, mod-2);
    }

    static void reserve(int n) {
        if (n < tsize) return;
        n = min(n, mod-1);
        factt.resize(n+1); finvt.resize(n+1);
        for (int i = tsize; i <= n; ++i) factt[i] = (long long int)i * factt[i-1] % mod;
        finvt[n] = (int)inv(factt[n]);
        for (int i = n-1; i >= tsize; --i) finvt[i] = (long long int)(i+1) * finvt[i+1] % mod;
        tsize = n+1;
    }

    static ModInt fact(int n) {
        if (n < 0) return -1;
        if (n >= mod) return 0;
        if (n < tsize) return factt[n]; 
        long long int ret = factt.back();
        for (int i = tsize; i <= n; ++i) ret = i * ret % mod;
        return ret;
    }

    static ModInt factinv(int n) {
        if (n < 0) return -1;
        if (n < tsize) return finvt[n];
        return inv(fact(n));
    }

    static ModInt perm(int n, int k) {
        if (n < k || k < 0) return -1;
        return fact(n) * factinv(n-k);
    }
    
    static ModInt comb(int n, int k) {
        if (n < k || k < 0) return -1;
        return fact(n) * factinv(n-k) * factinv(k);
    }

    static ModInt repcomb(int n, int k) {
        return comb(n+k-1, k);
    }

private:
    long long int num;
    static vector<int> factt, finvt;
    static int tsize;
};
template<int mod> vector<int> ModInt<mod>::factt(1, 1);
template<int mod> vector<int> ModInt<mod>::finvt(1, 1);
template<int mod> int ModInt<mod>::tsize = 1;

using mint = ModInt<1000000007>;

int main() {
    int N, M;
    cin >> N >> M;

    vector<int> np;
    for (int i = 2; i * i <= M; ++i) {
        int count = 0;
        while (M % i == 0) {
            M /= i;
            ++count;
        }
        if (count > 0) np.push_back(count);
    }
    if (M != 1) np.push_back(1);

    mint ans = 1;
    mint::reserve(N+32);
    for (auto e: np) ans *= mint::repcomb(N, e);

    cout << ans << endl;

    return 0;
}


Measured memory_bytes: 1024