// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <vector>

#include <set>

#include <unordered_set>

#include <cmath>

#include <algorithm>

#include <numeric>

#include <cassert>

#include <utility>



using namespace std;

using lli = long long int;

// #define DEBUG

#ifdef DEBUG

#define debug(var) cout << (#var) << ": " << (var) << endl;

template<class T> void dump_array_impl(const T& a) {

  bool first = true;

  for (auto&& x : a) {

    if (!first) { cout << ", "; first = false; }

    cout << x;

  }

}

#define debug_array(a) cout<<(#a)<<": ";dump_array_impl(a);cout<<endl

#else

#define debug(var) {}

#define debug_array(a) {}

#endif

template<class T> void read_n(vector<T>& v, size_t n) {

  v = vector<T>(n);

  for (lli i=0; i<n; ++i) cin >> v[i];

}



vector<lli> factmem, factinvmem;

lli n, m, mod = 1e9 + 7;



lli fact(lli n) {

  if (factmem[n] == 0) factmem[n] = n * fact(n-1) % mod;

  return factmem[n];

}



lli modinv(lli a) {

  lli b = mod, u = 1, v = 0;

  while (b) {

    lli t = a / b;

    a -= t * b; swap(a, b);

    u -= t * v; swap(u, v);

  }

  u %= mod;

  if (u < 0) u += mod;

  return u;

}



lli factinv(lli n) {

  if (factinvmem[n] == 0) factinvmem[n] = modinv(fact(n));

  return factinvmem[n];

}



lli conb(lli n, lli k) {

  return fact(n) * (factinv(k) * factinv(n - k) % mod) % mod;

}



int main() {

  factmem = vector<lli>(200000, 0);

  factinvmem = vector<lli>(200000, 0);

  factmem[0] = 1;



  cin >> n >> m;

  lli lim = sqrt((double)m);

  lli mm = m;

  lli ans = 1;

  for (lli i=2; i <= lim; ++i) {

    lli cnt = 0;

    while (mm % i == 0) {

      mm /= i;

      ++cnt;

    }

    if (cnt > 0) {

      ans = ans * conb(cnt + n - 1, n - 1) % mod;

    }

  }

  if (mm > 1) ans = ans * conb(1 + n - 1, n - 1) % mod;

  cout << ans << endl;

  

  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.4395795841494237x):
#include <iostream>

#include <cstdio>

#include <cstring>

#include <vector>

#include <deque>

#include <queue>

#include <array>

#include <set>

#include <map>

#include <cmath>

#include <algorithm>

#include <numeric>

#include <utility>

#include <tuple>

#include <functional>

#include <bitset>

#include <cstdint>

#include <cassert>



using namespace std;

using i64 = int64_t;

using i32 = int32_t;

template<class T, class U> void init_n(vector<T>& v, size_t n, U x) 

{ v = vector<T>(n, x); }

template<class T> void init_n(vector<T>& v, size_t n) { init_n(v, n, T()); }

template<class T> void read_n(vector<T>& v, size_t n, size_t o = 0) 

{ v = vector<T>(n+o); for (size_t i=o; i<n+o; ++i) cin >> v[i]; }

template<class T> void read_n(T a[], size_t n, size_t o = 0)

{ for (size_t i=o; i<n+o; ++i) cin >> a[i]; }

template<class T> T gabs(const T& x) { return max(x, -x); }

#define abs gabs



const i64 mod = 1e9 + 7;

i64 fact_memo[200001];

i64 fact(i64 x) {

  if (x == 0) return 1;

  if (fact_memo[x]) return fact_memo[x];

  return fact_memo[x] = x * fact(x - 1) % mod;

}

i64 ipow(i64 a, i64 b) {

  return (b & 1 ? a : 1) * (b > 1 ? ipow(a * a % mod, b >> 1) : 1) % mod;

}

i64 inv(i64 x) {

  return ipow(x, mod - 2);

}

i64 fact_inv(i64 x) {

  return inv(fact(x));

}

i64 perm(i64 a, i64 b) {

  return fact(a) * fact_inv(a - b) % mod;

}

i64 conb(i64 a, i64 b) {

  return fact(a) * fact_inv(b) % mod * fact_inv(a - b) % mod;

}



i64 n, m;

int main() {

  cin >> n >> m;

  map<i64, i64> fs;

  for (i64 x = 2; x <= min(n, i64(40000)); ++x) {

    while (m % x == 0) {

      cerr << x << endl;

      fs[x]++;

      m /= x;

    }

  }

  if (m > 1) fs[m]++;

  i64 ans = 1;

  for (auto p : fs) {

    i64 k = p.second;

    ans = ans * conb(k + n - 1, k) % mod;

  }

  cout << ans << endl;

  return 0;

}