#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <bitset>
#include <numeric> //lcm
#include <iomanip> //double精度 setprecision

using namespace std;

#define rep(i,n) for(int i = 0; i < (n); ++i)
#define rrep(i,n) for(int i = n-1; i >= 0; --i)
#define rep1(i,n) for(int i = 1; i <= (n); ++i)
#define all(vec) (vec).begin(),(vec).end()

#define debug(vec) for(auto v : vec) cout << v << " "; cout << endl;
#define debug2D(vec2D) for(auto vec : vec2D) { for (auto v : vec) cout << v << " "; cout << endl; } 
#define debugP(vec) for(auto v : vec) cout << "(" << v.first << "," << v.second << ") "; cout << endl;
#define debug2DP(vec2D) for(auto vec : vec2D) { for (auto v : vec) cout << "(" << v.first << "," << v.second << ") "; cout << endl; } 

typedef long long ll;

constexpr ll INF = 1000000000; //10^10
//const ll MOD = 998244353;
constexpr ll MOD = 1000000007;

template<class T>inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } else return false; }
template<class T>inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } else return false; }

struct ModInt {
	ModInt(ll n) : mInt(n) {};
	//~ModInt(){};
	ll mInt;
	static ll mMod;
	//todo
	ModInt& operator=(const ModInt& a) { mInt = a.mInt; return *this; }
	ModInt& operator+=(const ModInt& a) { mInt += a.mInt; mInt %= mMod; return *this; }
	ModInt& operator-=(const ModInt& a) { mInt -= a.mInt; if (mInt < 0) mInt += mMod; return *this; }
	ModInt& operator*=(const ModInt& a) { mInt *= a.mInt; mInt %= mMod; return *this; }
	ModInt operator+(const ModInt a) { return ModInt(mInt + a.mInt % mMod); }
	ModInt operator-(const ModInt a) { return ModInt(mInt - a.mInt < 0 ? mInt - a.mInt + mMod : mInt - a.mInt); }
	ModInt operator*(const ModInt a) { return ModInt(mInt * a.mInt % mMod); }
	ModInt& operator=(const ll& a) { mInt = a; return *this; }
	ModInt& operator+=(const ll& a) { mInt += a; mInt %= mMod; return *this; }
	ModInt& operator-=(const ll& a) { mInt -= a; if (mInt < 0) mInt += mMod; return *this; }
	ModInt& operator*=(const ll& a) { mInt *= a; mInt %= mMod; return *this; }
	ModInt operator+(const ll a) { return ModInt(mInt + a % mMod); }
	ModInt operator-(const ll a) { return ModInt(mInt - a < 0 ? mInt - a + mMod : mInt - a); }
	ModInt operator*(const ll a) { return ModInt(mInt * a % mMod); }
	ModInt operator++() { return ModInt(++mInt % mMod); }
	ModInt operator--() { return ModInt(++mInt % mMod); }
	bool operator==(ModInt a) { return mInt == a.mInt; }
	bool operator!=(ModInt a) { return mInt != a.mInt; }
	friend ostream& operator<<(ostream& os, const ModInt& n) {
		os << n.mInt;
		return os;
	}
	void setMod(ll mod) {
		ModInt::mMod = mod;
	}
};

ll ModInt::mMod = MOD;

ModInt modpow(ModInt a, int b) {
	ModInt ret = 1;
	while (b > 0) {
		if (b & 1) ret *= a;
		a *= a;
		b >>= 1;
	}
	return ret;
}

ModInt modinv(ModInt n) {
	return modpow(n, n.mMod - 2);
}

ModInt modfact(int n) {
	ModInt fac = 1;
	for (int i = n; i > 0; --i) fac *= i;
	return fac;
}

ModInt modcomb(ll n, ll r) {
	ModInt com = 1;
	if (n / 2 < r) return modcomb(n, n - r);
	else {
		for (int i = 0; i < r; ++i)
			com *= n - i;
		return com * modinv(modfact(r));
	}
}

map<ll, int> primeFactor(ll n) {
	map<ll, int> ret;

	while (n % 2 == 0) {
		n /= 2;
		++ret[2];
	}

	int i = 3;
	while (n > 1 && (ll)i * i <= n) {
		while (n % i == 0) {
			n /= i;
			++ret[i];
		}

		i += 2;
	}

	if (n != 1) ++ret[n];

	return ret;
}

int main() {
	ll n, m;
	cin >> n >> m;
  
	map<ll,int> f;

	f = primeFactor(m);

	ModInt ans(1);
	for (auto pe : f) {
		ans *= modcomb((ll)pe.second + n - 1, pe.second);
	}

	cout << ans << endl;
}


Measured memory_bytes: 256