// Slower C++ solution:
#include <bits/stdc++.h>

#define LL long long

#define db double

using namespace std;

 

const int MAXN = (1 << 17 | 3);

const int MAXE = 400400;

const int INF = 0x3f3f3f3f;

 

template<typename T> inline void CheckMax(T &A, T B) {

	A < B ? A = B : A;

}

 

template<typename T> inline void CheckMin(T &A, T B) {

	A > B ? A = B : A;

}

 

template <typename T> inline void read(T &x) {

    int c = getchar();

    bool f = false;

    for (x = 0; !isdigit(c); c = getchar()) {

        if (c == '-') {

            f = true;

        }

    }

    for (; isdigit(c); c = getchar()) {

        x = x * 10 + c - '0';

    }

    if (f) {

        x = -x;

    }

}

 

LL n, m;

LL P[MAXN], cnt;



const LL mod = 1000000007;



LL qpow(LL a, LL b) {

	LL ret = 1;

	while(b) {

		if(b & 1) ret *= a;

		ret %= mod;

		a = a * a % mod;

		b >>= 1;

	}

	return ret;

}



#define inv(x) qpow(x, mod - 2)

LL fac[MAXN + 10];



void init() {

	fac[0] = 1;

	for(LL i = 1; i <= MAXN; i++) fac[i] = fac[i - 1] * i % mod;

}



LL C(LL a, LL b) {

    return (fac[a] * inv(fac[b]) % mod * inv(fac[a - b]) % mod);

}



void solve(LL x) {

	for(LL i = 2; i * i <= x; i++) {

		if(x % i == 0) {

			LL cur = 0;

			while(x % i == 0) {

				x /= i;

				cur++;

			}

			P[++cnt] = cur;

		}

	}

	if(x > 1) P[++cnt] = 1;

}

 

signed main() {

	cin >> n >> m;

	solve(m);

	LL ans = 1LL;

	init();

	for(LL i = 1; i <= cnt; i++) {

		ans *= (LL) C(P[i] + n - 1LL, n - 1LL) % mod;

		ans %= mod;

	}

	printf("%lld\n", ans);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1443515759798484x):
/*

  Code By RyeCatcher

*/

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <algorithm>

#include <cctype>

#include <vector>

#include <queue>

#include <cmath>

#include <utility>

#define ri register int

#define ll long long

#define ull unsigned long long

#define pb push_back

#define DEBUG freopen("dat.in","r",stdin);freopen("wa.out","w".stdout);

#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}

using std::min;

using std::max;

using std::pair;

using std::queue;

using std::priority_queue;

using std::vector;

#define gc getchar

template <class T>inline void read(T &x){

	x=0;int ne=0;char c;

    while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;

    while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;

}

const int maxn=100155;

const int size=100150;

const int inf=0x7fffffff;

const ll P=1e9+7;

int n,m;

int c[maxn],tot=0;

ll fac[maxn],inv_fac[maxn];

ll C(int n,int m){

	return fac[m]*inv_fac[n]%P*inv_fac[m-n]%P;

}

ll ksm(ll a){

	ll ans=1;

	ll c=P-2;

	while(c){

		if(c&1)ans=ans*a%P;

		a=a*a%P;

		c=c>>1;

	}

	return ans%P;

}

int main(){

	int x,y,M;

	read(n),read(m);

	M=m;

	for(ri i=2;i*i<=M;i++){

		if(M%i==0){

			c[++tot]=1;

			M/=i;

			while(M%i==0){M/=i;c[tot]++;}

		}

	}

	if(M>1)c[++tot]=1;

	fac[0]=fac[1]=1;

	for(ri i=2;i<=size;i++)

		fac[i]=fac[i-1]*i%P;

	inv_fac[size]=ksm(fac[size]);

	for(ri i=size-1;i>=0;i--)

		inv_fac[i]=inv_fac[i+1]*1ll*(i+1)%P;

	ll ans=1;

	for(ri i=1;i<=tot;i++){

		ans=ans*C(n-1,n+c[i]-1)%P;

	}

	printf("%lld\n",ans);

	return 0;

}