// Slower C++ solution:
/*

  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);}

#define SIZE 23333

using std::min;

using std::max;

using std::pair;

using std::queue;

using std::priority_queue;

using std::vector;

inline char gc(){

    static char buf[SIZE],*p1=buf,*p2=buf;

    return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;

}

#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;

}


// Faster C++ solution for the same problem (measured speedup: 1.5023064834461588x):
//把质因数写出来后就是很明显的插板法了 

#include <bits/stdc++.h>

#define Maxn 1000000

#define rint register int

using namespace std;

const int Mod = 1e9 + 7;



int read() {

  rint s = 0, f = 1; register char ch = getchar();

  while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }

  while (isdigit(ch)) { s = s * 10 + ch - '0'; ch = getchar(); }

  return s * f;

}



namespace Mathscalc {

  inline int add(int a, int b) { return a + b >= Mod ? a + b - Mod : a + b; }

  inline int sub(int a, int b) { return a - b < 0 ? a - b + Mod : a - b; }

  inline int mul(int a, int b) { return 1LL * a * b % Mod; }

  inline int power(int a, int b) { rint res = 1; for (; b; b >>= 1) { if ( b & 1 ) res = mul(res, a); a = mul(a, a); } return res; }

} using namespace Mathscalc;



int n, m;

int c[Maxn], p[Maxn], primenum = 0;

int inv[Maxn], fac[Maxn], invfac[Maxn];



void input() { n = read(), m = read(); }



namespace Solution {

  void divide(int x) {

  	for (rint i = 2; i <= sqrt(x); ++i) {

  		if (x % i == 0) {

  			p[++primenum] = i, c[primenum] = 0;

  			while (x % i == 0) x /= i, ++c[primenum];

			}

		}

		if (x > 1) p[++primenum] = x, c[primenum] = 1;

	}

	

	void get() {

		inv[1] = 1;

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

		invfac[0] = invfac[1] = 1;

		for (rint i = 2; i <= n + 1000; ++i) {

		  inv[i] = mul((Mod - Mod / i), inv[Mod % i]);

			fac[i] = mul(fac[i - 1], i);

			invfac[i] = mul(invfac[i - 1], inv[i]);

		}

	}

	

	inline int C(int n, int m) { return mul(fac[n], mul(invfac[m], invfac[n - m])); }

	

	void solve() {

		divide(m);

		get();

		int ans = 1;

		for (rint i = 1; i <= primenum; ++i) ans = mul(ans, C(n + c[i] - 1, n - 1));

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

	}

}



signed main() {

  input();

  Solution :: solve();

  return 0;

}