#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <bitset>

using namespace std;
typedef long long ll;

/////////////         modの計算

#define MOD_IS_PRIME
const ll mod = 1000000007LL;

inline ll mod_adjust(ll a) {//	余りをとる(0～mod-1に調整する)
	if (a >= mod) {
		return a % mod;
	}
	if (a < 0) {
		a *= -1;
		a--;
		if (a >= mod) { a %= mod; }
		a++;
		return mod - a;
	}
	return a;
}
inline ll mod_add(ll a, ll b) {//	足し算
	return mod_adjust(a % mod + b % mod);
}
inline ll mod_sub(ll a, ll b) {//	引き算
	return mod_adjust(a % mod - b % mod);
}
inline ll mod_multi(ll a, ll b) {//	掛け算
	return mod_adjust(mod_adjust(a) * mod_adjust(b));
}
inline ll mod_inv(ll a) {//	逆元
	ll k = mod_adjust(a);
	if (k == 0) { return 0; }
	if (k == 1) { return 1; }
	ll p = mod, q = k, m = 0, n = 1, r, c;

	while (q > 1) {
		r = p % q;
		c = p / q;
		c = mod_adjust(m - n * c);
		p = q, m = n, q = r, n = c;
	}
	return mod_adjust(n);
}
inline ll mod_div(ll a, ll b) {//	割り算
	return mod_multi(a, mod_inv(b));
}
inline ll mod_pow(ll x, ll n) {//	累乗(logNオーダーなので速い)
	if (n < 0) {
		return mod_pow(mod_inv(x), -n);
	}

#ifdef MOD_IS_PRIME
	n = n % (mod - 1);
#endif

	if (n == 0) {
		return 1;
	}
	if (n == 1) {
		return mod_adjust(x);
	}
	if (n % 2 == 0) {
		ll k = mod_pow(x, n / 2);
		return mod_multi(k, k);
	}
	else {
		ll k = mod_pow(x, n / 2);
		return mod_multi(mod_multi(k, k), x);
	}
}

inline ll factorial(ll n, bool inverse = false) {//	階乗を計算する
	static vector<ll> factorial, factorial_inv, inv;

	ll M = factorial.size();
	if (M <= n) {
		if (M == 0) { factorial.push_back(1); factorial_inv.push_back(1); inv.push_back(1); M++; }
		if (M == 1) { factorial.push_back(1); factorial_inv.push_back(1); inv.push_back(1); M++; }

		for (ll i = M; i <= n; i++) {
			factorial.push_back(mod_multi(factorial.back(), i));
			ll p = mod / i;
			ll q = mod - (p * i);
			inv.push_back(mod_multi(-p, inv[q]));
			factorial_inv.push_back(mod_multi(factorial_inv.back(), inv.back()));
		}
	}
	if (inverse == true) {
		return factorial_inv[n];
	}
	else {
		return factorial[n];
	}
}
inline ll mod_combination(ll n, ll r) {//	nCr	を計算する
	if (n < 0 || r < 0 || r > n) { return 0; }
	if (n >= mod) { return 0; }
	if (r < 0) { return 0; }

	return mod_multi(factorial(n), mod_multi(factorial(n - r, true), factorial(r, true)));
}


inline ll l_sqrt(ll n) {//	誤差無し√nを計算する
	if (n <= 0) { return 0; }

	if (n > 256) {
		ll k = l_sqrt(n / 4) * 2;
		while ((k + 1) * (k + 1) <= n) { k++; }
		return k;
	}
	else {
		for (ll i = 16; i >= 1; i--) {
			if (i * i <= n) { return i; }
		}
	}
	return 0;
}
class primeFactorClass {//	素因数分解をする
public:
	primeFactorClass() {
		factorNum = 0;
	}
	~primeFactorClass() {
		reset();
	}

	ll factorNum;// 素因数の個数
	vector<ll> prime;// 素因数
	vector<ll> degree;// 次数

	void factorize(ll n) {// 素因数分解
		reset();
		if (n < 0) { n = -n; }
		if (n <= 1) { return; }

		if (n % 2 == 0) {
			factorNum++;
			prime.push_back(2);
			ll count = 0;
			while (n % 2 == 0) { count++; n /= 2; }
			degree.push_back(count);
		}

		ll M = l_sqrt(n) + 1;
		for (ll i = 3; i < M; i += 2) {
			if (n % i == 0) {
				factorNum++;
				prime.push_back(i);
				ll count = 0;
				while (n % i == 0) { count++; n /= i; }
				degree.push_back(count);
				M = l_sqrt(n) + 1;
				if (n == 1) { break; }
			}
		}

		if (n != 1) {
			factorNum++;
			prime.push_back(n);
			degree.push_back(1);
		}
	}

private:
	void reset() {
		factorNum = 0;
		prime.clear();
		degree.clear();
	}
};

int main() {
	ll N, M; cin >> N >> M;
	primeFactorClass p; p.factorize(M);

	ll ans = 1;
	for (auto itr = p.degree.begin(); itr != p.degree.end(); itr++) {
		ans = mod_multi(ans, mod_combination(*itr + N - 1, *itr));
	}

	cout << ans << endl;

	return 0;
}

Measured memory_bytes: 2912