#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の計算

int mod = 1000000007;

ll mod_adjust(ll a) {//	余りをとる(0～mod-1に調整する)
	if (a >= mod) {
		return a % mod;
	}
	if (a < 0) {
		a *= -1;
		a %= mod;
		return mod - a;
	}
	return a;
}
int mod_add(int a, int b) {//	足し算
	ll k = mod_adjust((ll)a); k += mod_adjust((ll)b);
	k = mod_adjust(k);
	return (int)k;
}
int mod_sub(int a, int b) {//	引き算
	return mod_add(a, -b);
}
int mod_multi(int a, int b) {//	掛け算
	ll k = mod_adjust((ll)a);
	k *= mod_adjust((ll)b);
	k = mod_adjust(k);
	return (int)k;
}
int mod_inv(int a) {//	逆元
	ll k = (int)mod_adjust((ll)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 (int)mod_adjust(n);
}
int mod_div(int a, int b) {//	割り算
	return mod_multi(a, mod_inv(b));
}
int mod_pow(int x, int n) {//	累乗(logNオーダーなので速い)
	x = (int)mod_adjust((ll)x);
	n = n % (mod - 1);
	if (n < 0) {
		return mod_pow(mod_div(1, x), -n);
	}
	if (n == 0) {
		return 1;
	}
	if (n == 1) {
		return (int)mod_adjust((ll)x);
	}
	if (n % 2 == 0) {
		int k = mod_pow(x, n / 2);
		return mod_multi(k, k);
	}
	else {
		int k = mod_pow(x, n / 2);
		return mod_multi(mod_multi(k, k), x);
	}
}

int* factorial = NULL;			//	階乗
int* factorial_inv = NULL;		//	階乗の逆元

//	階乗を事前に計算しておく関数。
//	Nはmod_combination(n, r)で呼び出されうる最大の数。
void calc_factorial(int N) {////////////////////////// 初めに必ず呼び出すこと！！！
	N = min(mod - 1, N);
	factorial = new int[N + 1];
	factorial_inv = new int[N + 1];

	factorial[0] = 1;
	factorial_inv[0] = 1;
	for (int i = 1; i <= N; i++) {
		factorial[i] = mod_multi(factorial[i - 1], i);
		factorial_inv[i] = mod_inv(factorial[i]);
	}
}
int mod_combination(int n, int 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_inv[n - r], factorial_inv[r]));
}


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() {
	calc_factorial(101000);
	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: 1024