Language: C++

#include <bits/stdc++.h>

using namespace std;
#ifdef _DEBUG
#define _GLIBCXX_DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
typedef __int128_t Int;
#define DBG 1
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define loop(n) rep(loop, (0), (n))
#define all(c) begin(c), end(c)
const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
const double PI = acos(-1);
const double EPS = 1e-9;
#define fi first
#define se second
#define eb emplace_back
using pii = pair<int, int>;
// template<class T> ostream &operator<<(ostream &os,T &t){dump(t);return os;}
template <typename T, typename S>
istream &operator>>(istream &is, pair<T, S> &p) {
  is >> p.first >> p.second;
  return is;
}
template <typename T> void printvv(const vector<vector<T>> &v) {
  cerr << endl;
  rep(i, 0, v.size()) rep(j, 0, v[i].size()) {
    if (typeid(v[i][j]) == typeid(INF) and v[i][j] == INF) {
      cerr << "INF";
    } else
      cerr << v[i][j];
    cerr << (j == v[i].size() - 1 ? '\n' : ' ');
  }
  cerr << endl;
}

#ifndef _DEBUG
#define printvv(...)
#endif
void YES(bool f) { cout << (f ? "YES" : "NO") << endl; }
void Yes(bool f) { cout << (f ? "Yes" : "No") << endl; }
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <int MOD> struct ModInt {
  static const int Mod = MOD;
  unsigned x;
  ModInt() : x(0) {}
  ModInt(signed sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  ModInt(signed long long sig) {
    int sigt = sig % MOD;
    if (sigt < 0)
      sigt += MOD;
    x = sigt;
  }
  int get() const { return (int)x; }

  ModInt &operator+=(ModInt that) {
    if ((x += that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(ModInt that) {
    if ((x += MOD - that.x) >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator*=(ModInt that) {
    x = (unsigned long long)x * that.x % MOD;
    return *this;
  }
  ModInt &operator/=(ModInt that) { return *this *= that.inverse(); }

  ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
  ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
  ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
  ModInt operator/(ModInt that) const { return ModInt(*this) /= that; }

  ModInt inverse() const {
    signed a = x, b = MOD, u = 1, v = 0;
    while (b) {
      signed t = a / b;
      a -= t * b;
      std::swap(a, b);
      u -= t * v;
      std::swap(u, v);
    }
    if (u < 0)
      u += MOD;
    ModInt res;
    res.x = (unsigned)u;
    return res;
  }
};
template <int MOD> ostream &operator<<(ostream &os, const ModInt<MOD> &m) {
  return os << m.x;
}
template <int MOD> istream &operator>>(istream &is, ModInt<MOD> &m) {
  signed long long s;
  is >> s;
  m = ModInt<MOD>(s);
  return is;
};
// pow(mint(2), 1000) のように
template <int MOD> ModInt<MOD> pow(ModInt<MOD> a, unsigned long long k) {
  ModInt<MOD> r = 1;
  while (k) {
    if (k & 1)
      r *= a;
    a *= a;
    k >>= 1;
  }
  return r;
}

//#define int long long を使っても大丈夫
using mint = ModInt<1000000007>;

// nCrで用いる
vector<mint> fact, factinv;
// nCrで用いる 予め計算しておく
void nCr_compute_factinv(int N) {
  N = min(N, mint::Mod - 1);
  fact.resize(N + 1);
  factinv.resize(N + 1);
  fact[0] = 1;
  rep(i, 1, N + 1) fact[i] = fact[i - 1] * i;
  factinv[N] = fact[N].inverse();
  for (int i = N; i >= 1; i--)
    factinv[i - 1] = factinv[i] * i;
}
mint nCr(int n, int r) {
  if (n >= mint::Mod)
    return nCr(n % mint::Mod, r % mint::Mod) *
           nCr(n / mint::Mod, r / mint::Mod);
  return r > n ? 0 : fact[n] * factinv[n - r] * factinv[r];
}

mint nHr(int n, int r) { return r == 0 ? 1 : nCr(n + r - 1, r); }

//エラトステネスの篩
vector<char> eratos(int n) {
  vector<char> is_prime(n + 1, true);
  is_prime[0] = is_prime[1] = false;
  for (int i = 2; i * i <= n; i++)
    if (is_prime[i]) {
      int j = i + i;
      while (j <= n) {
        is_prime[j] = false;
        j += i;
      }
    }
  return is_prime;
}
//戻り値: n以下の素数
vector<int> get_primes(int n) {
  vector<char> is_prime = eratos(n);
  vector<int> primes;
  for (int i = 0; i < n + 1; i++)
    if (is_prime[i])
      primes.emplace_back(i);
  return primes;
}
//素因数分解
vector<int> prime_factorization(int x) {
  vector<int> primes = get_primes(sqrt(x)); //√x以下の素数について調べれば良い
  vector<int> factors;
  // xまでのeratosと同じ。ｘはgiven ｘまでの最大の素数。
  // だんだん左によってくる。だからsqrt(x)まででいい
  for (auto &p : primes) {
    while (x % p == 0) {
      x /= p;
      factors.emplace_back(p);
    }
  }
  if (x != 1)
    factors.emplace_back(x);
  return factors;
}
bool is_prime(int x) {
  if (x <= 1)
    return false;
  else if (x == 2)
    return true;
  if (x % 2 == 0)
    return false;
  for (int i = 3; i * i <= x; i += 2)
    if (x % i == 0)
      return false;
  return true;
}


unordered_set<unordered_map<int, int>> s,done;
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);

  int N, M;
  cin >> N >> M;
  nCr_compute_factinv(N + 1);
  mint ans = nCr(N, 1);
  dump(ans);
  for (int i = 2; i * i <= M; i++) {
    if (M % i == 0 and i <= M / i) {
      dump(i, M / i);
      unordered_map<int, int> mp;
      mp[i] = mp[M / i] = 1;
      s.insert(mp);
    }
  }

//  auto is_prime = eratos(sqrt(M) + 1);

  while (s.size()) {
    map<int, int> mp = *s.begin();
    s.erase(s.begin());
    done.insert(mp);
    dump(mp);

    int sum = 0;
    for (auto p : mp) {
      dump(p);
      sum += p.second;
    }
    int one = N - sum;
    mint tmp = 1;

    if (one != 0)
      tmp *= nCr(N, one);
    dump(tmp, sum, one);
    for (auto p : mp) {
      if (sum != p.se)
        tmp *= nCr(sum, p.se);
      sum -= p.se;
      dump(tmp, sum, p);
    }
    ans += tmp;
    dump(tmp, ans);

    for (auto p : mp) {
      if (!is_prime(p.fi) and p.se >= 1) {
        for (int i = 2; i * i <= p.fi; i++) {
          if (p.fi % i == 0 and i <= p.fi / i) {
            unordered_map<int, int> mp2(mp);
            mp2[p.fi]--;
            if (mp2[p.fi] == 0)
              mp2.erase(p.fi);
            mp2[i]++;
            mp2[p.fi / i]++;
            if(done.count(mp2)==0)s.insert(mp2);
          }
        }
      }
    }
    
  }
  cout << ans << endl;

  return 0;
}


Compiler output:
a.cc:218:40: error: use of deleted function 'std::unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set() [with _Value = std::unordered_map<int, int>; _Hash = std::hash<std::unordered_map<int, int> >; _Pred = std::equal_to<std::unordered_map<int, int> >; _Alloc = std::allocator<std::unordered_map<int, int> >]'
  218 | unordered_set<unordered_map<int, int>> s,done;
      |                                        ^
In file included from /usr/include/c++/14/unordered_set:41,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:189,
                 from a.cc:1:
/usr/include/c++/14/bits/unordered_set.h:142:7: note: 'std::unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set() [with _Value = std::unordered_map<int, int>; _Hash = std::hash<std::unordered_map<int, int> >; _Pred = std::equal_to<std::unordered_map<int, int> >; _Alloc = std::allocator<std::unordered_map<int, int> >]' is implicitly deleted because the default definition would be ill-formed:
  142 |       unordered_set() = default;
      |       ^~~~~~~~~~~~~
/usr/include/c++/14/bits/unordered_set.h:142:7: error: use of deleted function 'std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::_Hashtable() [with _Key = std::unordered_map<int, int>; _Value = std::unordered_map<int, int>; _Alloc = std::allocator<std::unordered_map<int, int> >; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::unordered_map<int, int> >; _Hash = std::hash<std::unordered_map<int, int> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, true, true>]'
In file included from /usr/include/c++/14/bits/unordered_map.h:33,
                 from /usr/include/c++/14/unordered_map:41,
                 from /usr/include/c++/14/functional:63,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:53:
/usr/include/c++/14/bits/hashtable.h:539:7: note: 'std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::_Hashtable() [with _Key = std::unordered_map<int, int>; _Value = std::unordered_map<int, int>; _Alloc = std::allocator<std::unordered_map<int, int> >; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::unordered_map<int, int> >; _Hash = std::hash<std::unordered_map<int, int> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, true, true>]' is implicitly deleted because the default definition would be ill-formed:
  539 |       _Hashtable() = default;
      |       ^~~~~~~~~~
/usr/include/c++/14/bits/hashtable.h:539:7: error: use of deleted function 'std::__detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _Traits>::_Hashtable_base() [with _Key = std::unordered_map<int, int>; _Value = std::unordered_map<int, int>; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::unordered_map<int, int> >; _Hash = std::hash<std::unordered_map<int, int> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _Traits = std::__detail::_Hashtable_traits<true, true, true>]'
In file included from /usr/include/c++/14/bits/hashtable.h:35:
/usr/include/c++/14/bits/hashtable_policy.h:1731:7: note: 'std::__detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _Traits>::_Hashtable_base() [with _Key = std::unordered_map<int, int>; _Value = std::unordered_map<int, int>; _ExtractKey = std::__detail::_Identity; _Equal = std::equal_to<std::unordered_map<int, int> >; _Hash = std::hash<std::unordered_map<int, int> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _Traits = std::__detail::_Hashtable_traits<true, true, true>]' is implicitly deleted because the default definition would be ill-formed:
 1731 |       _Hashtable_base() = default;
      |       ^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1731:7: error: use of deleted function 'std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash, _Unused, __cache_hash_code>::_Hash_code_base() [with _Key = std::unordered_map<int, int>; _Value = std::unordered_map<int, int>; _ExtractKey = std::__detail::_Identity; _Hash = std::hash<std::unordered_map<int, int> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; bool __cache_hash_code = true]'
/usr/include/c++/14/bits/hashtable_policy.h: In instantiation of 'std::__detail::_Hashtable_ebo_helper<_Nm, _Tp, true>::_Hashtable_ebo_helper() [with int _Nm = 1; _Tp = std::hash<std::unordered_map<int, int> >]':
/usr/include/c++/14/bits/hashtable_policy.h:1328:7:   required from here
 1328 |       _Hash_code_base() = default;
      |       ^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1245:49: error: use of deleted function 'std::hash<std::unordered_map<int, int> >::hash()'
 1245 |       _Hashtable_ebo_helper() noexcept(noexcept(_Tp())) : _Tp() { }
      |                                                 ^~~~~
In file included from /usr/include/c++/14/string_view:50,
                 from /usr/include/c++/14/bits/basic_string.h:47,
                 from /usr/include/c++/14/string:54,
                 from /usr/include/c++/14/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:52:
/usr/include/c++/14/bits/functional_hash.h:102:12: note: 'std::hash<std::unordered_map<int, int> >::hash()' is implicitly deleted because the default definition would be ill-formed:
  102 |     struct hash : __hash_enum<_Tp>
      |            ^~~~
/usr/include/c++/14/bits/functional_hash.h:102:12: error: no matching function for call to 'std::__hash_enum<std::unordered_map<int, int>, false>::__hash_enum()'
/usr/include/c++/14/bits/functional_hash.h:83:7: note: candidate: 'std::__hash_enum<_Tp, <anonymous> >::__hash_enum(std::__hash_enum<_Tp, <anonymous> >&&) [with _Tp = std::unordered_map<int, int>; bool <anonymous> = false]'
   83 |       __hash_enum(__hash_enum&&);
      |       ^~~~~~~~~~~
/usr/include/c++/14/bits/functional_hash.h:83:7: note:   candidate expects 1 argument, 0 provided
/usr/include/c++/14/bits/functional_hash.h:102:12: error: 'std::__hash_enum<_Tp, <anonymous> >::~__hash_enum() [with _Tp = std::unordered_map<int, int>; bool <anonymous> = false]' is private within this context
  102 |     struct hash : __hash_enum<_Tp>
      |            ^~~~
/usr/include/c++/14/bits/functional_hash.h:84:7: note: declared private here
   84 |       ~__hash_enum();
      |       ^
/usr/include/c++/14/bits/hashtable_policy.h:1245:49: note: use '-fdiagnostics-all-candidates' to display considered candidates
 1245 |       _Hashtable_ebo_helper() noexcept(noexcept(_Tp())) : _Tp() { }
      |                                                 ^~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1328:7: note: 'std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash, _Unused, __cache_hash_code>::_Hash_code_base() [with _Key = std::unordered_map<int, int>; _Value = std::unordered_map<int, int>; _ExtractKey = std::__detail::_Identity; _Hash = std::hash<std::unordered_map<int, int> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; bool __cache_hash_code = true]' is implicitly deleted because the default definition would be ill-formed:
 1328 |       _Hash_code_base() = default;
      |       ^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1328:7: error: use of deleted function 'std::__detail::_Hashtable_ebo_helper<1, std::hash<std::unordered_map<int, int> >, true>::~_Hashtable_ebo_helper()'
/usr/include/c++/14/bits/hashtable_policy.h:1242:12: note: 'std::__detail::_Hashtable_ebo_helper<1, std::hash<std::unordered_map<int, int> >, true>::~_Hashtable_ebo_helper()' is implicitly deleted because the default definition would be ill-formed:
 1242 |     struct _Hashtable_ebo_helper<_Nm, _Tp, true>
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1242:12: error: use of deleted function 'std::hash<std::unordered_map<int, int> >::~hash()'
/usr/include/c++/14/bits/functional_hash.h:102:12: note: 'std::hash<std::unordered_map<int, int> >::~hash()' is implicitly deleted because the default definition would be ill-formed:
  102 |     struct hash : __hash_enum<_Tp>
      |            ^~~~
/usr/include/c++/14/bits/functional_hash.h:102:12: error: 'std::__hash_enum<_Tp, <anonymous> >::~__hash_enum() [with _Tp = std::unordered_map<int, int>; bool <anonymous> = false]' is private within this context
/usr/include/c++/14/bits/functional_hash.h:84:7: note: declared private here
   84 |       ~__hash_enum();
      |       ^
/usr/include/c++/14/bits/hashtable_policy.h:1731:7: note: use '-fdiagnostics-all-candidates' to display considered candidates
 1731 |       _Hashtable_base() = default;
      |       ^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1731:7: error: use of deleted function 'std::__detail::_Hash_code_base<std::unordered_map<int, int>, std::unordered_map<int, int>, std::__detail::_Identity, std::hash<std::unordered_map<int, int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::~_Hash_code_base()'
/usr/include/c++/14/bits/hashtable_policy.h:1306:12: note: 'std::__detail::_Hash_code_base<std::unordered_map<int, int>, std::unordered_map<int, int>, std::__detail::_Identity, std::hash<std::unordered_map<int, int> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::~_Hash_code_base()' is implicitly deleted because the default definition would be ill-formed:
 1306 |     struct _Hash_code_base
      |            ^~~~~~~~~~~~~~~
/usr/include/c++/14/bits/hashtable_policy.h:1306:12: error: use of deleted function 'std::__detail::_Hashtable_ebo_helper<1, std::hash<std::unordered_map<int, int> >, true>::~_Hashtable_ebo_helper()'
/usr/include/c++/14/bits/hash