stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



ll fact[500000];



ll comb(ll a, ll b) {

  ll ue=fact[a], shita1=1, shita2=1;

  ll tmpshita1, tmpshita2;

  ll two, h;

  h = mod - 2;

  while(h>0) {

    two = 1;

    tmpshita1 = fact[b];

    tmpshita2 = fact[a-b];

    while(2*two<h) {

      two *= 2;

      tmpshita1 *= tmpshita1;

      tmpshita2 *= tmpshita2;

      tmpshita1 %= mod;

      tmpshita2 %= mod;

    }

    h -= two;

    shita1 *= tmpshita1;

    shita2 *= tmpshita2;

    shita1 %= mod;

    shita2 %= mod;

  }

  return ue*shita1%mod*shita2%mod;

}



int main() {

  fact[0] = 1;

  for(ll i=1;i<500000;++i) {

    fact[i] = fact[i-1]*i%mod;

  }

  ll N, M;

  cin>>N>>M;

  vector<ll> prime;

  map<ll, int> amap;

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

    if(M%i==0) prime.push_back(i);

    while(M%i==0) {

      amap[i]++;

      M /= i;

    }

  }

  if(M>1) prime.push_back(M);

  amap[M]++;

  ll ans = 1;

  for(int i=0;i<prime.size();++i) {

    ans *= comb(amap[prime[i]]+N-1, amap[prime[i]]);

    ans %= mod;

  }

  cout<<ans<<endl;

}




// Faster C++ solution for the same problem (measured speedup: 1.948511931566333x):
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



ll frac[200000];



ll comb(ll a, ll b) {

  ll ue = frac[a], sh1=1, sh2=1;

  ll tsh1, tsh2;

  ll two, h;

  h = mod - 2;

  while(h>0) {

    two = 1;

    tsh1 = frac[b];

    tsh2 = frac[a-b];

    while(2*two<h) {

      two *= 2;

      tsh1 *= tsh1;

      tsh2 *= tsh2;

      tsh1 %= mod;

      tsh2 %= mod;

    }

    h -= two;

    sh1 *= tsh1;

    sh2 *= tsh2;

    sh1 %= mod;

    sh2 %= mod;

  }

  return ue*sh1%mod*sh2%mod;

}



int main() {

  frac[0] = 1;

  for(ll i=1;i<200000;++i) frac[i] = frac[i-1]*i%mod;

  ll N, M;

  cin>>N>>M;

  vector<ll> prime;

  map<ll, int> amap;

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

    if(M%i==0) prime.push_back(i);

    while(M%i==0) {

      amap[i]++;

      M /= i;

    }

  }

  if(M>1) {

    prime.push_back(M);

    amap[M]++;

  }

  ll ans = 1;

  for(int i=0;i<prime.size();++i) {

    ans *= comb(amap[prime[i]]+N-1, amap[prime[i]]);

    ans %= mod;

  }

  cout<<ans<<endl;

}
// Slower C++ solution:
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



ll fact[500000];



ll comb(ll a, ll b) {

  ll ue=fact[a], shita1=1, shita2=1;

  ll tmpshita1, tmpshita2;

  ll two, h;

  h = mod - 2;

  while(h>0) {

    two = 1;

    tmpshita1 = fact[b];

    tmpshita2 = fact[a-b];

    while(2*two<h) {

      two *= 2;

      tmpshita1 *= tmpshita1;

      tmpshita2 *= tmpshita2;

      tmpshita1 %= mod;

      tmpshita2 %= mod;

    }

    h -= two;

    shita1 *= tmpshita1;

    shita2 *= tmpshita2;

    shita1 %= mod;

    shita2 %= mod;

  }

  return ue*shita1%mod*shita2%mod;

}



int main() {

  fact[0] = 1;

  for(ll i=1;i<500000;++i) {

    fact[i] = fact[i-1]*i%mod;

  }

  ll N, M;

  cin>>N>>M;

  vector<ll> prime;

  map<ll, int> amap;

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

    if(M%i==0) prime.push_back(i);

    while(M%i==0) {

      amap[i]++;

      M /= i;

    }

  }

  if(M>1) prime.push_back(M);

  amap[M]++;

  ll ans = 1;

  for(int i=0;i<prime.size();++i) {

    ans *= comb(amap[prime[i]]+N-1, amap[prime[i]]);

    ans %= mod;

  }

  cout<<ans<<endl;

}




// Faster C++ solution for the same problem (measured speedup: 2.8109488618898237x):
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



ll frac[100100];



ll comb(ll a, ll b) {

  ll ue = frac[a];

  ll sh1, sh2;

  ll h=mod-2;

  ll two;

  while(h>0) {

    two = 1;

    sh1 = frac[b];

    sh2 = frac[a-b];

    while(2*two<h) {

      two *= 2;

      sh1 *= sh1;

      sh1 %= mod;

      sh2 *= sh2;

      sh2 %= mod;

    }

    h -= two;

    ue *= sh1;

    ue %= mod;

    ue *= sh2;

    ue %= mod;

  }

  return ue;

}



int main() {

  frac[0] = 1;

  for(ll i=1;i<100100;++i) frac[i] = frac[i-1]*i%mod;

  ll N, M;

  cin>>N>>M;

  vector<ll> prime;

  map<ll, ll> amap;

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

    if(M%i==0) prime.push_back(i);

    while(M%i==0) {

      amap[i]++;

      M /= i;

    }

  }

  if(M>1) prime.push_back(M);

  amap[M]++;

  ll ans = 1;

  for(int i=0;i<prime.size();++i) {

    ans *= comb(amap[prime[i]]+N-1, N-1);

    ans %= mod;

  }

  cout<<ans<<endl;

}
// Slower C++ solution:
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



ll frac[200000];



ll comb(ll a, ll b) {

  ll ue = frac[a], sh1=1, sh2=1;

  ll tsh1, tsh2;

  ll two, h;

  h = mod - 2;

  while(h>0) {

    two = 1;

    tsh1 = frac[b];

    tsh2 = frac[a-b];

    while(2*two<h) {

      two *= 2;

      tsh1 *= tsh1;

      tsh2 *= tsh2;

      tsh1 %= mod;

      tsh2 %= mod;

    }

    h -= two;

    sh1 *= tsh1;

    sh2 *= tsh2;

    sh1 %= mod;

    sh2 %= mod;

  }

  return ue*sh1%mod*sh2%mod;

}



int main() {

  frac[0] = 1;

  for(ll i=1;i<200000;++i) frac[i] = frac[i-1]*i%mod;

  ll N, M;

  cin>>N>>M;

  vector<ll> prime;

  map<ll, int> amap;

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

    if(M%i==0) prime.push_back(i);

    while(M%i==0) {

      amap[i]++;

      M /= i;

    }

  }

  if(M>1) {

    prime.push_back(M);

    amap[M]++;

  }

  ll ans = 1;

  for(int i=0;i<prime.size();++i) {

    ans *= comb(amap[prime[i]]+N-1, amap[prime[i]]);

    ans %= mod;

  }

  cout<<ans<<endl;

}




// Faster C++ solution for the same problem (measured speedup: 1.4426131122688128x):
#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<cstring>

#include<vector>

#include<list>

#include<algorithm>

#include<map>

#include<set>

#include<queue>

#include<stack>

using namespace std;

typedef long long ll;

#define fi first

#define se second

#define mp make_pair

#define rep(i, n) for(int i=0;i<n;++i)

#define rrep(i, n) for(int i=n;i>=0;--i)

const int inf=1e9+7;

const ll mod=1e9+7;

const ll mod1=998244353;

const ll big=1e18;

const double PI=2*asin(1);



ll frac[100100];



ll comb(ll a, ll b) {

  ll ue = frac[a];

  ll sh1, sh2;

  ll h=mod-2;

  ll two;

  while(h>0) {

    two = 1;

    sh1 = frac[b];

    sh2 = frac[a-b];

    while(2*two<h) {

      two *= 2;

      sh1 *= sh1;

      sh1 %= mod;

      sh2 *= sh2;

      sh2 %= mod;

    }

    h -= two;

    ue *= sh1;

    ue %= mod;

    ue *= sh2;

    ue %= mod;

  }

  return ue;

}



int main() {

  frac[0] = 1;

  for(ll i=1;i<100100;++i) frac[i] = frac[i-1]*i%mod;

  ll N, M;

  cin>>N>>M;

  vector<ll> prime;

  map<ll, ll> amap;

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

    if(M%i==0) prime.push_back(i);

    while(M%i==0) {

      amap[i]++;

      M /= i;

    }

  }

  if(M>1) prime.push_back(M);

  amap[M]++;

  ll ans = 1;

  for(int i=0;i<prime.size();++i) {

    ans *= comb(amap[prime[i]]+N-1, N-1);

    ans %= mod;

  }

  cout<<ans<<endl;

}
// 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.73532620273402x):
#include<bits/stdc++.h>

using namespace std;



#define Abigail inline void

typedef long long LL;



const int N=100000,C=30,mod=1000000007;



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

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

int mul(int a,int b){return (LL)a*b%mod;}

void sadd(int &a,int b){a=add(a,b);}

void ssub(int &a,int b){a=sub(a,b);}

void smul(int &a,int b){a=mul(a,b);}



int n,m;

int pr[C+9],cnt[C+9],cp;



void Get_pr(int n){

  int now=n;

  for (int i=2;i*i<=n;++i)

    if (now%i==0)

    	for (pr[++cp]=i;now%i==0;now/=i) ++cnt[cp];

  if (now>1) pr[++cp]=now,cnt[cp]=1;

}



int inv[N+C+9],fac[N+C+9],ifac[N+C+9];



void Get_inv(int n){

  inv[1]=1;

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

	ifac[0]=ifac[1]=1;

  for (int i=2;i<=n;++i){

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

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

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

	}

}



int Get_c(int n,int m){return mul(fac[n],mul(ifac[m],ifac[n-m]));}



int ans;



Abigail into(){

  scanf("%d%d",&n,&m);

}



Abigail work(){

  Get_pr(m);

  Get_inv(n+C);

  ans=1;

  for (int i=1;i<=cp;++i)

    smul(ans,Get_c(n+cnt[i]-1,cnt[i]));

}



Abigail outo(){

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

}



int main(){

  into();

  work();

  outo();

  return 0;

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

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;

}


// Faster C++ solution for the same problem (measured speedup: 1.516427502839895x):
#include<bits/stdc++.h>

using namespace std;



#define Abigail inline void

typedef long long LL;



const int N=100000,C=30,mod=1000000007;



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

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

int mul(int a,int b){return (LL)a*b%mod;}

void sadd(int &a,int b){a=add(a,b);}

void ssub(int &a,int b){a=sub(a,b);}

void smul(int &a,int b){a=mul(a,b);}



int n,m;

int pr[C+9],cnt[C+9],cp;



void Get_pr(int n){

  int now=n;

  for (int i=2;i*i<=n;++i)

    if (now%i==0)

    	for (pr[++cp]=i;now%i==0;now/=i) ++cnt[cp];

  if (now>1) pr[++cp]=now,cnt[cp]=1;

}



int inv[N+C+9],fac[N+C+9],ifac[N+C+9];



void Get_inv(int n){

  inv[1]=1;

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

	ifac[0]=ifac[1]=1;

  for (int i=2;i<=n;++i){

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

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

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

	}

}



int Get_c(int n,int m){return mul(fac[n],mul(ifac[m],ifac[n-m]));}



int ans;



Abigail into(){

  scanf("%d%d",&n,&m);

}



Abigail work(){

  Get_pr(m);

  Get_inv(n+C);

  ans=1;

  for (int i=1;i<=cp;++i)

    smul(ans,Get_c(n+cnt[i]-1,cnt[i]));

}



Abigail outo(){

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

}



int main(){

  into();

  work();

  outo();

  return 0;

}
// 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.921504204527509x):
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+20 , SIZE = 1020 , Mod = 1e9+7;

int n,m,p[SIZE],a[SIZE],cnt,fac[2*N],inv[2*N],Max,ans;

inline int quickpow(int a,int b)

{

    int res = 1;

    for (;b;a=1LL*a*a%Mod,b>>=1)

        if ( 1 & b ) res = 1LL * res * a % Mod;

    return res;

}

inline int C(int a,int b) { return 1LL * fac[a] * inv[b] % Mod * inv[a-b] % Mod; }

int main(void)

{

    scanf("%d%d",&n,&m);

    int val = m;

    for (int i=2;i*i<=val;i++)

        if ( m % i == 0 )

        {

            p[++cnt] = i;

            while ( m % i == 0 )

                m /= i , Max = max( Max , ++a[cnt] );

        }

    if ( m > 1 ) p[++cnt] = m , Max = max( Max , a[cnt] = 1 );

    fac[0] = inv[0] = 1LL;

    for (int i=1;i<=n+Max;i++)

        fac[i] = 1LL * fac[i-1] * i % Mod;

    inv[n+Max] = quickpow( fac[n+Max] , Mod-2 );

    for (int i=n+Max-1;i>=1;i--)

        inv[i] = 1LL * inv[i+1] * ( i + 1 ) % Mod;

    ans = 1LL;

    for (int i=1;i<=cnt;i++)

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

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

    return 0;

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

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;

}


// Faster C++ solution for the same problem (measured speedup: 1.6791205123147803x):
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+20 , SIZE = 1020 , Mod = 1e9+7;

int n,m,p[SIZE],a[SIZE],cnt,fac[2*N],inv[2*N],Max,ans;

inline int quickpow(int a,int b)

{

    int res = 1;

    for (;b;a=1LL*a*a%Mod,b>>=1)

        if ( 1 & b ) res = 1LL * res * a % Mod;

    return res;

}

inline int C(int a,int b) { return 1LL * fac[a] * inv[b] % Mod * inv[a-b] % Mod; }

int main(void)

{

    scanf("%d%d",&n,&m);

    int val = m;

    for (int i=2;i*i<=val;i++)

        if ( m % i == 0 )

        {

            p[++cnt] = i;

            while ( m % i == 0 )

                m /= i , Max = max( Max , ++a[cnt] );

        }

    if ( m > 1 ) p[++cnt] = m , Max = max( Max , a[cnt] = 1 );

    fac[0] = inv[0] = 1LL;

    for (int i=1;i<=n+Max;i++)

        fac[i] = 1LL * fac[i-1] * i % Mod;

    inv[n+Max] = quickpow( fac[n+Max] , Mod-2 );

    for (int i=n+Max-1;i>=1;i--)

        inv[i] = 1LL * inv[i+1] * ( i + 1 ) % Mod;

    ans = 1LL;

    for (int i=1;i<=cnt;i++)

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

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

    return 0;

}
// 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.9701687644644588x):
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<math.h>

#include<algorithm>

#include<queue>

#include<set>

#include<map>

#include<iostream>

using namespace std;

#define ll long long

#define REP(a,b,c) for(int a=b;a<=c;a++)

#define re register

#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)

typedef pair<int,int> pii;

#define mp make_pair

inline int gi()

{

	int f=1,sum=0;char ch=getchar();

	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}

	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}

	return f*sum;

}

const int N=50,Mod=1e9+7;

int n,m,stk[N],f[100010][N],top;

int main()

{

	n=gi();m=gi();

	for(int i=2;i*i<=m;i++)

		if(m%i==0)

		{

			top++;int s=0;

			while(m%i==0)

			{

				s++;m/=i;

			}

			stk[top]=s;

		}

	if(m!=1)stk[++top]=1;

	f[0][0]=1;

	for(int i=1;i<=n;i++)

		for(int j=0;j<=40;j++)

			for(int k=0;k<=j;k++)f[i][j]=(f[i-1][j-k]+f[i][j])%Mod;

	ll ans=1;

	for(int i=1;i<=top;i++)ans=1ll*ans*f[n][stk[i]]%Mod;

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

	return 0;

}