#pragma once
template <int md> struct ModInt {
#if __cplusplus >= 201402L
#define MDCONST constexpr
#else
#define MDCONST
#endif
using lint = long long;
MDCONST static int mod() { return md; }
static int get_primitive_root() {
static int primitive_root = 0;
if (!primitive_root) {
primitive_root = [&]() {
std::set<int> fac;
int v = md - 1;
for (lint i = 2; i * i <= v; i++)
while (v % i == 0) fac.insert(i), v /= i;
if (v > 1) fac.insert(v);
for (int g = 1; g < md; g++) {
bool ok = true;
for (auto i : fac)
if (ModInt(g).pow((md - 1) / i) == 1) {
ok = false;
break;
}
if (ok) return g;
}
return -1;
}();
}
return primitive_root;
}
int val_;
int val() const noexcept { return val_; }
MDCONST ModInt() : val_(0) {}
MDCONST ModInt &_setval(lint v) { return val_ = (v >= md ? v - md : v), *this; }
MDCONST ModInt(lint v) { _setval(v % md + md); }
MDCONST explicit operator bool() const { return val_ != 0; }
MDCONST ModInt operator+(const ModInt &x) const {
return ModInt()._setval((lint)val_ + x.val_);
}
MDCONST ModInt operator-(const ModInt &x) const {
return ModInt()._setval((lint)val_ - x.val_ + md);
}
MDCONST ModInt operator*(const ModInt &x) const {
return ModInt()._setval((lint)val_ * x.val_ % md);
}
MDCONST ModInt operator/(const ModInt &x) const {
return ModInt()._setval((lint)val_ * x.inv().val() % md);
}
MDCONST ModInt operator-() const { return ModInt()._setval(md - val_); }
MDCONST ModInt &operator+=(const ModInt &x) { return *this = *this + x; }
MDCONST ModInt &operator-=(const ModInt &x) { return *this = *this - x; }
MDCONST ModInt &operator*=(const ModInt &x) { return *this = *this * x; }
MDCONST ModInt &operator/=(const ModInt &x) { return *this = *this / x; }
friend MDCONST ModInt operator+(lint a, const ModInt &x) {
return ModInt()._setval(a % md + x.val_);
}
friend MDCONST ModInt operator-(lint a, const ModInt &x) {
return ModInt()._setval(a % md - x.val_ + md);
}
friend MDCONST ModInt operator*(lint a, const ModInt &x) {
return ModInt()._setval(a % md * x.val_ % md);
}
friend MDCONST ModInt operator/(lint a, const ModInt &x) {
return ModInt()._setval(a % md * x.inv().val() % md);
}
MDCONST bool operator==(const ModInt &x) const { return val_ == x.val_; }
MDCONST bool operator!=(const ModInt &x) const { return val_ != x.val_; }
MDCONST bool operator<(const ModInt &x) const {
return val_ < x.val_;
} // To use std::map<ModInt, T>
friend std::istream &operator>>(std::istream &is, ModInt &x) {
lint t;
return is >> t, x = ModInt(t), is;
}
MDCONST friend std::ostream &operator<<(std::ostream &os, const ModInt &x) {
return os << x.val_;
}
MDCONST ModInt pow(lint n) const {
ModInt ans = 1, tmp = *this;
while (n) {
if (n & 1) ans *= tmp;
tmp *= tmp, n >>= 1;
}
return ans;
}
static std::vector<ModInt> facs, facinvs, invs;
MDCONST static void _precalculation(int N) {
int l0 = facs.size();
if (N > md) N = md;
if (N <= l0) return;
facs.resize(N), facinvs.resize(N), invs.resize(N);
for (int i = l0; i < N; i++) facs[i] = facs[i - 1] * i;
facinvs[N - 1] = facs.back().pow(md - 2);
for (int i = N - 2; i >= l0; i--) facinvs[i] = facinvs[i + 1] * (i + 1);
for (int i = N - 1; i >= l0; i--) invs[i] = facinvs[i] * facs[i - 1];
}
MDCONST ModInt inv() const {
if (this->val_ < std::min(md >> 1, 1 << 21)) {
if (facs.empty()) facs = {1}, facinvs = {1}, invs = {0};
while (this->val_ >= int(facs.size())) _precalculation(facs.size() * 2);
return invs[this->val_];
} else {
return this->pow(md - 2);
}
}
MDCONST ModInt fac() const {
while (this->val_ >= int(facs.size())) _precalculation(facs.size() * 2);
return facs[this->val_];
}
MDCONST ModInt facinv() const {
while (this->val_ >= int(facs.size())) _precalculation(facs.size() * 2);
return facinvs[this->val_];
}
MDCONST ModInt doublefac() const {
lint k = (this->val_ + 1) / 2;
return (this->val_ & 1) ? ModInt(k * 2).fac() / (ModInt(2).pow(k) * ModInt(k).fac())
: ModInt(k).fac() * ModInt(2).pow(k);
}
MDCONST ModInt nCr(const ModInt &r) const {
return (this->val_ < r.val_) ? 0 : this->fac() * (*this - r).facinv() * r.facinv();
}
MDCONST ModInt nPr(const ModInt &r) const {
return (this->val_ < r.val_) ? 0 : this->fac() * (*this - r).facinv();
}
ModInt sqrt() const {
if (val_ == 0) return 0;
if (md == 2) return val_;
if (pow((md - 1) / 2) != 1) return 0;
ModInt b = 1;
while (b.pow((md - 1) / 2) == 1) b += 1;
int e = 0, m = md - 1;
while (m % 2 == 0) m >>= 1, e++;
ModInt x = pow((m - 1) / 2), y = (*this) * x * x;
x *= (*this);
ModInt z = b.pow(m);
while (y != 1) {
int j = 0;
ModInt t = y;
while (t != 1) j++, t *= t;
z = z.pow(1LL << (e - j - 1));
x *= z, z *= z, y *= z;
e = j;
}
return ModInt(std::min(x.val_, md - x.val_));
}
};
template <int md> std::vector<ModInt<md>> ModInt<md>::facs = {1};
template <int md> std::vector<ModInt<md>> ModInt<md>::facinvs = {1};
template <int md> std::vector<ModInt<md>> ModInt<md>::invs = {0};
// https://hitonanode.github.io/cplib-cpp/modint.hpp
// using mint = ModInt<998244353>;
// using mint = ModInt<1000000007>;
#line 2 "library/mod/modint.hpp"
template <int md> struct ModInt {
#if __cplusplus >= 201402L
#define MDCONST constexpr
#else
#define MDCONST
#endif
using lint = long long;
MDCONST static int mod() { return md; }
static int get_primitive_root() {
static int primitive_root = 0;
if (!primitive_root) {
primitive_root = [&]() {
std::set<int> fac;
int v = md - 1;
for (lint i = 2; i * i <= v; i++)
while (v % i == 0) fac.insert(i), v /= i;
if (v > 1) fac.insert(v);
for (int g = 1; g < md; g++) {
bool ok = true;
for (auto i : fac)
if (ModInt(g).pow((md - 1) / i) == 1) {
ok = false;
break;
}
if (ok) return g;
}
return -1;
}();
}
return primitive_root;
}
int val_;
int val() const noexcept { return val_; }
MDCONST ModInt() : val_(0) {}
MDCONST ModInt &_setval(lint v) { return val_ = (v >= md ? v - md : v), *this; }
MDCONST ModInt(lint v) { _setval(v % md + md); }
MDCONST explicit operator bool() const { return val_ != 0; }
MDCONST ModInt operator+(const ModInt &x) const {
return ModInt()._setval((lint)val_ + x.val_);
}
MDCONST ModInt operator-(const ModInt &x) const {
return ModInt()._setval((lint)val_ - x.val_ + md);
}
MDCONST ModInt operator*(const ModInt &x) const {
return ModInt()._setval((lint)val_ * x.val_ % md);
}
MDCONST ModInt operator/(const ModInt &x) const {
return ModInt()._setval((lint)val_ * x.inv().val() % md);
}
MDCONST ModInt operator-() const { return ModInt()._setval(md - val_); }
MDCONST ModInt &operator+=(const ModInt &x) { return *this = *this + x; }
MDCONST ModInt &operator-=(const ModInt &x) { return *this = *this - x; }
MDCONST ModInt &operator*=(const ModInt &x) { return *this = *this * x; }
MDCONST ModInt &operator/=(const ModInt &x) { return *this = *this / x; }
friend MDCONST ModInt operator+(lint a, const ModInt &x) {
return ModInt()._setval(a % md + x.val_);
}
friend MDCONST ModInt operator-(lint a, const ModInt &x) {
return ModInt()._setval(a % md - x.val_ + md);
}
friend MDCONST ModInt operator*(lint a, const ModInt &x) {
return ModInt()._setval(a % md * x.val_ % md);
}
friend MDCONST ModInt operator/(lint a, const ModInt &x) {
return ModInt()._setval(a % md * x.inv().val() % md);
}
MDCONST bool operator==(const ModInt &x) const { return val_ == x.val_; }
MDCONST bool operator!=(const ModInt &x) const { return val_ != x.val_; }
MDCONST bool operator<(const ModInt &x) const {
return val_ < x.val_;
} // To use std::map<ModInt, T>
friend std::istream &operator>>(std::istream &is, ModInt &x) {
lint t;
return is >> t, x = ModInt(t), is;
}
MDCONST friend std::ostream &operator<<(std::ostream &os, const ModInt &x) {
return os << x.val_;
}
MDCONST ModInt pow(lint n) const {
ModInt ans = 1, tmp = *this;
while (n) {
if (n & 1) ans *= tmp;
tmp *= tmp, n >>= 1;
}
return ans;
}
static std::vector<ModInt> facs, facinvs, invs;
MDCONST static void _precalculation(int N) {
int l0 = facs.size();
if (N > md) N = md;
if (N <= l0) return;
facs.resize(N), facinvs.resize(N), invs.resize(N);
for (int i = l0; i < N; i++) facs[i] = facs[i - 1] * i;
facinvs[N - 1] = facs.back().pow(md - 2);
for (int i = N - 2; i >= l0; i--) facinvs[i] = facinvs[i + 1] * (i + 1);
for (int i = N - 1; i >= l0; i--) invs[i] = facinvs[i] * facs[i - 1];
}
MDCONST ModInt inv() const {
if (this->val_ < std::min(md >> 1, 1 << 21)) {
if (facs.empty()) facs = {1}, facinvs = {1}, invs = {0};
while (this->val_ >= int(facs.size())) _precalculation(facs.size() * 2);
return invs[this->val_];
} else {
return this->pow(md - 2);
}
}
MDCONST ModInt fac() const {
while (this->val_ >= int(facs.size())) _precalculation(facs.size() * 2);
return facs[this->val_];
}
MDCONST ModInt facinv() const {
while (this->val_ >= int(facs.size())) _precalculation(facs.size() * 2);
return facinvs[this->val_];
}
MDCONST ModInt doublefac() const {
lint k = (this->val_ + 1) / 2;
return (this->val_ & 1) ? ModInt(k * 2).fac() / (ModInt(2).pow(k) * ModInt(k).fac())
: ModInt(k).fac() * ModInt(2).pow(k);
}
MDCONST ModInt nCr(const ModInt &r) const {
return (this->val_ < r.val_) ? 0 : this->fac() * (*this - r).facinv() * r.facinv();
}
MDCONST ModInt nPr(const ModInt &r) const {
return (this->val_ < r.val_) ? 0 : this->fac() * (*this - r).facinv();
}
ModInt sqrt() const {
if (val_ == 0) return 0;
if (md == 2) return val_;
if (pow((md - 1) / 2) != 1) return 0;
ModInt b = 1;
while (b.pow((md - 1) / 2) == 1) b += 1;
int e = 0, m = md - 1;
while (m % 2 == 0) m >>= 1, e++;
ModInt x = pow((m - 1) / 2), y = (*this) * x * x;
x *= (*this);
ModInt z = b.pow(m);
while (y != 1) {
int j = 0;
ModInt t = y;
while (t != 1) j++, t *= t;
z = z.pow(1LL << (e - j - 1));
x *= z, z *= z, y *= z;
e = j;
}
return ModInt(std::min(x.val_, md - x.val_));
}
};
template <int md> std::vector<ModInt<md>> ModInt<md>::facs = {1};
template <int md> std::vector<ModInt<md>> ModInt<md>::facinvs = {1};
template <int md> std::vector<ModInt<md>> ModInt<md>::invs = {0};
// https://hitonanode.github.io/cplib-cpp/modint.hpp
// using mint = ModInt<998244353>;
// using mint = ModInt<1000000007>;