#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>

#ifndef ULLONG
typedef unsigned long long ULLONG;
#endif
#ifndef LLONG
typedef long long LLONG;
#endif
static const ULLONG UL_HUGE_DIVIDER = 1000000007LLU;
static const LLONG LL_HUGE_DIVIDER = 1000000007LL;

//static void ABC111D_RobotArms();
static void ABC110D_Factorization();

#if 1
int main()
{
	//ABC111D_RobotArms();
	ABC110D_Factorization();

	fflush(stdout);
	return 0;
}
#endif


//	素因数分解した結果を map で返す
template <class _Ty> void tp_getPrimes(_Ty targ, std::map<_Ty, _Ty>& primes)
{
	_Ty target = targ;
	_Ty i = 2;
	while ((i * i) <= target) {
		if ((target % i) == 0) {
			target /= i;

			if (primes.find(i) == primes.end()) {
				primes[i] = 1;
			}
			else {
				primes[i] = primes[i] + 1;
			}
		}
		else {
			i++;
		}
	}
	if (target == 1) {
		//	なにもしない
	}
	else if (primes.find(target) == primes.end()) {
		primes[target] = 1;
	}
	else {
		primes[target] = primes[target] + 1;
	}


#if 0
	printf("Target: %d equals\n", targ);
	for (auto it = primes.begin(); it != primes.end(); it++) {
		printf("%d ^ %d\n", it->first, it->second);
	}
#endif
}

template <class _Ty> class PermComb
{
protected:

	_Ty _maxNum = 0;
	_Ty _use_mod = 0;
	_Ty* _fact = 0;
	_Ty* _inv = 0;
	_Ty* _finv = 0;

	PermComb(){}

public:
	PermComb(_Ty maxNum, _Ty use_mod = 0) {
		_maxNum = maxNum;
		_use_mod = use_mod;
		_fact = new _Ty[(unsigned int)maxNum + 1];
		_fact[0] = _fact[1] = 1;

		if (_use_mod) {
			_inv = new _Ty[(unsigned int)maxNum + 1];
			_finv = new _Ty[(unsigned int)maxNum + 1];
			_inv[0] = _inv[1] = 1;
			_finv[0] = _finv[1] = 1;
		}

		for (_Ty i = 2; i <= maxNum; i++) {
			_fact[i] = _fact[i - 1] * i;
			if (_use_mod) {
				_fact[i] %= _use_mod;
				_inv[i] = _use_mod - _inv[_use_mod % i] * (_use_mod / i) % _use_mod;
				_finv[i] = _finv[i - 1] * _inv[i] % _use_mod;
			}
		}
	}

	//	get permutation value
	virtual _Ty GetPermAns(int n, int k) {
		if ((k > _maxNum) || (n > _maxNum) || (k > n) || (k < 0) || (n < 0)) {
			return 0;
		}
		return(_fact[n] / _fact[n - k]);
	}

	//	get combination value
	virtual _Ty GetCombAns(int n, int k) {
		_Ty ans = 0;
		if ((k > _maxNum) || (n > _maxNum) || (k > n) || (k < 0) || (n < 0)) {
			ans = 0;
		}
		else if (_use_mod == 0) {
			ans = GetPermAns(n, k);
			ans /= _fact[k];
		}
		else {
			ans = _fact[n] * (_finv[k] * _finv[n - k] % _use_mod) % _use_mod;
		}
		return ans;
	}

	//	destructor
	~PermComb() {
		delete[] _fact; 
		delete[] _inv;
		delete[] _finv;
	}
};

static void ABC110D_Factorization() 
{
	int N, M;
	scanf(" %d %d", &N, &M);

	std::map<int, int> primes;
	tp_getPrimes<int>(M, primes);

	int expMax = 0;
	for (auto prIt = primes.begin(); prIt != primes.end(); prIt++) {
		expMax = std::max(expMax, prIt->second);
	}
	
	PermComb<LLONG> calc(((LLONG)expMax + N), LL_HUGE_DIVIDER);

	//	N - 1個の仕切りとexpSum 個の次数から N - 1 個選ぶ
	LLONG ans = 1;
	for (auto prIt = primes.begin(); prIt != primes.end(); prIt++) {
		LLONG tmp = calc.GetCombAns(prIt->second + (N - 1), (N - 1));
		ans = ans * tmp % LL_HUGE_DIVIDER;
	}

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


Measured memory_bytes: 2688