/* * @uni_kakurenbo * https://github.com/uni-kakurenbo/competitive-programming-workspace * * CC0 1.0 http://creativecommons.org/publicdomain/zero/1.0/deed.ja */ /* #language C++ GCC */ /* #region template */ #include /* #expanded [template.hpp] */ /* #expanded [snippet/aliases.hpp] */ #include #include /* #expanded [snippet/internal/types.hpp] */ #include namespace lib {using i16 = std::int16_t;using u16 = std::uint16_t;using i32 = std::int32_t;using u32 = std::uint32_t;using i64 = std::int64_t;using u64 = std::uint64_t; #ifdef __GNUC__ using i128 = __int128_t;using u128 = __uint128_t; #endif using uint = unsigned;using ll = long long;using ull = unsigned long long;using ld = long double;} /* [snippet/internal/types.hpp] */ #define until(...) while(!(__VA_ARGS__)) #define ALL(x) std::begin((x)),std::end((x)) #define RALL(x) std::rbegin((x)),std::rend((x)) #define $F first #define $S second namespace lib {template using spair = std::pair;}namespace std {using bit_reference = std::vector::reference;bit_reference operator |= (bit_reference a, const bool b) { return a = a | b; }bit_reference operator &= (bit_reference a, const bool b) { return a = a & b; }} /* [snippet/aliases.hpp] */ /* #expanded [snippet/iterations.hpp] */ /* #expanded [snippet/internal/overload.hpp] */ #define $OVERLOAD2(arg0, arg1, cmd, ...) cmd #define $OVERLOAD3(arg0, arg1, arg2, cmd, ...) cmd #define $OVERLOAD4(arg0, arg1, arg2, arg3, cmd, ...) cmd #define $OVERLOAD5(arg0, arg1, arg2, arg3, arg4, cmd, ...) cmd /* [snippet/internal/overload.hpp] */ #define LOOP(n) REPI($_, (n)) #define REPI(i,n) for(int i=0, i##_length=(n); i=0;) #define REPB(i,l,r) for(auto i=(r), i##_last=(l); --i>=i##_last;) #define REPRS(i,l,r,s) for(auto i=(r), i##_last=(l); (i-=(s))>=i##_last;) #define REP(...) $OVERLOAD4(__VA_ARGS__, REPIS, REPF, REPI, LOOP)(__VA_ARGS__) #define REPD(...) $OVERLOAD4(__VA_ARGS__, REPRS, REPB, REPR)(__VA_ARGS__) #define FORO(i,n) for(int i=0, i##_last=(n); i<=i##_last; ++i) #define FORI(i,l,r) for(auto i=(l), i##_last=(r); i<=i##_last; ++i) #define FORIS(i,l,r,s) for(auto i=(l), i##_last=(r); i<=i##_last; i+=(s)) #define FORRO(i,n) for(auto i=(n); i>=0; --i) #define FORR(i,l,r) for(auto i=(r), i##_last=(l); i>=i##_last; --i) #define FORRS(i,l,r,s) for(auto i=(r), i##_last=(l); i>=i##_last; i-=(s)) #define FOR(...) $OVERLOAD4(__VA_ARGS__, FORIS, FORI, FORO)(__VA_ARGS__) #define FORD(...) $OVERLOAD4(__VA_ARGS__, FORRS, FORR, FORRO)(__VA_ARGS__) #define ITR1(e0,v) for(const auto &e0 : (v)) #define ITRP1(e0,v) for(auto e0 : (v)) #define ITRR1(e0,v) for(auto &e0 : (v)) #define ITR2(e0,e1,v) for(const auto [e0, e1] : (v)) #define ITRP2(e0,e1,v) for(auto [e0, e1] : (v)) #define ITRR2(e0,e1,v) for(auto &[e0, e1] : (v)) #define ITR3(e0,e1,e2,v) for(const auto [e0, e1, e2] : (v)) #define ITRP3(e0,e1,e2,v) for(auto [e0, e1, e2] : (v)) #define ITRR3(e0,e1,e2,v) for(auto &[e0, e1, e2] : (v)) #define ITR4(e0,e1,e2,e3,v) for(const auto [e0, e1, e2, e3] : (v)) #define ITRP4(e0,e1,e2,e3,v) for(auto [e0, e1, e2, e3] : (v)) #define ITRR4(e0,e1,e2,e3,v) for(auto &[e0, e1, e2, e3] : (v)) #define ITR(...) $OVERLOAD5(__VA_ARGS__, ITR4, ITR3, ITR2, ITR1)(__VA_ARGS__) #define ITRP(...) $OVERLOAD5(__VA_ARGS__, ITRP4, ITRP3, ITRP2, ITRP1)(__VA_ARGS__) #define ITRR(...) $OVERLOAD5(__VA_ARGS__, ITRR4, ITRR3, ITRR2, ITRR1)(__VA_ARGS__) /* [snippet/iterations.hpp] */ /* #expanded [snippet/fast_io.hpp] */ #include #ifdef __GNUC__ __attribute__((constructor)) inline void fast_io() { std::ios::sync_with_stdio(false), std::cin.tie(nullptr); } #else inline void fast_io() { std::ios::sync_with_stdio(false), std::cin.tie(nullptr); } #endif /* [snippet/fast_io.hpp] */ /* #expanded [snippet/using.hpp] */ #include #include #include #include #include #include #include #include #include #include /* #expanded [utilities.hpp] */ /* #expanded [numeric/int128.hpp] */ #include #include #include #include #include templatestd::basic_istream& operator>>(std::basic_istream& in, lib::i128& v) {std::string str; in >> str;v = 0;bool negative = (str[0] == '-');REP(d, std::next(str.begin(), negative), str.end()) {assert(std::isdigit(*d));v = v * 10 + *d - '0';}if(negative) v *= -1;return in;}templatestd::basic_ostream& operator<<(std::basic_ostream& out, lib::i128 v) {if(v == 0) return out << 0;if(v < 0) out << '-', v *= -1;std::string str;while(v > 0) str += v%10 + '0', v /= 10;std::reverse(str.begin(), str.end());return out << str;} /* [numeric/int128.hpp] */ /* #expanded [geometry.hpp] */ /* #expanded [geometry/basic.hpp] */ /* #expanded [geometry/point.hpp] */ #include #include #include #include namespace lib {template struct point : protected std::pair {public:constexpr point() {}constexpr point(const T& x, const T& y) : std::pair(x, y) {}template constexpr point(const point& p) : point(p.x(), p.y()) {};template constexpr point(point&& p) : point(p.x(), p.y()) {};templateconstexpr point& operator=(const point& p) & { this->x() = p.x(),this->y() = p.y(); return *this; };templateconstexpr point& operator=(point&& p) && { this->x() = p.x(), this->y() = p.y(); return *this; };inline T& x() { return this->first; }inline T& y() { return this->second; }inline const T& x() const { return this->first; }inline const T& y() const { return this->second; }inline constexpr point& operator+=(const point& v) { this->x() += v.x(), this->y() += v.y(); return *this; }inline constexpr point& operator-=(const point& v) { this->x() -= v.x(), this->y() -= v.y(); return *this; }friend inline constexpr point operator+(point a, const point& b) { return a += b; }friend inline constexpr point operator-(point a, const point& b) { return a -= b; }friend inline constexpr point operator*(const point& a, const point& b) { return a.x() * b.x() + a.y() * b.y(); }friend inline constexpr bool operator==(const point& a, const point& b) { return a.x() == b.x() && a.y() == b.y(); }friend inline constexpr bool operator!=(const point& a, const point& b) { return a.x() != b.x() or a.y() != b.y(); }friend inline constexpr bool operator<(const point& a, const point& b) { return a.x() != b.x() ? a.x() < b.x() : a.y() < b.y(); }friend inline constexpr bool operator>(const point& a, const point& b) { return a.x() != b.x() ? a.x() > b.x() : a.y() > b.y(); }friend inline constexpr bool operator<=(const point& a, const point& b) { return !(a > b); }friend inline constexpr bool operator>=(const point& a, const point& b) { return !(a < b); }std::pair _debug() const { return { this->x(), this->y() }; }};}templateinline constexpr T std::abs(const lib::point& v) {T x = v.x(), y = v.y(), n = std::max(std::abs(x), std::abs(y));if(n == 0) return 0;x /= n, y /= n;return n * std::sqrt(x * x + y * y);}namespace lib {templateinline constexpr U distance(const point& a, const point& b) {return std::abs(point(a - b));}templateinline constexpr T cross(point a, point b, const point& o = {}) {a -= o, b -= o;return a.x() * b.y() - a.y() * b.x();}}templatestd::basic_istream& operator>>(std::basic_istream& in, lib::point& v) {T x, y; in >> x >> y;v = { x, y };return in;} /* [geometry/point.hpp] */ /* [geometry/basic.hpp] */ /* [geometry.hpp] */ /* #expanded [numeric/arithmetic.hpp] */ #include #include #include #include #include /* #expanded [internal/types.hpp] */ #include namespace lib {namespace internal {using size_t = std::int32_t;using int128_t = __int128_t;using uint128_t = __uint128_t;}} /* [internal/types.hpp] */ /* #expanded [numeric/internal/number_base.hpp] */ #include #include #include #include #include #include namespace lib {templatestd::string base_n_string(T v) {constexpr char CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";static_assert(0 < B <= std::strlen(CHARS));assert(0 <= v);std::string res;while(v > 0) {res += CHARS[v%B] + '0';v /= B;}std::reverse(ALL(res));return res;}templatestd::string base_n_string(T v, std::size_t b = 2) {constexpr char CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";assert(1 < b && b <= std::strlen(CHARS));assert(0 <= v);std::string res;while(v > 0) {res += CHARS[v%b];v /= b;}std::reverse(ALL(res));return res;}templatestd::vector base_n_vector(T v, std::size_t b = 2) {assert(1 < b);assert(0 <= v);std::vector res;while(v > 0) {res.push_back(v%b);v /= b;}std::reverse(ALL(res));return res;}} /* [numeric/internal/number_base.hpp] */ namespace lib {templateT nPr(const T n, T r) {assert(0 <= n);assert(0 <= r);if(n < r) return 0;T res = 1;REP(i, r) res *= n-i;return res;}templateT nCr(const T n, T r) {assert(0 <= n);assert(0 <= r);if(n == r) return 1;if(n < r) return 0;if(n < r*2) r = n-r;T p = 1, q = 1;REP(i, r) p *= n-i, q *= r-i;return p / q;}templateT pow(T x, U n) {T res = 1;while(n > 0) {if(n & 1) res *= x;x *= x;n >>= 1;}return res;}using atcoder::pow_mod;using atcoder::inv_mod;using atcoder::crt;templateinline bool mul_over(T x, U y, V s){if(x >= s) return true;if(x >= 0 && y >= 0) return x > s/y;if(x <= 0 && y <= 0) return x < s/y;return false;}templateinline bool mul_under(T x, U y, V s){if(x <= s) return true;if(x >= 0 && y <= 0) return x > s/y;if(x <= 0 && y >= 0) return x < s/y;return false;}} /* [numeric/arithmetic.hpp] */ /* #expanded [numeric/matrix.hpp] */ #include #include /* #expanded [grid.hpp] */ #include #include #include #include #include #include #include #include /* #expanded [internal/dev_env.hpp] */ #ifdef LOCAL_JUDGE constexpr bool DEV_ENV = true; #else constexpr bool DEV_ENV = false; #endif /* [internal/dev_env.hpp] */ namespace lib {namespace internal {namespace grid_impl {templatestruct interface {virtual void assign(const size_t, const size_t, const T&&) = 0;virtual void resize(const size_t, const size_t) = 0;virtual size_t height() const = 0;virtual size_t width() const = 0;virtual size_t id(const size_t, const size_t) const = 0;virtual T& operator()(const size_t, const size_t) = 0;virtual const T& operator()(const size_t, const size_t) const = 0;};template struct container_base : virtual interface {private:size_t _h, _w;protected:inline void _validate_index(__attribute__ ((unused)) const size_t i, __attribute__ ((unused)) const size_t j) const {assert(0 <= i and i < this->height());assert(0 <= j and j < this->width());}inline size_t _positivize_row_index(const size_t x) const {return x < 0 ? this->height() + x : x;}inline size_t _positivize_col_index(const size_t x) const {return x < 0 ? this->width() + x : x;}public:container_base() = default;container_base(const size_t _h, const size_t _w) : _h(_h), _w(_w) {}virtual void resize(const size_t h, const size_t w) override {this->_h = h, this->_w = w;}inline size_t height() const override { return this->_h; }inline size_t width() const override { return this->_w; }inline size_t id(const size_t i, const size_t j) const override {const size_t _i = this->_positivize_row_index(i);const size_t _j = this->_positivize_col_index(j);this->_validate_index(_i, _j);return _i * this->width() + _j;}};template, class base = std::vector>struct container : base, container_base, virtual interface {container(const size_t n = 0) : container(n, n) {}container(const size_t h, const size_t w, const T &&val = T{}) : base(h, Row(w, std::forward(val))), container_base(h, w) {}container(const std::initializer_list init_list) : base(init_list) {const size_t rows = std::distance(ALL(init_list));const size_t first_cols = init_list.begin()->size();if constexpr (DEV_ENV) { ITR(init_row, init_list) assert((size_t)init_row.size() == first_cols); }this->container_base::resize(rows, first_cols);}inline void assign(const container &source) {this->resize(source.height(), source.width());this->base::assign(ALL(source));}inline void assign(const size_t h, const size_t w, const T &&val = T{}) override {this->container_base::resize(h, w);this->base::resize(h);ITRR(row, *this) row.assign(w, std::forward(val));}inline void resize(const size_t h, const size_t w) override {this->container_base::resize(h, w);this->base::resize(h);ITRR(row, *this) row.resize(w);}inline T& operator()(const size_t i, const size_t j) override {const size_t _i = this->_positivize_row_index(i);const size_t _j = this->_positivize_col_index(j);this->_validate_index(_i, _j);return (*this)[_i][_j];}inline const T& operator()(const size_t i, const size_t j) const override {const size_t _i = this->_positivize_row_index(i);const size_t _j = this->_positivize_col_index(j);this->_validate_index(_i, _j);return (*this)[_i][_j];}};template>struct unfolded_container : base, container_base, virtual interface {unfolded_container(size_t n = 0) : unfolded_container(n, n) {}unfolded_container(const size_t h, const size_t w, const T &&val = T{}) : base(h*w, std::forward(val)), container_base(h, w) {}unfolded_container(std::initializer_list> init_list) {const size_t rows = std::distance(init_list.begin(), init_list.end());const size_t first_cols = init_list.begin()->size();this->resize(rows, first_cols);for(auto index=0, itr=init_list.begin(), itr_end=init_list.end(); itr!=itr_end; ++itr) {assert((size_t)itr->size() == first_cols);for(auto v=itr->begin(), v_end=itr->end(); v!=v_end; ++v) (*this)[index++] = *v;}}inline void assign(const unfolded_container &source) {this->resize(source.height(), source.width());this->base::assign(ALL(source));}inline void assign(const size_t h, const size_t w, const T &&val = T{}) override {this->container_base::resize(h, w);this->base::assign(h*w, std::forward(val));}inline void resize(const size_t h, const size_t w) override {this->container_base::resize(h, w);this->base::resize(h*w);}inline T& operator()(const size_t i, const size_t j) override {const size_t _i = this->_positivize_row_index(i);const size_t _j = this->_positivize_col_index(j);return (*this)[this->id(_i, _j)];}inline const T& operator()(const size_t i, const size_t j) const override {const size_t _i = this->_positivize_row_index(i);const size_t _j = this->_positivize_col_index(j);return (*this)[this->id(_i, _j)];}};}template struct grid_core : container, virtual grid_impl::interface {using container::container;enum class invert_direction { vertical, horizontal };enum class rotate_direction { counter_clockwise, clockwise };templatevoid inline read(Stream *const ist = &std::cin) {REP(i, this->height()) REP(j, this->width()) {U val; *ist >> val;(*this)(i, j) = val;}}templateinline grid_core& invert() {grid_core res(this->height(), this->width());REP(i, this->height()) REP(j, this->width()) {if constexpr (DIRECTION == invert_direction::vertical) {res(i,j) = (*this)(this->height()-i-1,j);}else {res(i,j) = (*this)(i, this->width()-j-1);}}this->assign(res);return *this;}templateinline grid_core& rotate(const size_t k) {grid_core res = *this;REP(i, k) { res = res.rotate(); }this->assign(res);return *this;}templateinline grid_core& rotate() {grid_core res(this->width(), this->height());REP(i, this->width()) REP(j, this->height()) {if constexpr (DIRECTION == rotate_direction::clockwise) {res(i,j) = (*this)(this->height()-j-1,i);}else {res(i,j) = (*this)(j,this->width()-i-1);}}this->assign(res);return *this;}inline grid_core& transpose() {grid_core res(this->width(), this->height());REP(i, this->width()) REP(j, this->height()) {res(i,j) = (*this)(j,i);}this->assign(res);return *this;}};}template, class base = std::vector>using grid = internal::grid_core>;template>using unfolded_grid = internal::grid_core>;} /* [grid.hpp] */ /* #expanded [valarray.hpp] */ #include #include #include #include #include #include namespace lib {template struct valarray : std::valarray {using size_type = internal::size_t;using iterator = T*;using const_iterator = const T*;protected:inline bool _validate_index_in_right_open([[maybe_unused]] const size_type p) const {return 0 <= p and p < this->size();}inline bool _validate_index_in_closed([[maybe_unused]] const size_type p) const {return 0 <= p and p <= this->size();}inline bool _validate_rigth_open_interval([[maybe_unused]] const size_type l, [[maybe_unused]] const size_type r) const {return 0 <= l and l <= r and r <= this->size();}inline size_type _positivize_index(const size_type p) const {return p < 0 ? this->size() + p : p;}public:valarray() {}valarray(const size_type length, const T& val = T{}) : std::valarray(std::forward(val), length) {}template::value_type* = nullptr>valarray(const I first, const I last) : std::valarray(first, last) {}template valarray(const std::initializer_list& init) : valarray(std::begin(init), std::end(init)) {}inline size_type size() const { return this->std::valarray::size(); }inline void reserve(const size_type) {}template::value_type* = nullptr>inline void assign(const I first, const I last) {this->resize(std::distance(first, last));std::copy(first, last, begin(*this));}inline void assign(const size_type length, const T& val = T{}) {this->std::valarray::resize(length, val);}inline void resize(const size_type length, const T& val = T{}) {std::valarray temp = *this;this->assign(length, val);std::move(std::begin(temp), std::min(std::end(temp), std::next(std::begin(temp), length)), std::begin(*this));}inline const T& operator[](size_type pos) const {pos = this->_positivize_index(pos), assert(this->_validate_index_in_right_open(pos));return this->std::valarray::operator[](pos);}inline T& operator[](size_type pos) {pos = this->_positivize_index(pos), assert(this->_validate_index_in_right_open(pos));return this->std::valarray::operator[](pos);}inline const T& back() const { return *std::prev(this->end()); }inline T& back() { return *std::prev(this->end()); }inline const T& front() const { return *this->begin(); }inline T& front() { return *this->begin(); }inline const T* begin() const { return this->size() ? std::addressof((*this)[0]) : nullptr; }inline T* begin() { return this->size() ? std::addressof((*this)[0]) : nullptr; }inline const T* end() const { if(auto n = this->size()) { return std::addressof((*this)[0]) + n; } else { return nullptr; } }inline T* end() { if(auto n = this->size()) { return std::addressof((*this)[0]) + n; } else { return nullptr; } }};} /* [valarray.hpp] */ namespace lib {namespace internal {namespace matrix_impl {template struct interface : virtual grid_impl::interface {virtual size_t rows() const = 0;virtual size_t cols() const = 0;virtual size_t square() const = 0;};}templatestruct matrix_core : base, virtual matrix_impl::interface {using base::base;static inline matrix_core identity(const size_t n, const T &&val = { 1 }) {matrix_core res(n);REP(i, n) res(i, i) = val;return res;}inline size_t rows() const override { return this->height(); }inline size_t cols() const override { return this->width(); }inline size_t square() const override { return this->rows() == this->cols(); }template inline matrix_core& operator+=(const U rhs) {REP(i, this->rows()) REP(j, this->cols()) (*this)(i, j) += rhs;return *this;}template inline matrix_core& operator+=(const matrix_core rhs) {REP(i, this->rows()) REP(j, this->cols()) (*this)(i, j) += rhs(i, j);return *this;}template inline matrix_core operator+(const U rhs) const {return matrix_core(*this) += rhs;}template inline matrix_core& operator-=(const U rhs) {REP(i, this->rows()) REP(j, this->cols()) (*this)(i, j) -= rhs;return *this;}template inline matrix_core& operator-=(const matrix_core rhs) {REP(i, this->rows()) REP(j, this->cols()) (*this)(i, j) -= rhs(i, j);return *this;}template inline matrix_core operator-(const U rhs) const {return matrix_core(*this) -= rhs;}template inline matrix_core operator*(const matrix_core rhs) {assert(this->cols() == rhs.rows());matrix_core res(this->rows(), rhs.cols());REP(i, this->rows()) REP(j, rhs.cols()) REP(k, this->cols()) {res(i, j) += (*this)(i, k) * rhs(k, j);}return res;}template inline matrix_core operator*(const U rhs) {matrix_core res(*this);REP(i, res.rows()) REP(j, res.cols()) res(i, j) *= rhs;return res;}template inline matrix_core& operator*=(const U rhs) {matrix_core res = *this * rhs;this->assign(res);return *this;}template inline matrix_core& operator/=(const U rhs) {REP(i, this->rows()) REP(j, this->cols()) (*this)(i, j) /= rhs;return *this;}template inline matrix_core operator/(const U rhs) const {return matrix_core(*this) /= rhs;}template inline matrix_core& operator%=(const U rhs) {REP(i, this->rows()) REP(j, this->cols()) (*this)(i, j) %= rhs;return *this;}template inline matrix_core operator%(const U rhs) const {return matrix_core(*this) %= rhs;}inline matrix_core pow(ll p) {assert(this->square());matrix_core x = *this, res = matrix_core::Identity(this->rows());while(p > 0) {if(p & 1) res *= x;x *= x;p >>= 1;}return res;}};}template>using matrix = internal::matrix_core;templateusing valmatrix = internal::matrix_core>>;templateusing unfolded_matrix = internal::matrix_core>;} /* [numeric/matrix.hpp] */ /* #expanded [numeric/modint.hpp] */ #include #include #include namespace lib {template using static_modint = atcoder::static_modint<_mod>;using modint998244353 = atcoder::modint998244353;using modint1000000007 = atcoder::modint1000000007;template using dynamic_modint = atcoder::dynamic_modint;using modint = atcoder::modint;template struct dynamic_modint_64bit;using modint64 = dynamic_modint_64bit<-1>;}namespace lib {template struct dynamic_modint_64bit : atcoder::internal::modint_base {private:using mint = dynamic_modint_64bit;using int64_t = std::int64_t;using uint64_t = std::uint64_t;using uint128_t = internal::uint128_t;protected:static uint64_t _mod;static uint64_t r;static uint64_t n2;static uint64_t get_r() {uint64_t res = _mod;for(int64_t i = 0; i < 5; ++i)res *= 2 - _mod * res;return res;}static uint64_t reduce(const uint128_t &b) {return (b + uint128_t(uint64_t(b) * uint64_t(-r)) * _mod) >> 64;}public:static uint64_t mod() { return _mod; }static void set_mod(const uint64_t m) {assert(m < (1UL << 63));assert((m & 1) == 1);_mod = m;n2 = -static_cast(m) % m;r = get_r();assert(r * _mod == 1);}uint64_t _val;dynamic_modint_64bit() : _val(0) {}dynamic_modint_64bit(const std::int64_t b): _val(this->reduce((static_cast(b) + this->_mod) * this->n2)) {};mint &operator+=(const mint &b) {if(static_cast(_val += b._val - 2 * _mod) < 0) this->_val += 2 * this->_mod;return *this;}mint &operator-=(const mint &b) {if(static_cast(this->_val -= b._val) < 0)this->_val += 2 * this->_mod;return *this;}mint &operator*=(const mint &b) {this->_val = reduce(static_cast(this->_val) * b._val);return *this;}mint &operator/=(const mint &b) {*this *= b.inv();return *this;}mint operator+(const mint &b) const { return mint(*this) += b; }mint operator-(const mint &b) const { return mint(*this) -= b; }mint operator*(const mint &b) const { return mint(*this) *= b; }mint operator/(const mint &b) const { return mint(*this) /= b; }bool operator==(const mint &b) const {return (this->_val >= this->_mod ? this->_val - this->_mod : this->_val) == (b._val >= this->_mod ? b._val - this->_mod : b._val);}bool operator!=(const mint &b) const {return (this->_val >= this->_mod ? this->_val - this->_mod : this->_val) != (b._val >= this->_mod ? b._val - this->_mod : b._val);}mint operator-() const { return mint{} - static_cast(*this); }mint pow(uint128_t n) const {mint res(1), mul(*this);while(n > 0) {if(n & 1)res *= mul;mul *= mul;n >>= 1;}return res;}mint inv() const { return this->pow(this->_mod - 2); }uint64_t val() const {uint64_t res = this->reduce(this->_val);return res >= this->_mod ? res - this->_mod : res;}};template typename dynamic_modint_64bit::uint64_t dynamic_modint_64bit::_mod;template typename dynamic_modint_64bit::uint64_t dynamic_modint_64bit::r;template typename dynamic_modint_64bit::uint64_t dynamic_modint_64bit::n2;} /* [numeric/modint.hpp] */ /* #expanded [constants.hpp] */ #include #include #include namespace lib {i32 INF32 = (std::numeric_limits::max() >> 1) - 1;i64 INF64 = (std::numeric_limits::max() >> 1) - 1;constexpr char LN = '\n';constexpr char SPC = ' ';constexpr std::pair DIRS4[] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };constexpr std::pair DIRS8[] = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } };enum class comp : std::int8_t {equal_to,not_equal_to,equals = equal_to,eq = equal_to,under,over,or_under,or_over,less = under,more = over,less_than = under,more_than = over,not_less_than = or_over,not_more_than = or_under,leq = or_under,geq = or_over};enum class interval : std::int8_t {right_open,left_open,open,closed,};} /* [constants.hpp] */ /* #expanded [multi_container.hpp] */ #include #include #include /* #expanded [internal/exception.hpp] */ namespace lib {namespace internal {template constexpr bool EXCEPTION = false;template constexpr bool EXCEPTION_INT = false;}} /* [internal/exception.hpp] */ namespace lib {namespace internal {namespace multi_container_impl {template struct base : container {using container::container;protected:inline void _validate_index(__attribute__ ((unused)) const internal::size_t index) const {assert(0 <= index and index < (internal::size_t)this->size());}inline internal::size_t _positivize_index(const internal::size_t x) const {return x < 0 ? this->size() + x : x;}};}}template class container = valarray>struct multi_container : internal::multi_container_impl::base>> {using internal::multi_container_impl::base>>::base;templatemulti_container(const Head head, const Tail... tail): internal::multi_container_impl::base>>(head, multi_container(tail...)) {static_assert(std::is_integral_v, "size must be integral");}template T& operator()(const Head _head, const Tail... tail) {static_assert(std::is_integral_v, "index must be integral");const internal::size_t head = this->_positivize_index(_head);this->_validate_index(head);return (*this)[head](tail...);}template const T& operator()(const Head _head, const Tail... tail) const {static_assert(std::is_integral_v, "index must be integral");const internal::size_t head = this->_positivize_index(_head);this->_validate_index(head);return (*this)[head](tail...);}};template class container>struct multi_container : internal::multi_container_impl::base> {using internal::multi_container_impl::base>::base;template multi_container(const Args&... args) : internal::multi_container_impl::base>(args...) {}T& operator()(const internal::size_t _index) {const internal::size_t index = this->_positivize_index(_index);this->_validate_index(index);return (*this)[index];}const T& operator()(const internal::size_t _index) const {const internal::size_t index = this->_positivize_index(_index);this->_validate_index(index);return (*this)[index];}};template class container>struct multi_container {static_assert(internal::EXCEPTION, "invalid rank: 0, should be 1 or more");};} /* [multi_container.hpp] */ /* #expanded [graph.hpp] */ #include #include #include #include /* #expanded [data_structure/disjoint_set_union.hpp] */ #include #include #include #include namespace lib {struct dsu {using size_type = internal::size_t;private:size_type _n, _group_count;mutable std::vector _parent_or_size;public:dsu() : _n(0) {}explicit dsu(const size_type n) : _n(n), _group_count(n), _parent_or_size(n, -1) {}inline size_type size() const { return this->_n; }inline size_type group_count() const { return this->_group_count; }inline size_type merge(const size_type a, const size_type b) {assert(0 <= a && a < _n);assert(0 <= b && b < _n);size_type x = this->leader(a), y = this->leader(b);if (x == y) return x;--this->_group_count;if (-this->_parent_or_size[x] < -this->_parent_or_size[y]) std::swap(x, y);this->_parent_or_size[x] += this->_parent_or_size[y];this->_parent_or_size[y] = x;return x;}inline bool same(const size_type a, const size_type b) const {assert(0 <= a && a < _n);assert(0 <= b && b < _n);return this->leader(a) == this->leader(b);}inline size_type leader(const size_type a) const {assert(0 <= a && a < _n);if (_parent_or_size[a] < 0) return a;return _parent_or_size[a] = this->leader(_parent_or_size[a]);}inline size_type size(const size_type a) const {assert(0 <= a && a < _n);return -_parent_or_size[this->leader(a)];}inline std::vector> groups() const {std::vector leader_buf(_n), group_size(_n);for (size_type i = 0; i < _n; i++) {leader_buf[i] = this->leader(i);group_size[leader_buf[i]]++;}std::vector> result(_n);for (size_type i = 0; i < _n; i++) {result[i].reserve(group_size[i]);}for (size_type i = 0; i < _n; i++) {result[leader_buf[i]].push_back(i);}result.erase(std::remove_if(result.begin(), result.end(),[&](const std::vector& v) { return v.empty(); }),result.end());return result;}};} /* [data_structure/disjoint_set_union.hpp] */ namespace lib {namespace internal {namespace graph_impl {template struct edge {private:inline static internal::size_t unique() { static internal::size_t id = 0; return id++; }public:using cost_type = cost_t;const internal::size_t id = unique();const size_type from, to; const cost_t cost;edge(const size_type u, const size_type v, const cost_t w) : from(u), to(v), cost(w) {}std::tuple _debug() const { return { from, to, cost }; };friend bool operator==(const edge& lhs, const edge& rhs) { return lhs.id == rhs.id; }friend bool operator!=(const edge& lhs, const edge& rhs) { return lhs.id != rhs.id; }};}}templatestruct graph : std::vector>> {using size_type = internal::size_t;using cost_type = C;using edge = typename internal::graph_impl::edge;enum class edge_type { undirected, directed };private:size_type _directed_edge_count, _undirected_edge_count;protected:inline void _add_edge(const size_type u, const size_type v, const cost_type w) {this->operator[](u).emplace_back(u, v, w);++this->_directed_edge_count;}public:explicit graph(const size_type n = 0) : std::vector>(n) {}inline void clear() { ITR(row, *this) row.clear(); }inline size_type vertexes() const { return this->size(); }inline size_type edges() const { return this->inputted.size(); }templateinline void add_edge(const size_type u, const size_type v, const cost_type w = 1) {assert(0 <= u and u < this->vertexes()), assert(0 <= v and v < this->vertexes());this->_add_edge(u, v, w);if constexpr(EDGE_TYPE == edge_type::undirected) this->_add_edge(v, u, w);++this->_undirected_edge_count;}inline void add_edge_bidirectionally(const size_type u, const size_type v, const cost_type w = 1) {this->add_edge(u, v, w);}templatevoid inline read(const size_type edges, Stream *const ist = &std::cin) {REP(edges) {size_type u, v; cost_type w = 1; *ist >> u >> v; if(ONE_ORIGIN) --u, --v;if(WEIGHTED) *ist >> w;this->add_edge(u, v, w);}}templatevoid inline read_bidirectionally(const size_type edges, Stream *const ist = &std::cin) {REP(edges) {size_type u, v; cost_type w = 1; *ist >> u >> v; if(ONE_ORIGIN) --u, --v;if(WEIGHTED) *ist >> w;this->add_edge(u, v, w);}}template inline void distances_without_cost(const size_type, std::vector *const) const;template inline std::vector distances_without_cost(const size_type) const;template inline void distances_with_01cost(const size_type, std::vector *const) const;template inline std::vector distances_with_01cost(const size_type) const;template inline void distances(const size_type, std::vector *const) const;template inline std::vector distances(const size_type) const;inline bool sort_topologically(std::vector *const ) const;inline bool sort_topologically() const;template inline bool sort_topologically_with_priority(std::vector *const) const;template inline bool sort_topologically_with_priority() const;inline size_type minimum_paph_cover_size_as_dag() const;templateinline cost_t minimum_spanning_tree_cost() const;templateinline cost_t maximum_spanning_tree_cost() const;inline dsu components() const;templateinline void from_grid(const G&, U = '.');templateinline distance_type build_manhattan_mst(const I, const I, const J, const J);};} /* [graph.hpp] */ /* #expanded [string.hpp] */ #include #include namespace lib {templateRes to_lower(const I first, const I last) {Res res;res.reserve(std::distance(first, last));std::transform(first, last, std::back_inserter(res), ::tolower);return res;}templateRes to_uppwer(const I first, const I last) {Res res;res.reserve(std::distance(first, last));std::transform(first, last, std::back_inserter(res), ::toupper);return res;}templateRes to_lower(const std::string str) {return to_lower(std::begin(str), std::end(str));}templateRes to_uppwer(const std::string str) {return to_uppwer(std::begin(str), std::end(str));}} /* [string.hpp] */ /* #expanded [adapter/set.hpp] */ #include #include #include #include /* #expanded [utility/functional.hpp] */ #include #include namespace lib {namespace internal {template constexpr T plus(const T a, const T b) { return std::plus{}(a, b); }template constexpr T minus(const T a, const T b) { return std::minus{}(a, b); }template constexpr T bitxor(const T a, const T b) { return a xor b; }}template inline auto mod(T1 x, T2 r) { return (x%r+r)%r; }template inline bool chmax(T1 &a, T2 b) { return (a inline bool chmin(T1 &a, T2 b) { return (a>b ? a=b, true : false); }template inline constexpr T sign(const T x) {return (x > 0) - (x < 0);}template inline constexpr T mapping(const T x) {return (x - FROM_MIN) * (TO_MAX - TO_MIN) / (FROM_MAX - FROM_MIN) + TO_MIN;}template inline constexpr T mapping(const T x, const T from_min, const T from_max, const T to_min, const T to_max) {return (x - from_min) * (to_max - to_min) / (from_max - from_min) + to_min;}} /* [utility/functional.hpp] */ namespace lib {namespace internal {template struct set_wrapper : set {using set::set;using size_type = internal::size_t;inline size_type size() const { return this->set::size(); }inline bool contains(const typename set::key_type& key) { return static_cast(this->count(key)); }inline auto remove(const typename set::key_type& key) { return this->erase(this->find(key)); }inline auto min_element() { return this->begin(); }inline auto max_element() { return this->begin(); }inline auto min() { return *this->begin(); }inline auto max() { return *this->end(); }inline void pop_min() { return this->erase(this->begin()); }inline void pop_max() { return this->erase(this->end()); }inline auto next_element(const typename set::key_type& key, const size_type _count = 0) {size_type count = std::abs(_count);auto itr = this->lower_bound(key);const auto begin = this->begin(), end = this->end();if(itr == end) return this->end();if(itr == begin) return this->begin();while(count--) {if(_count < 0) if(itr-- == begin) return this->begin();if(_count > 0) if(++itr == end) return this->end();}return itr;}inline auto prev_element(const typename set::key_type& key, const size_type _count = 0) {size_type count = std::abs(_count);auto itr = this->upper_bound(key);const auto begin = this->begin(), end = this->end();if(itr == end) return this->end();if(itr-- == begin) return this->begin();while(count--) {if(_count < 0) if(itr-- == begin) return this->begin();if(_count > 0) if(++itr == end) return this->end();}return itr;}inline std::optional next(const typename set::key_type& key, size_type count = 0) {auto itr = this->lower_bound(key);const auto end = this->end();if(itr == end) return {};while(count--) if(++itr == end) return {};return { *itr };}inline std::optional prev(const typename set::key_type& key, size_type count = 0) {auto itr = this->upper_bound(key);const auto begin = this->begin();if(itr-- == begin) return {};while(count--) if(itr-- == begin) return {};return { *itr };}};}template using set = internal::set_wrapper>;template using unordered_set = internal::set_wrapper>;template using multiset = internal::set_wrapper>;template using unordered_multiset = internal::set_wrapper>;} /* [adapter/set.hpp] */ /* #expanded [utility/applier.hpp] */ #include #include namespace lib {namespace internal {template T max(T a, T b) { return std::max(a, b); }template T max(T x) { return x; }template T max() { return -std::numeric_limits::min(); }template T min(T a, T b) { return std::min(a, b); }template T min(T x) { return x; }template T min() { return std::numeric_limits::max(); }}template struct applier {using value_type = T;protected:T _v;public:applier(const T& v = T{}) : _v(v) {}template applier& operator<<=(U&& val) & noexcept {_v = op(_v, std::forward(val));return *this;}inline T val() const { return _v; }inline operator T() const { return _v; }};template using maximum = applier>;template using minimum = applier>;} /* [utility/applier.hpp] */ /* #expanded [utility/restrictor.hpp] */ #include namespace lib {template struct static_restrictor {using restrictor = static_restrictor;protected:T _v;inline void _clamp() { this->_v = std::clamp(this->_v, INF, SUP); }inline restrictor& _assign(T v) {this->_v = std::clamp(v, INF, SUP);return *this;}public:static_restrictor(T v = T{}) : _v(v) {}inline T val() const { return this->_v; }restrictor& operator++() { return this->_assign(this->_v + 1); }restrictor& operator--() { return this->_assign(this->_v - 1); }restrictor operator++(int) {restrictor res = *this;*this++;return res;}restrictor operator--(int) {restrictor res = *this;*this--;return res;}restrictor& operator+=(const restrictor& rhs) { return this->_assign(this->_v + rhs.val()); }restrictor& operator-=(const restrictor& rhs) { return this->_assign(this->_v - rhs.val()); }restrictor& operator*=(const restrictor& rhs) {if(mul_over(this->_v, rhs.val(), SUP)) return this->_assign(SUP);if(mul_under(this->_v, rhs.val(), INF)) return this->_assign(INF);return this->_assign(this->_v * rhs.val());}restrictor& operator/=(const restrictor& rhs) { return this->_assign(this->_v / rhs.val()); }restrictor operator+() const { return *this; }restrictor operator-() const { return restrictor() - *this; }friend restrictor operator+(const restrictor& lhs, const restrictor& rhs) {return restrictor(lhs) += rhs;}friend restrictor operator-(const restrictor& lhs, const restrictor& rhs) {return restrictor(lhs) -= rhs;}friend restrictor operator*(const restrictor& lhs, const restrictor& rhs) {return restrictor(lhs) *= rhs;}friend restrictor operator/(const restrictor& lhs, const restrictor& rhs) {return restrictor(lhs) /= rhs;}friend bool operator==(const restrictor& lhs, const restrictor& rhs) {return lhs._v == rhs._v;}friend bool operator!=(const restrictor& lhs, const restrictor& rhs) {return lhs._v != rhs._v;}friend bool operator<(const restrictor& lhs, const restrictor& rhs) {return lhs._v < rhs._v;}friend bool operator>(const restrictor& lhs, const restrictor& rhs) {return lhs._v > rhs._v;}friend bool operator<=(const restrictor& lhs, const restrictor& rhs) {return lhs._v <= rhs._v;}friend bool operator>=(const restrictor& lhs, const restrictor& rhs) {return lhs._v >= rhs._v;}};}namespace std {templateT std::abs(const lib::static_restrictor& v) { return std::abs(v.val()); }} /* [utility/restrictor.hpp] */ /* #expanded [iterable/applied.hpp] */ #include #include #include namespace lib {template::value_type>>inline auto applied(const I first, const I last, F&& func) {C res(first, last);func(std::begin(res), std::end(res));return res;}templateinline auto applied(V v, F&& func) {return applied(std::begin(v), std::end(v), func);}templateinline auto sorted(const I first, const I last) {return applied(first, last, std::sort);}templateinline auto sorted(V v) {return applied(v, std::sort);}templateinline auto reversed(const I first, const I last) {return applied(first, last, std::reverse);}templateinline auto reversed(V v) {return applied(v, std::reverse);}} /* [iterable/applied.hpp] */ /* #expanded [iterable/accumulation.hpp] */ #include #include #include #include #include namespace lib {template>struct accumulation : container {using size_type = internal::size_t;protected:inline size_type _positivize_index(const size_type x) const {return x < 0 ? std::size(*this) + x : x;}public:accumulation() {}template>accumulation(const I first, const I last, const T head = T{}, const Operator op = std::plus{}) {this->assign(std::distance(first, last) + 1, {});std::exclusive_scan(first, last, std::begin(*this), head, op);if(this->size() > 1) *std::prev(this->end()) = op(*std::prev(std::end(*this), 2), *std::prev(last));}template>inline T operator()(size_type left, size_type right, Operaotr op = std::minus{}) const {left = _positivize_index(left), right = _positivize_index(right);assert(0 <= left and left <= right and right < (size_type)std::size(*this));return op((*this)[right], (*this)[left]);}};template>, class Operator = std::plus>struct accumulation_2d : container {using size_type = internal::size_t;protected:inline size_type _positivize_index(const size_type x) const {return x < 0 ? std::size(*this) + x : x;}Operator _op;public:accumulation_2d() {}templateaccumulation_2d(const I first, const I last, const T head = T{}, const Operator op = std::plus{}) : _op(op) {const size_type h = std::distance(first, last);const size_type w = std::distance(std::begin(*first), std::end(*first));{auto row = first;this->assign(h+1, head);(*this)[0].assign(w+1, head);REP(i, h) {assert(w == std::distance(std::begin(*row), std::end(*row)));(*this)[i+1].assign(w+1, head);REP(j, w) (*this)[i+1][j+1] = first[i][j];++row;}}FOR(i, 1, h) FOR(j, w) (*this)[i][j] = op((*this)[i][j], (*this)[i-1][j]);FOR(i, h) FOR(j, 1, w) (*this)[i][j] = op((*this)[i][j], (*this)[i][j-1]);}template>inline T operator()(size_type a, size_type b, size_type c, size_type d, const Rev rev = std::minus{}) const {a = _positivize_index(a), b = _positivize_index(b);c = _positivize_index(c), d = _positivize_index(d);assert(0 <= a and a <= b and b < (size_type)std::size(*this));assert(0 <= c and c <= d and d < (size_type)std::size((*this)[0]));return this->_op(rev((*this)[b][d], this->_op((*this)[a][d], (*this)[b][c])), (*this)[a][c]);}template>inline T operator()(const std::pair p, const std::pair q, const Rev rev = std::minus{}) const {return this->operator()(p.first, p.second, q.first, q.second, rev);}};} /* [iterable/accumulation.hpp] */ /* #expanded [iterable/operation.hpp] */ #include #include #include namespace lib {templatestd::string join(const I first, const I last, const std::string& sep = "") {std::ostringstream res;std::copy(first, last, std::ostream_iterator::value_type>(res, sep));return res.str();}templatestd::string join(V& v, const std::string& sep = "") {return join(std::begin(v), std::end(v), sep);}template::value_type>T sum(const I first, const I second, const T& base = 0) {return std::accumulate(first, second, base);}templateauto sum(V& v, T base = 0) {return sum(std::begin(v), std::end(v), base);}} /* [iterable/operation.hpp] */ /* #expanded [iterable/mex.hpp] */ #include #include namespace lib {template::value_type>T mex(const I first, const I last, const T& base = 0) {std::vector val(first, last);std::sort(val.begin(), val.end());val.erase(std::unique(val.begin(), val.end()), val.end());val.erase(val.begin(), std::lower_bound(val.begin(), val.end(), base));internal::size_t i = 0;while(i < (internal::size_t)val.size() and val[i] == T{i} + base) ++i;return T{i} + base;}templateauto mex(const V v, const T& base = 0) {return mex(v.begin(), v.end(), base);}} /* [iterable/mex.hpp] */ /* [utilities.hpp] */ using std::cin;using std::cout;using std::pair;using std::tuple;using std::vector;using std::array;using std::string;using std::queue;using std::stack;using std::priority_queue;using std::bitset;using std::sort;using std::reverse;using std::map;using std::unordered_map;using std::min_element;using std::max_element;using lib::i32;using lib::u32;using lib::i64;using lib::u64; #ifdef __GNUC__ using lib::i128;using lib::u128; #endif using lib::uint;using lib::ll;using lib::ull;using lib::ld;using lib::INF32;using lib::INF64;using lib::LN;using lib::SPC;using lib::DIRS4;using lib::DIRS8;using lib::nPr;using lib::nCr;using lib::pow;using lib::pow_mod;using lib::inv_mod;using lib::spair;using lib::valarray;using lib::multi_container;using lib::minimum;using lib::maximum;using lib::modint998244353;using lib::modint1000000007;using lib::modint;using lib::modint64;using lib::sorted;using lib::reversed;using lib::join;using lib::chmin;using lib::chmax;using lib::grid;using lib::graph;using lib::matrix;using lib::unordered_multiset;using lib::set;using lib::unordered_set;using lib::multiset;using lib::unordered_multiset; /* [snippet/using.hpp] */ #ifdef LOCAL_JUDGE #include #define debug(...) debugger::debug(debugger::split(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__) #define DEBUG(...) do { debugger::DEBUG(nullptr, "\033[3;35m#" + std::to_string(__LINE__) + "\033[m "); debugger::DEBUG(__VA_ARGS__); debugger::DEBUG(nullptr, "\033[m\n"); } while(0); #else #define debug(...) ({ ; }) #define DEBUG(...) ({ ; }) #endif /* #expanded [adapter/input.hpp] */ #include #include #include #include #include #include /* #expanded [internal/resolving_rank.hpp] */ namespace lib {namespace internal {template struct resolving_rank : resolving_rank {};template<> struct resolving_rank<0> {};}} /* [internal/resolving_rank.hpp] */ templatestruct input_adapter {private:templateauto _set(lib::internal::resolving_rank<3>, T *const val) -> decltype(std::declval() >> *val, 0) {*this->in >> *val;return 0;}templateauto _set(lib::internal::resolving_rank<2>, T *const val) -> decltype(std::begin(*val), std::end(*val), 0) {(*this)(std::begin(*val), std::end(*val));return 0;}templateauto _set(lib::internal::resolving_rank<1>, T *const val) -> decltype(val->first, val->second, 0) {(*this)(&*val);return 0;}templateauto _set(lib::internal::resolving_rank<0>, T *const val) -> std::enable_if_t::value,int> {long long v; std::cin >> v;*val = { v };return 0;}protected:templatesource *set(T *const val) {this->_set(lib::internal::resolving_rank<3>{}, val);return this->in;}public:using char_type = typename source::char_type;source *in;input_adapter(source *in = &std::cin) : in(in) {}template inline input_adapter& operator>>(T &s) {this->set(&s);return *this;}template inline T one() {T val; *this >> val;return val;}template inline void operator()(T*const val) {*this >> *val;}template inline void operator()(T *const head, Args *const... tail) {*this >> *head;(*this)(tail...);}template::value_type> inline void operator()(I first, I last) {for(I itr=first; itr!=last; ++itr) *this >> *itr;}template inline void operator()(std::pair *const p) {*this >> p->first >> p->second;}}; /* [adapter/input.hpp] */ /* #expanded [adapter/output.hpp] */ #include #include #include #include #include templatestruct output_adapter {private:templateauto _put(lib::internal::resolving_rank<2>, const T &val) -> decltype(std::declval() << val, 0) {*this->out << val;return 0;}templateauto _put(lib::internal::resolving_rank<1>, const T &val) -> decltype(val.val(), 0) {this->put(val.val());return 0;}templateauto _put(lib::internal::resolving_rank<0>, const T &val) -> decltype(std::begin(val), std::end(val), 0) {(*this)(std::begin(val), std::end(val), false);return 0;}protected:templatedestination *put(const T &val) {this->_put(lib::internal::resolving_rank<2>{}, val);return this->out;}public:using char_type = typename destination::char_type;static constexpr auto sendl = std::endl>;destination *out;Terminator endline;Separator separator;output_adapter(destination *out = &std::cout, Terminator endline = "\n", Separator separator = " "): out(out), endline(endline), separator(separator){*this << std::fixed << std::setprecision(20);}inline void seekp(const typename destination::off_type off, const std::ios_base::seekdir dir = std::ios_base::cur) { this->out->seekp(off, dir); };template inline output_adapter& operator<<(const T &s) {this->put(s);return *this;}template inline void operator()(const T &val = "") {*this << val << this->endline;}template inline void operator()(const T &head, const Args& ...tail) {*this << head << this->separator;(*this)(tail...);}template::iterator_category> inline void operator()(const I first, const I last, const bool terminate = true) {for(I itr=first; itr!=last;) {*this << *itr;if(++itr == last) {if(terminate) *this << this->endline;}else *this << this->separator;}}template inline void operator()(const std::initializer_list vals) {std::vector wrapped(vals.begin(), vals.end());(*this)(wrapped.begin(), wrapped.end());}template inline void operator()(const std::pair &p) {(*this)(p.first, p.second);}}; /* [adapter/output.hpp] */ input_adapter _input;output_adapter _print; #define input _input #define print _print /* [template.hpp] */ /* #endregion */ void solve(); signed main() { int $ = 1; // std::cin >> $; for(int _ = 0; _ < $; ++_) { DEBUG("Case: #" + std::to_string(_)); solve(); } return 0; } /* #expanded [iterable/counter.hpp] */ #include #include namespace lib {template>struct counter : container {counter() {}template counter(const I first, const I last) {for(auto itr=first; itr!=last; ++itr) ++(*this)[*itr];}};} /* [iterable/counter.hpp] */ void solve() { i64 n, p; cin >> n >> p; valarray a(n); input >> a; debug(a); i64 ans = 0; for(int k=1; lib::pow(p, k) <= INF32; ++k) { valarray b = a; b %= lib::pow(p, k); lib::counter cnt(ALL(b)); debug(cnt); ITR(v, cnt) ans += lib::nCr(v.second, 2); debug(ans); } print(ans); }