#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define rep(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define rrep(i,n) for(int i=1,i##_len=(n); i<=i##_len; ++i)
#define drep(i,n) for(int i=(n)-1; i>=0; --i)
#define srep(i,s,t) for(int i=(s);i<(t);++i)
#define rng(obj) (obj).begin(), (obj).end()
#define rrng(obj) (obj).rbegin(), (obj).rend()
#define maxs(x,y) (x=max((x),(y)))
#define mins(x,y) (x=min((x),(y)))
#define isin(x,l,r) ((l) <= (x) && (x) < (r))
#define pb push_back
#define uni(x) x.erase(unique(rng(x)),x.end())
#define PQ(T) priority_queue<T,v(T),greater<T>>
#define dup(x,y) (((x)+(y)-1)/(y))
#define v(T) vector<T>
#define vv(T) vector<vector<T>>
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vp = vector<pii>;
template <class T> inline istream& operator>>(istream&i,v(T)&v)
{ rep(j,v.size())i>>v[j];return i;}
template <class T> string join(const v(T)&v)
{ stringstream s;rep(i,v.size())s<<' '<<v[i];return s.str().substr(1);}
template <class T> inline ostream& operator<<(ostream&o,const v(T)&v)
{ if(v.size())o<<join(v); return o;}
template <class T1,class T2> inline istream& operator>>(istream&i ,pair<T1,T2>&v)
{ return i>>v.fi>>v.se;}
template <class T1,class T2> inline ostream& operator<<(ostream&o ,pair<T1,T2>&v)
{ return o<<v.fi<<","<<v.se;}
const int INF = 1001001001;
const ll LINF = 1001002003004005006ll;
const double eps = 1e-10;
bool comp(pair<char,int> a,pair<char,int> b){
  return a.se<b.se;
}
//----------------------------------------------------------------

#define fileio ifstream fio; if(argc>=2){ fio.open(argv[1]); std::cin.rdbuf(fio.rdbuf());}
#define fastio ios_base::sync_with_stdio(false);
#define myLoopSet int lp=1; if( argc==3 ){lp = stoi(argv[2]); } for(int i=0;i<lp;++i) 
//----------------------------------------------------------------

const ll mod = 1000000007;
struct mint {
    ll x;
mint(ll x=0):x((x%mod+mod)%mod){}
mint operator-() const {return mint(-x);}
mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
}
mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
}
mint& operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
}
mint operator+(const mint a) const {
    mint res(*this);
    return res+=a;
}
mint operator-(const mint a) const {
    mint res(*this);
    return res-=a;
}
mint operator*(const mint a) const {
    mint res(*this);
    return res*=a;
}
mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
}

// for prime mod
mint inv() const {
    return pow(mod-2);
}
mint& operator/=(const mint a) {
    return (*this) *= a.inv();
}
mint operator/(const mint a) const {
    mint res(*this);
    return res/=a;
}
};

mint Factrial(ll n){
  mint ret = 1;
  for (ll i = 2; i <= n; i++)
  {
    ret *= i;
  }
  return ret;
}

mint Combination(ll n,ll k){
  mint ret =1;
  k = min(n-k, k);
  for (ll i = 1; i <= k; i++)
  {
    ret *= (n-i+1); 
    ret /= i;
  }
  return ret;
}

mint MultiChooseCombination(ll n,ll k){
  return Combination(n+k-1 , min(n,k-1));
}

// 素因数分解
template <class T>
map< T, int > PrimeFactor(T n) {
    map< T, int > ret;
    for(T i = 2; i * i <= n; i++) {
        while(n % i == 0) {
            ret[i]++;
            n /= i;
        }
    }
    if(n != 1) ret[n] = 1;
    return ret;
}


void Main(){
  ll n,m;
  cin>>n>>m;
  auto mp = PrimeFactor(m);
  mint ans(1);
  for(auto m:mp)
    ans*= MultiChooseCombination(m.second,n);
  cout<<ans.x<<endl;

} int main(int argc,char* argv[]){ 
    fastio; fileio; myLoopSet Main();}

Measured memory_bytes: 256