stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include<iostream>

#include<algorithm>

#include<vector>

#include<queue>

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

#define mod 1000000007

typedef long long ll;



using namespace std;

#define N 100010

ll n,a[N];

ll f[N],g[N],h[N],cs[N];

int main(){

    cin>>n;lol(i,n)cin>>a[i];

    f[0]=1;

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

    g[n+1]=1;

    for(ll i=n;i>=1;i--)g[i]=g[i+1]*i%mod;

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

	h[i+1]=f[i]*g[i+2]%mod;

    }h[1]=g[2];

    cs[0]=cs[1]=0;

    for(ll i=2;i<N;i++)cs[i]=(cs[i-1]+h[i])%mod;

    ll ans=0;

    lol(i,n){

	ll cur=cs[i+1]+cs[n-i]+h[1];

	ans=(ans+cur*a[i])%mod;

    }

    cout<<ans<<endl;

    return 0;

}


// Optimized solution to the same problem (faster):
#include<iostream>

#include<algorithm>

#include<vector>

#include<queue>

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

#define mod 1000000007

typedef long long ll;

using namespace std;

#define N 100010

ll n,a[N];

ll f[N],g[N];

ll val[N],cs[N];

int main(){

    cin>>n;

    lol(i,n)cin>>a[i];

    f[0]=1;

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

    g[n+1]=1;

    for(ll i=n;i>=1;i--)g[i]=g[i+1]*i%mod;

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

	val[i]=f[i-1]*g[i+1]%mod;

    }

    val[1]=g[2];

    cs[0]=cs[1]=0;

    for(ll i=2;i<=n;i++)cs[i]=(cs[i-1]+val[i])%mod;

    ll ans=0;

    lol(i,n){

	ll cur=cs[i+1]+cs[n-i]+val[1];

	ans=(ans+cur*a[i])%mod;

    }

    return cout<<ans<<endl,0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
//此程序使用了qt专属名称，请勿模仿。侵权必究！！！

//我真是太菜了…… 

#include<bits/stdc++.h>

using namespace std;

#define ll long long

const ll N=20,P=1e9+7;

ll n,m,ans=1,a[1<<N]={1};

inline ll read()

{

	ll sum=0,flag=1;

	char c;

	for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1;

	for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0';

	return sum*flag;

}

inline ll pow(ll x,ll y)

{

	ll k=1;

	while(y)

	{

		if(y&1)

		{

			k*=x;

			k%=P;

		}

		y>>=1;

		x*=x;

		x%=P;

	}

	return k;

}

int main()

{

//	freopen("a.in","r",stdin);

//	freopen("a.out","w",stdout);

	n=read();

	m=read();

	for(int i=1;i<=1<<(N-1);++i)

	{

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

	}

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

	{

		if(!(m%i))

		{

			ll k=0;

			while(!(m%i))

			{

				++k;

				m/=i;

			}

			ans*=a[n+k-1]%P*pow(a[n-1],P-2)%P*pow(a[k],P-2)%P;

			ans%=P;

		}

	}

	if(m>1)

	{

		ans*=n;

		ans%=P;

	}

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

	return 0;

}






// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define ll long long



const ll MOD = 1e9+7;

ll n, m, ans = 1, cnt=0, tot=0, sum[100050];



void getprime(){

	for(ll i = 2; i <= m; i++){

		if(m % i == 0){

			m /= i;

			sum[++cnt]++;

			while(m % i == 0)  

				m /= i, sum[cnt]++;

			tot += sum[cnt];

		}

	}

	if(m != 1) sum[++cnt] = 1, tot++;

}



ll inv(ll x){

    return x==1 ? 1 : (MOD-MOD/x)*inv(MOD%x)%MOD;

}

ll C(ll n,ll m){

    if(m<0 || n<m) return 0;

    if(m > n-m)  m = n-m;

    ll zi = 1, mu = 1;

    for(ll i = 0; i < m; i++){

        zi = zi *(n-i) %MOD;

        mu = mu *(i+1) %MOD;

    }

    return zi*inv(mu)%MOD;

}



int main(){

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

	getprime();

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

		ans *= C(sum[i]+n-1, n-1);

		ans %= MOD;

	}

	printf("%lld", ans);

	return 0;

} 

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



typedef long long ll;



const int N = 2e5 + 5;

const ll mod = 1e9 + 7;



ll fact[N];

int n, m;



ll bigmod(ll p, ll q) {

  ll res = 1;

  while(q > 0) {

    if(q & 1) {

      res = (res * p) % mod;

    }

    q >>= 1;

    p = (p * p) % mod;

  }

  return res;

}



ll inverse(ll p) {

  return bigmod(p, mod - 2);

}



ll ncr(ll p, ll q) {

  if(p < q or p < 0 or q < 0) return 0;

  ll up = fact[p];

  ll down = ((fact[q] % mod) * (fact[p - q] % mod)) % mod;

  return ((up % mod) * inverse(down)) % mod;

}



int main() {

  fact[0] = fact[1] = 1;

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

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

  }

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

  vector <int> prime;

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

    if(m % i == 0) {

      int cnt = 0;

      while(m % i == 0) {

        m /= i;

        cnt++;

      }

      prime.push_back(cnt);

    }

  }

  if(m > 1) {

    prime.push_back(1);

  }

  ll ans = 1ll;

  for(auto c : prime) {

    ans = (ans * ncr(n + c - 1, c)) % mod;

  }

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

  return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define ll long long



const ll MOD = 1e9+7;

ll n, m, ans = 1, cnt=0, tot=0, sum[100050];



void getprime(){

	for(ll i = 2; i <= m; i++){

		if(m % i == 0){

			m /= i;

			sum[++cnt]++;

			while(m % i == 0)  

				m /= i, sum[cnt]++;

			tot += sum[cnt];

		}

	}

	if(m != 1) sum[++cnt] = 1, tot++;

}



ll inv(ll x){

    return x==1 ? 1 : (MOD-MOD/x)*inv(MOD%x)%MOD;

}

ll C(ll n,ll m){

    if(m<0 || n<m) return 0;

    if(m > n-m)  m = n-m;

    ll zi = 1, mu = 1;

    for(ll i = 0; i < m; i++){

        zi = zi *(n-i) %MOD;

        mu = mu *(i+1) %MOD;

    }

    return zi*inv(mu)%MOD;

}



int main(){

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

	getprime();

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

		ans *= C(sum[i]+n-1, n-1);

		ans %= MOD;

	}

	printf("%lld", ans);

	return 0;

} 

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define ll long long

using namespace std;

const int mod=1e9+7;

int n,m,sum=0;

int p[100005];

ll fuc[101105],inv[101105];

ll ans=1;

ll pow2(ll a,ll b)

{

	ll ans=1;

	while(b)

	{

		if(b%2) ans=ans*a%mod;

		b/=2; a=a*a%mod;

	}

	return ans;

}

void divide(int x)

{

    sum=0;

	for(int i=2;i<=sqrt(x);i++)

	{

		if(x%i==0)

		{

			sum++;

			while(x%i==0)

			{

				x/=i;

				p[sum]++;

			}

		}

	}

	if(x>1)

	{

		p[++sum]++;

	}

}

int main()

{

//freopen(".in","r",stdin);

//freopen(".out","w",stdout);

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

  divide(m); 

  fuc[1]=1;

  for(int i=2;i<=101000+100;i++)

    fuc[i]=(ll)(fuc[i-1]*i)%mod;

  inv[101000+100]=pow2(fuc[101000+100],mod-2);

  inv[0]=1;

  for(int i=101000+99;i>=1;i--)

    inv[i]=(ll)(inv[i+1]*(i+1))%mod;

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

  {

  	ans=(ll)ans*(ll)(fuc[p[i]-1+n]%mod*inv[n-1]%mod*inv[p[i]]%mod)%mod;

  	ans=ans%mod;

  }

  cout<<ans<<endl;

  return 0;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

#define ll long long



const ll MOD = 1e9+7;

ll n, m, ans = 1, cnt=0, tot=0, sum[100050];



void getprime(){

	for(ll i = 2; i <= m; i++){

		if(m % i == 0){

			m /= i;

			sum[++cnt]++;

			while(m % i == 0)  

				m /= i, sum[cnt]++;

			tot += sum[cnt];

		}

	}

	if(m != 1) sum[++cnt] = 1, tot++;

}



ll inv(ll x){

    return x==1 ? 1 : (MOD-MOD/x)*inv(MOD%x)%MOD;

}

ll C(ll n,ll m){

    if(m<0 || n<m) return 0;

    if(m > n-m)  m = n-m;

    ll zi = 1, mu = 1;

    for(ll i = 0; i < m; i++){

        zi = zi *(n-i) %MOD;

        mu = mu *(i+1) %MOD;

    }

    return zi*inv(mu)%MOD;

}



int main(){

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

	getprime();

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

		ans *= C(sum[i]+n-1, n-1);

		ans %= MOD;

	}

	printf("%lld", ans);

	return 0;

} 

// Fastest known solution for this problem:
// Original C++ solution (slower):
				#include <bits/stdc++.h>

				using namespace std;

				#define ll long long

				#define mod 1000000007

				#define pll pair<long,long>

				#define se second

				#define fi first

				#define pb push_back

				#include <ext/pb_ds/assoc_container.hpp>

				#include <ext/pb_ds/tree_policy.hpp>

				using namespace __gnu_pbds;



				typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;

				typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update>pllordered_set;

				

				const ll INF=(ll)1e18;

				ll fac[300050];

				

				ll binpow(ll a,ll b,ll m)

				{

					a%=m;

					ll ans=1;

					while(b)

					{

						if(b&1)

							ans=ans*a%m;

						a=a*a%m;

						b=b>>1;

					}

					return ans;

					

				}

				ll mod_inverse(ll n)

				{

					return binpow(n,mod-2,mod);

				}

				

				ll C(ll n,ll r)

				{

					return fac[n]*mod_inverse(fac[r])%mod * mod_inverse(fac[n-r])%mod;

				}

				

				int main()

				{

					ios_base::sync_with_stdio(false);

					cin.tie(NULL);

					fac[0]=1;

					

					for(ll i=1;i<=300005;i++)

						fac[i]=(i*fac[i-1])%mod;

					

					

					

					ll n,m;

					cin>>n>>m;

					ll ans=1;

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

					{

						ll cnt=0;

						while(m%i==0)

						{

								cnt++;

								m=m/i;

						}

						ans=ans*C(cnt+n-1,n-1);

						ans%=mod;

					}

					if(m>1)

					{

						ans*=C(1+n-1,n-1);

						ans%=mod;

					}

						cout<<ans;

				}

				


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



using namespace std;



typedef long long          ll;

typedef unsigned long long ull;

typedef vector<int>	       vi;

typedef vector<bool>       vb;

typedef map<int, int>      mii;

typedef pair<int, int>     ii;



#define INF                0x3f3f3f3f

#define INFLL              0x3f3f3f3f3f3f3f3f

#define each(x, s)         for(auto& x : s)

#define loop(x)	           for(int i = 0;i < x;i++)

#define vloop(v, x)        for(int v = 0;v < x;v++)

#define avg(l, r)          l + (r - l) / 2

#define iter(a)            a.begin(), a.end()

#define riter(a)           a.rbegin(), a.rend()

#define endl               "\n"



const ll mod = 1000000007;



mii fats(int x) {

	mii fs;

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

		while (x % i == 0) {

			fs[i]++;

			x /= i;

		}

	}

	if (x > 1) fs[x]++;

	return fs;

}



pair<ll, ll> eucl(ll a, ll b) {

	if (b == 0) return make_pair(1ll, 0ll);

	ll x, y;

	tie(x, y) = eucl(b, a % b);

	return make_pair(y, x - a / b * y);

}



ll inv(ll a) {

	ll x;

	tie(x, ignore) = eucl(a, mod);

	return (x % mod + mod) % mod;

}



ll choose(ll n, ll k) {

	k = min(k, n - k);

	ll a = 1, b = 1;

	loop(k) {

		a *= n - i;

		b *= i + 1;

		a %= mod;

		b %= mod;

	}

	return a * inv(b) % mod;

}



int main() {

	ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);



	int n, m;

	cin >> n >> m;

	mii fs = fats(m);

	ll ans = 1;

	each(p, fs) {

		ans *= choose(p.second + n - 1, n - 1);

		ans %= mod;

	}

	cout << ans << endl;

	return 0;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}




// Optimized solution to the same problem (faster):
#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;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}




// Optimized solution to the same problem (faster):
#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;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
/*

  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;

}


// Optimized solution to the same problem (faster):
#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;

}


// Fastest known solution for this problem: