結果
問題 | No.1549 [Cherry 2nd Tune] BANning Tuple |
ユーザー |
![]() |
提出日時 | 2021-06-11 22:07:12 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 494 ms / 4,000 ms |
コード長 | 60,233 bytes |
コンパイル時間 | 1,712 ms |
コンパイル使用メモリ | 107,800 KB |
最終ジャッジ日時 | 2025-01-22 05:55:46 |
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 20 |
ソースコード
#line 2 "Library\\src\\algebra\\polynomial.hpp"/*** @file polynomial.hpp* @brief Polynomial*/#include <algorithm>#include <cassert>#include <vector>#line 2 "Library\\lib\\cxx17"#ifndef _CXX17_CONSTEXPR#if __cplusplus >= 201703L#define _CXX17_CONSTEXPR constexpr#else#define _CXX17_CONSTEXPR#endif#endif#line 2 "Library\\src\\algebra\\ntt.hpp"/*** @file ntt.hpp* @brief Number Theoretic Transform* @date 2021-02-20***/#line 2 "Library\\src\\number_theory\\ext_gcd.hpp"/*** @file ext_gcd.hpp* @brief Extended Euclidean Algorithm*/#include <tuple>#line 2 "Library\\src\\utils\\sfinae.hpp"/*** @file sfinae.hpp* @brief SFINAE*/#include <cstdint>#include <iterator>#include <type_traits>#ifndef __INT128_DEFINED__#ifdef __SIZEOF_INT128__#define __INT128_DEFINED__ 1#else#define __INT128_DEFINED__ 0#endif#endifnamespace std {#if __INT128_DEFINED__template <> struct make_signed<__uint128_t> { using type = __int128_t; };template <> struct make_signed<__int128_t> { using type = __int128_t; };template <> struct make_unsigned<__uint128_t> { using type = __uint128_t; };template <> struct make_unsigned<__int128_t> { using type = __uint128_t; };template <> struct is_signed<__uint128_t> : std::false_type {};template <> struct is_signed<__int128_t> : std::true_type {};template <> struct is_unsigned<__uint128_t> : std::true_type {};template <> struct is_unsigned<__int128_t> : std::false_type {};#endif} // namespace stdnamespace workspace {template <class Tp, class... Args> struct variadic_front { using type = Tp; };template <class... Args> struct variadic_back;template <class Tp> struct variadic_back<Tp> { using type = Tp; };template <class Tp, class... Args> struct variadic_back<Tp, Args...> {using type = typename variadic_back<Args...>::type;};template <class type, template <class> class trait>using enable_if_trait_type = typename std::enable_if<trait<type>::value>::type;/*** @brief Return type of subscripting ( @c [] ) access.*/template <class _Tp>using subscripted_type =typename std::decay<decltype(std::declval<_Tp&>()[0])>::type;template <class Container>using element_type = typename std::decay<decltype(*std::begin(std::declval<Container&>()))>::type;template <class _Tp, class = std::nullptr_t>struct has_begin : std::false_type {};template <class _Tp>struct has_begin<_Tp, decltype(std::begin(std::declval<_Tp>()), nullptr)>: std::true_type {};template <class _Tp, class = void> struct has_mod : std::false_type {};template <class _Tp>struct has_mod<_Tp, std::__void_t<decltype(_Tp::mod)>> : std::true_type {};template <class _Tp, class = void> struct is_integral_ext : std::false_type {};template <class _Tp>struct is_integral_ext<_Tp, typename std::enable_if<std::is_integral<_Tp>::value>::type>: std::true_type {};#if __INT128_DEFINED__template <> struct is_integral_ext<__int128_t> : std::true_type {};template <> struct is_integral_ext<__uint128_t> : std::true_type {};#endif#if __cplusplus >= 201402template <class _Tp>constexpr static bool is_integral_ext_v = is_integral_ext<_Tp>::value;#endiftemplate <typename _Tp, typename = void> struct multiplicable_uint {using type = uint_least32_t;};template <typename _Tp>struct multiplicable_uint<_Tp,typename std::enable_if<(2 < sizeof(_Tp)) &&(!__INT128_DEFINED__ || sizeof(_Tp) <= 4)>::type> {using type = uint_least64_t;};#if __INT128_DEFINED__template <typename _Tp>struct multiplicable_uint<_Tp,typename std::enable_if<(4 < sizeof(_Tp))>::type> {using type = __uint128_t;};#endiftemplate <typename _Tp> struct multiplicable_int {using type =typename std::make_signed<typename multiplicable_uint<_Tp>::type>::type;};template <typename _Tp> struct multiplicable {using type = std::conditional_t<is_integral_ext<_Tp>::value,std::conditional_t<std::is_signed<_Tp>::value,typename multiplicable_int<_Tp>::type,typename multiplicable_uint<_Tp>::type>,_Tp>;};template <class> struct first_arg { using type = void; };template <class _R, class _Tp, class... _Args>struct first_arg<_R(_Tp, _Args...)> {using type = _Tp;};template <class _R, class _Tp, class... _Args>struct first_arg<_R (*)(_Tp, _Args...)> {using type = _Tp;};template <class _G, class _R, class _Tp, class... _Args>struct first_arg<_R (_G::*)(_Tp, _Args...)> {using type = _Tp;};template <class _G, class _R, class _Tp, class... _Args>struct first_arg<_R (_G::*)(_Tp, _Args...) const> {using type = _Tp;};template <class _Tp, class = void> struct parse_compare : first_arg<_Tp> {};template <class _Tp>struct parse_compare<_Tp, std::__void_t<decltype(&_Tp::operator())>>: first_arg<decltype(&_Tp::operator())> {};} // namespace workspace#line 11 "Library\\src\\number_theory\\ext_gcd.hpp"namespace workspace {/*** @param __a Integer* @param __b Integer* @return Pair of integers (x, y) s.t. ax + by = g = gcd(a, b), 0 <= x <* |b/g|, -|a/g| < y <= 0. Return (0, 0) if (a, b) = (0, 0).*/template <typename _T1, typename _T2> constexpr auto ext_gcd(_T1 __a, _T2 __b) {static_assert(is_integral_ext<_T1>::value);static_assert(is_integral_ext<_T2>::value);using result_type = typename std::make_signed<typename std::common_type<_T1, _T2>::type>::type;result_type a{__a}, b{__b}, p{1}, q{}, r{}, s{1};// Euclidean algorithmwhile (b) {result_type t = a / b;r ^= p ^= r ^= p -= t * r;s ^= q ^= s ^= q -= t * s;b ^= a ^= b ^= a -= t * b;}// Normalizeif (a < 0) p = -p, q = -q;if (p < 0) p += __b / a, q -= __a / a;return std::make_pair(p, q);}} // namespace workspace#line 2 "Library\\src\\number_theory\\primitive_root.hpp"/*** @file primitive_root.hpp* @brief Primitive Root* @date 2020-12-28*/#line 10 "Library\\src\\number_theory\\primitive_root.hpp"namespace workspace {/*** @brief Compile time primitive root.** @tparam __mod Positive integer* @return Minimum positive one if it exists. Otherwise 0.*/template <class Tp>constexpr typename std::enable_if<(is_integral_ext<Tp>::value), Tp>::typeprimitive_root(const Tp __mod) noexcept {assert(__mod > 0);using int_type = typename multiplicable_uint<Tp>::type;int_type __r = __mod, __p[16] = {}, *__q = __p;for (int_type __i = 2; __i <= __r / __i; ++__i) {if (__r % __i) continue;*__q++ = __i;while (!(__r % __i)) __r /= __i;}if (__r != 1) *__q++ = __r;int_type __tot = __mod;for (__q = __p; *__q; *__q++ = 0) (__tot /= *__q) *= *__q - 1;__r = __tot, __q = __p + 1, __p[0] = 1;for (int_type __i = 2; __i <= __r / __i; ++__i) {if (__r % __i) continue;*__q++ = __i;while (!(__r % __i)) __r /= __i;}if (__r != 1) *__q++ = __r;for (Tp __r = 1; __r != __mod; ++__r) {auto __cnt = 0;for (__q = __p; *__q; ++__q) {int_type __w = 1;for (int_type __e = __tot / *__q, __x = __r; __e;__e >>= 1, (__x *= __x) %= __mod)if (__e & 1) (__w *= __x) %= __mod;if (__w == 1 && ++__cnt > 1) break;}if (__cnt == 1) return __r;}return 0;};} // namespace workspace#line 13 "Library\\src\\algebra\\ntt.hpp"namespace workspace {namespace ntt_impl {/*** @see* https://github.com/atcoder/ac-library/blob/master/atcoder/convolution.hpp*/template <class _Tp> struct __coef {_Tp sum_e[30]; // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]constexpr __coef() : sum_e{} {if (_Tp::mod < 2) return;int cnt2 = __builtin_ctz(_Tp::mod - 1);_Tp e = 1;{auto p = (_Tp::mod - 1) >> cnt2;_Tp w = primitive_root(_Tp::mod);while (p) {if (p & 1) e *= w;p >>= 1;w *= w;}}_Tp ie = ext_gcd(decltype(_Tp::mod)(e), _Tp::mod).first;_Tp es[30] = {}, ies[30] = {}; // es[i]^(2^(2+i)) == 1for (int i = cnt2; i >= 2; i--) {// e^(2^i) == 1es[i - 2] = e;ies[i - 2] = ie;e *= e;ie *= ie;}_Tp now = 1;for (int i = 0; i <= cnt2 - 2; i++) {sum_e[i] = es[i] * now;now *= ies[i];}}};template <class _Tp> struct __icoef {_Tp sum_ie[30]; // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]constexpr __icoef() : sum_ie{} {if (_Tp::mod < 2) return;int cnt2 = __builtin_ctz(_Tp::mod - 1);_Tp e = 1;{auto p = (_Tp::mod - 1) >> cnt2;_Tp w = primitive_root(_Tp::mod);while (p) {if (p & 1) e *= w;p >>= 1;w *= w;}}_Tp ie = ext_gcd(decltype(_Tp::mod)(e), _Tp::mod).first;_Tp es[30] = {}, ies[30] = {}; // es[i]^(2^(2+i)) == 1for (int i = cnt2; i >= 2; i--) {// e^(2^i) == 1es[i - 2] = e;ies[i - 2] = ie;e *= e;ie *= ie;}_Tp now = 1;for (int i = 0; i <= cnt2 - 2; i++) {sum_ie[i] = ies[i] * now;now *= es[i];}}};template <class _Tp> struct __ipow2 {_Tp __ip2[30];constexpr __ipow2() : __ip2{1, (1 + _Tp::mod) / 2} {for (size_t __i = 1; __i + 1 != std::size(__ip2); ++__i)__ip2[__i + 1] = __ip2[__i] * __ip2[1];}};template <class _FIter>constexpr void ntt(_FIter __first, _FIter __last) noexcept {using value_type = typename std::decay<decltype(*__first)>::type;constexpr __coef<value_type> _;auto __h = __builtin_ctz(std::distance(__first, __last));for (ptrdiff_t __p = 1 << __h; __p >>= 1;) {value_type now = -1;auto __l = __first;for (size_t __s = 1 << __h; __l != __last;now *= _.sum_e[__builtin_ctz(--__s)]) {auto __r = __l + __p;for (auto __mid = __r; __l != __mid; ++__l, ++__r) {auto __tmp = *__l;*__l -= *__r *= now;*__r += __tmp;}__l = __r;}}}template <class _A> constexpr void ntt(_A &a) noexcept {ntt(std::begin(a), std::end(a));}template <class _FIter>constexpr void intt(_FIter __first, _FIter __last) noexcept {using value_type = typename std::decay<decltype(*__first)>::type;constexpr __icoef<value_type> _;auto __h = __builtin_ctz(std::distance(__first, __last));for (ptrdiff_t __p = 1; __p >> __h ^ 1; __p <<= 1) {value_type inow = 1;auto __l = __first;for (size_t __s = 1 << __h; __l != __last;inow *= _.sum_ie[__builtin_ctz(--__s)]) {auto __r = __l + __p;for (auto __mid = __r; __l != __mid; ++__l, ++__r) {auto __tmp = (*__l - *__r) * inow;*__l += *__r;*__r = __tmp;}__l = __r;}}constexpr __ipow2<value_type> __;while (__first != __last) *--__last *= __.__ip2[__h];} // namespace ntt_impltemplate <class _A> constexpr void intt(_A &a) noexcept {intt(std::begin(a), std::end(a));}} // namespace ntt_implusing ntt_impl::intt;using ntt_impl::ntt;} // namespace workspace#line 15 "Library\\src\\algebra\\polynomial.hpp"namespace workspace {/*** @brief Polynomial.** @tparam _Tp Ring structure* @tparam _Conv_threshold Threshold for convolution method*/template <class _Tp, std::size_t _Conv_threshold = 64>class polynomial : public std::vector<_Tp> {using vec = std::vector<_Tp>;using poly = polynomial;template <class _Os> friend _Os& operator<<(_Os& __os, const poly& __x) {bool __head = true;for (const auto& __a : __x) {if (!__head) __os << ' ';__head = false;__os << __a;}return __os;}public:using vec::vec;using size_type = typename vec::size_type;protected:void _erase_leading_zeros() noexcept {auto __i = vec::_M_impl._M_finish;while (__i != vec::_M_impl._M_start && *(__i - 1) == _Tp(0)) --__i;vec::_M_erase_at_end(__i);}template <class _Iter> void _dft(_Iter __first, _Iter __last) const noexcept {if _CXX17_CONSTEXPR (has_mod<_Tp>::value)ntt(__first, __last);else {// fft(__first, __last);assert(0); // Not implemented!}}template <class _Iter>void _idft(_Iter __first, _Iter __last) const noexcept {if _CXX17_CONSTEXPR (has_mod<_Tp>::value)intt(__first, __last);else {// ifft(__first, __last);assert(0); // Not implemented!}}void _conv_naive(const poly& __x) noexcept {if (vec::_M_impl._M_start == vec::_M_impl._M_finish) return;if (__x._M_impl._M_start == __x._M_impl._M_finish) {vec::_M_erase_at_end(vec::_M_impl._M_start);return;}vec::_M_default_append(__x._M_impl._M_finish - __x._M_impl._M_start - 1);for (auto __i = vec::_M_impl._M_finish; __i-- != vec::_M_impl._M_start;) {auto __j = __i, __k = __x._M_impl._M_start;*__i *= *__k++;while (__j != vec::_M_impl._M_start && __k != __x._M_impl._M_finish)*__i += *--__j * *__k++;}}void _conv_dft(poly&& __x) noexcept {if _CXX17_CONSTEXPR (has_mod<_Tp>::value)_conv_ntt(std::move(__x));else {// _conv_fft(std::move(__x));assert(0); // Not implemented!}}void _conv_fft(poly&& __x) noexcept;void _conv_ntt(poly&& __x) noexcept {size_type __n = vec::_M_impl._M_finish - vec::_M_impl._M_start,__m = __x._M_impl._M_finish - __x._M_impl._M_start,__len = 1 << (32 - __builtin_clz(__n + __m - 1));vec::_M_default_append(__len - __n);__x._M_default_append(__len - __m);ntt(vec::_M_impl._M_start, vec::_M_impl._M_finish);ntt(__x._M_impl._M_start, __x._M_impl._M_finish);for (auto __i = vec::_M_impl._M_start, __j = __x._M_impl._M_start;__i != vec::_M_impl._M_finish; ++__i, ++__j)*__i *= std::move(*__j);intt(vec::_M_impl._M_start, vec::_M_impl._M_finish);vec::_M_erase_at_end(vec::_M_impl._M_start + __n + __m - 1);}/*** @brief** @param __x* @return Degree of __x.*/size_type _divmod_naive(const poly& __x) {auto __xfin = __x._M_impl._M_finish;auto __xlen = __x.size();while (__xfin != __x._M_impl._M_start && *(__xfin - 1) == _Tp(0))--__xfin, --__xlen;assert(__xlen != 0);_erase_leading_zeros();auto __p = vec::_M_impl._M_finish;while (size_type(__p - vec::_M_impl._M_start) >= __xlen) {--__p;auto __src = __xfin;auto __dst = __p;*__dst /= *--__src;while (__src != __x._M_impl._M_start) *--__dst -= *--__src * *__p;}return std::min<size_type>(__xlen - 1, __p - vec::_M_impl._M_start);}void _div_naive(const poly& __x) { operator>>=(_divmod_naive(__x)); }void _div_doubling(poly&& __x) noexcept {_erase_leading_zeros();__x._erase_leading_zeros();auto __n = vec::_M_impl._M_finish - vec::_M_impl._M_start;auto __m = __x._M_impl._M_finish - __x._M_impl._M_start;if (__n < __m)vec::clear();else {assert(__m != 0);std::reverse(__x._M_impl._M_start, __x._M_impl._M_finish);__x = __x.inv(__n - __m + 1);std::reverse(vec::_M_impl._M_start, vec::_M_impl._M_finish);vec::_M_erase_at_end(vec::_M_impl._M_finish - (__m - 1));operator*=(__x).resize(__n - __m + 1);std::reverse(vec::_M_impl._M_start, vec::_M_impl._M_finish);}}public:/*** @return Degree of %polynomial. Return -1 if it equals zero.*/size_type deg() const noexcept { return vec::size() - 1; }/*** @param __i Not exceeding the degree.* @return Coefficient of x^i.*/typename vec::reference operator[](size_type __i) noexcept {assert(__i < vec::size());return *(vec::_M_impl._M_start + __i);}/*** @param __i Not exceeding the degree.* @return Coefficient of x^i.*/typename vec::const_reference operator[](size_type __i) const noexcept {assert(__i < vec::size());return *(vec::_M_impl._M_start + __i);}/*** @brief Evaluate at given point.*/_Tp eval(const _Tp& __a) const noexcept {_Tp __v(0), __p(1);for (auto __i = vec::_M_impl._M_start; __i != vec::_M_impl._M_finish;++__i, __p *= __a)__v += *__i * __p;return __v;}/*** @brief In-place multipoint evaluation.*/template <class _Iter, typename = std::_RequireInputIter<_Iter>>_Iter eval(_Iter __first, _Iter __last) const noexcept {return eval(__first, __last, __first);}/*** @brief Multipoint evaluation.*/template <class _InputIter, class _OutputIter,typename = std::_RequireInputIter<_InputIter>>_OutputIter eval(_InputIter __first, _InputIter __last,_OutputIter __result) const noexcept {size_type __n = std::distance(__first, __last);if (!__n) return __result;auto __tree = new poly[__n << 1];for (auto __p = __tree + __n; __first != __last; ++__p, ++__first)*__p = {-*__first, 1};for (size_type __i = __n; --__i;)__tree[__i] = __tree[__i << 1] * __tree[__i << 1 | 1];__tree[1] = operator%(std::move(__tree[1]));for (size_type __i = 2; __i != __n << 1; __i += 2)__tree[__i] = __tree[__i >> 1] % std::move(__tree[__i]),__tree[__i | 1] =std::move(__tree[__i >> 1] %= std::move(__tree[__i | 1]));for (size_type __i = 0; __i != __n; ++__i)*__result++ = std::move(*__tree[__n + __i]._M_impl._M_start);delete[] __tree;return __result;}/*** @brief Conversion to bool.** @return Whether the %polynomial is not zero.*/operator bool() const noexcept {auto __first = vec::_M_impl._M_start, __last = vec::_M_impl._M_finish;while (__first != __last)if (*__first++ != _Tp(0)) return true;return false;}bool operator==(const poly& __x) const noexcept {auto __first1 = vec::_M_impl._M_start, __last1 = vec::_M_impl._M_finish;auto __first2 = __x._M_impl._M_start, __last2 = __x._M_impl._M_finish;if (__last1 - __first1 < __last2 - __first2) {while (__first1 != __last1)if (*__first1++ != *__first2++) return false;while (__first2 != __last2)if (*__first2++ != _Tp(0)) return false;}else {while (__first2 != __last2)if (*__first1++ != *__first2++) return false;while (__first1 != __last1)if (*__first1++ != _Tp(0)) return false;}return true;}bool operator!=(const poly& __x) const noexcept { return !operator==(__x); }/*** @brief Multiply by x^i.*/poly& operator<<=(size_type __i) noexcept {vec::insert(vec::begin(), __i, _Tp(0));return *this;}/*** @brief Divide by x^i.*/poly& operator>>=(size_type __i) noexcept {vec::_M_erase_at_end(std::move(vec::_M_impl._M_start + std::min(__i, vec::size()),vec::_M_impl._M_finish, vec::_M_impl._M_start));return *this;}/*** @brief Multiply by x^i.*/poly operator<<(size_type __i) const noexcept {return poly(*this).operator<<=(__i);}/*** @brief Divide by x^i.*/poly operator>>(size_type __i) const noexcept {return poly(*this).operator>>=(__i);}poly operator+() const noexcept { return *this; }poly operator-() const noexcept {poly __x = *this;for (auto __i = __x._M_impl._M_start; __i != __x._M_impl._M_finish; ++__i)*__i = -*__i;return __x;}poly& operator+=(const poly& __x) noexcept {if (vec::size() < __x.size())vec::_M_default_append(__x.size() - vec::size());for (auto __i = vec::_M_impl._M_start, __j = __x._M_impl._M_start;__j != __x._M_impl._M_finish; ++__i, ++__j)*__i += *__j;_erase_leading_zeros();return *this;}poly& operator+=(const _Tp& __c) noexcept {if (__c != static_cast<_Tp>(0)) {if (vec::_M_impl._M_start == vec::_M_impl._M_finish)vec::emplace_back(__c);else*vec::_M_impl._M_start += __c, _erase_leading_zeros();}return *this;}poly& operator-=(const poly& __x) noexcept {if (vec::size() < __x.size())vec::_M_default_append(__x.size() - vec::size());for (auto __i = vec::_M_impl._M_start, __j = __x._M_impl._M_start;__j != __x._M_impl._M_finish; ++__i, ++__j)*__i -= *__j;_erase_leading_zeros();return *this;}poly& operator-=(const _Tp& __c) noexcept {if (__c != static_cast<_Tp>(0)) {if (vec::_M_impl._M_start == vec::_M_impl._M_finish)vec::emplace_back(-__c);else*vec::_M_impl._M_start -= __c, _erase_leading_zeros();}return *this;}poly& operator*=(const poly& __x) noexcept {std::min(vec::size(), __x.size()) > _Conv_threshold? _conv_dft(poly(__x)): _conv_naive(this == std::addressof(__x) ? poly(__x) : __x);return *this;}poly& operator*=(poly&& __x) noexcept {std::min(vec::size(), __x.size()) > _Conv_threshold? _conv_dft(std::move(__x)): _conv_naive(__x);return *this;}poly& operator*=(const _Tp& __c) noexcept {if (__c == static_cast<_Tp>(0))vec::_M_erase_at_end(vec::_M_impl._M_start);elsefor (auto __i = vec::_M_impl._M_start; __i != vec::_M_impl._M_finish;++__i)*__i *= __c;return *this;}poly& operator/=(const _Tp& __c) noexcept {assert(__c != static_cast<_Tp>(0));for (auto __i = vec::_M_impl._M_start; __i != vec::_M_impl._M_finish; ++__i)*__i /= __c;return *this;}poly rev() const noexcept { return rev(vec::size()); }poly rev(size_type __n) const noexcept {poly __r(__n);auto __src = vec::_M_impl._M_start;auto __dst = __r._M_impl._M_finish;for (size_type __i = std::min(__n, vec::size()); __i; --__i)*--__dst = *__src++;return __r;}poly inv() const noexcept { return inv(vec::size()); }/*** @brief Multiplicative inverse modulo x^n.** @param __n Degree of modulus* @return*/poly inv(size_type __n) const noexcept {if (!__n) return {};assert(*vec::_M_impl._M_start != _Tp(0));size_type __len = 1;while (__len < __n) __len <<= 1;poly __y(__len);auto __xp = new _Tp[__len], __yp = __y._M_impl._M_start,__zp = new _Tp[__len];*__yp = _Tp(1) / *vec::_M_impl._M_start;for (size_type __i = 1; __i != __len; __i <<= 1) {std::fill(std::copy_n(__yp, __i, __zp), __zp + (__i << 1), _Tp(0));_dft(__zp, __zp + (__i << 1));std::fill(std::copy_n(vec::_M_impl._M_start,std::min(__i << 1, vec::size()), __xp),__xp + (__i << 1), _Tp(0));_dft(__xp, __xp + (__i << 1));for (size_type __j = 0; __j != (__i << 1); ++__j) __xp[__j] *= -__zp[__j];_idft(__xp, __xp + (__i << 1));std::fill(std::move(__xp + __i, __xp + (__i << 1), __xp),__xp + (__i << 1), _Tp(0));_dft(__xp, __xp + (__i << 1));for (size_type __j = 0; __j != (__i << 1); ++__j)__xp[__j] *= static_cast<_Tp&&>(__zp[__j]);_idft(__xp, __xp + (__i << 1));std::move(__xp, __xp + __i, __yp + __i);}delete[] __xp;delete[] __zp;__y._M_erase_at_end(__yp + __n);return __y;}poly& operator/=(const poly& __x) noexcept {if (__x.size() > _Conv_threshold)_div_doubling(poly(__x));else_div_naive(__x);return *this;}poly& operator/=(poly&& __x) noexcept {if (__x.size() > _Conv_threshold)_div_doubling(std::move(__x));else_div_naive(__x);return *this;}poly& operator%=(const poly& __x) noexcept {if (__x.size() > _Conv_threshold)return operator-=(__x.operator*(operator/(__x)));vec::_M_erase_at_end(vec::_M_impl._M_start + _divmod_naive(__x));return *this;}template <class _T> poly operator+(_T&& __x) const noexcept {return poly(*this).operator+=(std::forward<_T>(__x));}template <class _T> poly operator-(_T&& __x) const noexcept {return poly(*this).operator-=(std::forward<_T>(__x));}template <class _T> poly operator*(_T&& __x) const noexcept {return poly(*this).operator*=(std::forward<_T>(__x));}template <class _T> poly operator/(_T&& __x) const noexcept {return poly(*this).operator/=(std::forward<_T>(__x));}template <class _T> poly operator%(_T&& __x) const noexcept {return poly(*this).operator%=(std::forward<_T>(__x));}std::pair<poly, poly> divmod(const poly& __x) const {if (__x.size() > _Conv_threshold) return {operator/(__x), operator%(__x)};poly __rem(*this);auto __p = __rem._M_impl._M_start + __rem._divmod_naive(__x);poly __quot(__p, __rem._M_impl._M_finish);__rem._M_erase_at_end(__p);return {__quot, __rem};}/*** @brief Differentiate.** @return Derivative.*/poly deriv() const noexcept {if (auto __s = vec::_M_impl._M_start, __f = vec::_M_impl._M_finish;__s != __f) {poly __der(++__s, __f);__s = __der._M_impl._M_start, __f = __der._M_impl._M_finish;for (_Tp __i(1); __s != __f; ++__s, __i += 1) *__s *= __i;__der._erase_leading_zeros();return __der;}return {};}/*** @brief Differentiate at given point.** @return Derivative coefficient.*/_Tp deriv(const _Tp& __a) const noexcept {_Tp __der(0);if (auto __s = vec::_M_impl._M_start, __f = vec::_M_impl._M_finish;__s != __f)for (_Tp __i(1), __p(1); ++__s != __f; __i += 1, __p *= __a)__der += *__s * __i * __p;return __der;}/*** @brief Integrate.** @return Integral indefinite at the degrees divisible by the characteristic* of `_Tp`. Coefficients are set as 0 there.*/poly integ() const noexcept {if (auto __s = vec::_M_impl._M_start, __f = vec::_M_impl._M_finish;__s != __f) {poly __int(__f - __s + 1);__f = std::copy(__s, __f, __int._M_impl._M_start + 1);__s = __int._M_impl._M_start + 1;for (_Tp __i(1); __s != __f; ++__s, __i += 1)__i == _Tp(0) ? assert(*__s == _Tp(0)) : void(*__s /= __i);return __int;}return {};}/*** @brief Integrate in given range.** @return Definite integral over [0, __a].*/_Tp integ(const _Tp& __a) const noexcept {_Tp __int(0);auto __s = vec::_M_impl._M_start, __f = vec::_M_impl._M_finish;for (_Tp __p(__a), __i(1); __s != __f; ++__s, __p *= __a, __i += 1)__int += *__s / __i * __p;return __int;}/*** @brief Integrate in given range.** @return Definite integral over [__a, __b].*/_Tp integ(const _Tp& __a, const _Tp& __b) const noexcept {_Tp __int(0);auto __s = vec::_M_impl._M_start, __f = vec::_M_impl._M_finish;for (_Tp __pa(__a), __pb(__b), __i(1); __s != __f;++__s, __pa *= __a, __pb *= __b, __i += 1)__int += *__s / __i * (__pb - __pa);return __int;}};/*** @brief Polynomial interpolation in O(n log(n)^2) time.** @param __first* @param __last* @return*/template <class _InputIter, typename = std::_RequireInputIter<_InputIter>>auto interpolate(_InputIter __first, _InputIter __last) {size_t __n = std::distance(__first, __last);auto [__1, __2] =typename std::iterator_traits<decltype(__first)>::value_type{};using poly = polynomial<decltype(__1)>;if (!__n) return poly{};struct node {poly __all, __lack;};auto __tree = new node[__n << 1];auto __iter = __first;for (size_t __i = 0; __i != __n; ++__i) {auto&& [__a, __b] = *__iter++;__tree[__i + __n].__all = {-__a, 1}, __tree[__i + __n].__lack = {1};}for (size_t __i = __n; --__i;)__tree[__i].__all = __tree[__i << 1].__all * __tree[__i << 1 | 1].__all,__tree[__i].__lack =__tree[__i << 1].__all * std::move(__tree[__i << 1 | 1].__lack) +__tree[__i << 1 | 1].__all * std::move(__tree[__i << 1].__lack);for (size_t __i = 2; __i != __n << 1; __i += 2)__tree[__i].__lack = __tree[__i >> 1].__lack % __tree[__i].__all,__tree[__i | 1].__lack =std::move(__tree[__i >> 1].__lack %= __tree[__i | 1].__all);for (size_t __i = 0; __i != __n; ++__i) {auto&& [__a, __b] = *__first++;__tree[__i + __n].__lack[0] =std::move(__b) / std::move(__tree[__i + __n].__lack[0]);}for (size_t __i = __n; --__i;)__tree[__i].__lack = std::move(__tree[__i << 1].__all) *std::move(__tree[__i << 1 | 1].__lack) +std::move(__tree[__i << 1 | 1].__all) *std::move(__tree[__i << 1].__lack);auto __result = std::move(__tree[1].__lack);delete[] __tree;return __result;}// /**// * @brief Rising factorial of degree n.// * @return \\prod_{i=0}^{n-1} (x+i)// */// template <class _Tp> auto rising_factorial(_Tp __n) {}// /**// * @brief \\prod_{i=0}^{n-1} (x+i).// */// template <class _Tp> auto rising_factorial(_Tp __n) {// return rising_factorial(__n, __n);// }// /**// * @brief \\prod_{i=0}^{n-1} (x-i) \\bmod x^d.// */// template <class _Tp> auto falling_factorial(_Tp __n, std::size_t __d) {// auto __f = rising_factorial(__n, __d);// for (std::size_t __i = (__n & 1) ^ 1; __i < __d; __i += 2)// __f[__i] = -__f[__i];// return __f;// }// /**// * @brief \\prod_{i=0}^{n-1} (x-i).// */// template <class _Tp> auto falling_factorial(_Tp __n) {// return falling_factorial(__n, __n);// }/*** @brief Generating function of the sum of k-th powers of the first n* non-negative integers. O(d \\log d) time in modulo x^d.** @return \\sum_{k=0}^{d-1} x^k \\sum_{i=0}^{n-1} i^k.*/template <class _Tp> polynomial<_Tp> power_sum(_Tp __n, std::size_t __d) {if (!__d) return {};polynomial<_Tp> __f(__d), __e(__d);__f[0] = __n;for (std::size_t __i = 1; __i != __d; ++__i) __f[__i] = __f[__i - 1] * __n;_Tp __c{1};for (std::size_t __i = 0; __i != __d; ++__i)__c /= __i + 1, __f[__i] *= __c, __e[__i] = __c;(__f *= __e.inv(__d)).resize(__d);__c = 1;for (std::size_t __i = 0; __i != __d; __c *= ++__i) __f[__i] *= __c;return __f;}} // namespace workspace#line 2 "Library\\src\\data_structure\\segment_tree\\basic.hpp"/*** @file basic.hpp* @brief Segment Tree*/#line 10 "Library\\src\\data_structure\\segment_tree\\basic.hpp"#if __cplusplus >= 201703L#include <optional>#endif#line 2 "Library\\src\\algebra\\system\\monoid.hpp"/** @file monoid.hpp* @brief Monoid*/#include <limits>namespace workspace {template <class T, class E = T> struct min_monoid {using value_type = T;static T min, max;T value;min_monoid() : value(max) {}min_monoid(const T &value) : value(value) {}operator T() const { return value; }min_monoid operator+(const min_monoid &rhs) const {return value < rhs.value ? *this : rhs;}min_monoid operator*(const E &rhs) const;};template <class T, class E>T min_monoid<T, E>::min = std::numeric_limits<T>::min() / 2;template <class T, class E>T min_monoid<T, E>::max = std::numeric_limits<T>::max() / 2;template <class T, class E = T> struct max_monoid : min_monoid<T, E> {using base = min_monoid<T, E>;using base::min_monoid;max_monoid() : base(base::min) {}max_monoid operator+(const max_monoid &rhs) const {return !(base::value < rhs.value) ? *this : rhs;}max_monoid operator*(const E &rhs) const;};} // namespace workspace#line 2 "Library\\src\\algebra\\system\\operation.hpp"/*** @file operation.hpp* @brief Operation Traits*/#line 9 "Library\\src\\algebra\\system\\operation.hpp"namespace workspace {// Unary `+`template <class _Tp>using require_unary_plus = std::enable_if_t<std::is_convertible<decltype(+std::declval<const _Tp &>()), _Tp>::value>;template <class _Tp, class = void> struct has_unary_plus : std::false_type {};template <class _Tp>struct has_unary_plus<_Tp, require_unary_plus<_Tp>> : std::true_type {};// Unary `-`template <class _Tp>using require_unary_minus = std::enable_if_t<std::is_convertible<decltype(-std::declval<const _Tp &>()), _Tp>::value>;template <class _Tp, class = void> struct has_unary_minus : std::false_type {};template <class _Tp>struct has_unary_minus<_Tp, require_unary_minus<_Tp>> : std::true_type {};// Binary `+`template <class _Tp1, class _Tp2 = _Tp1>using require_binary_plus =std::enable_if_t<std::is_convertible<decltype(std::declval<const _Tp1 &>() +std::declval<const _Tp2 &>()),_Tp1>::value>;template <class _Tp1, class _Tp2 = _Tp1, class = void>struct has_binary_plus : std::false_type {};template <class _Tp1, class _Tp2>struct has_binary_plus<_Tp1, _Tp2, require_binary_plus<_Tp1, _Tp2>>: std::true_type {};// Binary `-`template <class _Tp1, class _Tp2 = _Tp1>using require_binary_minus = std::__void_t<decltype(std::declval<const _Tp1 &>() - std::declval<const _Tp2 &>())>;template <class _Tp1, class _Tp2 = _Tp1, class = void>struct has_binary_minus : std::false_type {};template <class _Tp1, class _Tp2>struct has_binary_minus<_Tp1, _Tp2, require_binary_minus<_Tp1, _Tp2>>: std::true_type {};// Binary `*`template <class _Tp1, class _Tp2 = _Tp1>using require_binary_multiplies =std::enable_if_t<std::is_convertible<decltype(std::declval<const _Tp1 &>() *std::declval<const _Tp2 &>()),_Tp1>::value>;template <class _Tp1, class _Tp2 = _Tp1, class = void>struct has_binary_multiplies : std::false_type {};template <class _Tp1, class _Tp2>struct has_binary_multiplies<_Tp1, _Tp2, require_binary_multiplies<_Tp1, _Tp2>>: std::true_type {};// Binary `/`template <class _Tp1, class _Tp2 = _Tp1>using require_binary_divides =std::enable_if_t<std::is_convertible<decltype(std::declval<const _Tp1 &>() /std::declval<const _Tp2 &>()),_Tp1>::value>;template <class _Tp1, class _Tp2 = _Tp1, class = void>struct has_binary_divides : std::false_type {};template <class _Tp1, class _Tp2>struct has_binary_divides<_Tp1, _Tp2, require_binary_divides<_Tp1, _Tp2>>: std::true_type {};// Binary `%`template <class _Tp1, class _Tp2 = _Tp1>using require_binary_modulus =std::enable_if_t<std::is_convertible<decltype(std::declval<const _Tp1 &>() %std::declval<const _Tp2 &>()),_Tp1>::value>;template <class _Tp1, class _Tp2 = _Tp1, class = void>struct has_binary_modulus : std::false_type {};template <class _Tp1, class _Tp2>struct has_binary_modulus<_Tp1, _Tp2, require_binary_modulus<_Tp1, _Tp2>>: std::true_type {};} // namespace workspace#line 17 "Library\\src\\data_structure\\segment_tree\\basic.hpp"namespace workspace {/*** @tparam _Monoid `operator+`, `operator=`* @tparam Container_tmpl `operator[]`, `size_type`*/template <class _Monoid, class _Endomorphism = void,template <class...> class Container_tmpl = std::vector>class segment_tree {static_assert(has_binary_plus<_Monoid>::value,"\'_Monoid\' has no proper binary \'operator+\'.");constexpr static bool __support_lazy = !std::is_void<_Endomorphism>::value;#if __cplusplus < 201703Lstruct node_base {node_base() = default;node_base(_Monoid const &__x) : __v(__x) {}operator bool() const { return __f; }void operator=(_Monoid const &__x) {__v = __x;__f = true;}_Monoid &operator*() { return __v; }_Monoid const &operator*() const { return __v; }void reset() { __f = false; }private:_Monoid __v{};bool __f{true};};#elsestruct node_base : std::optional<_Monoid> {using std::optional<_Monoid>::operator=;node_base() : std::optional<_Monoid>(_Monoid{}) {}};#endifstruct node_lazy : node_base {using node_base::operator=;std::optional<_Endomorphism> __z;};using node =typename std::conditional<__support_lazy, node_lazy, node_base>::type;using container_type = Container_tmpl<node>;public:using size_type = typename container_type::size_type;using difference_type = typename container_type::difference_type;class iterator {segment_tree *__p;size_type __i;public:using difference_type = segment_tree::difference_type;using value_type = _Monoid;using reference = _Monoid &;using pointer = iterator;using iterator_category = std::random_access_iterator_tag;/*** @brief Construct a new iterator object**/iterator() = default;/*** @brief Construct a new iterator object** @param __p Pointer to a segment tree object* @param __i Index*/iterator(segment_tree *__p, size_type __i) : __p(__p), __i(__i) {}bool operator==(iterator const &rhs) const {return __p == rhs.__p && __i == rhs.__i;}bool operator!=(iterator const &rhs) const { return !operator==(rhs); }bool operator<(iterator const &rhs) const { return __i < rhs.__i; }bool operator>(iterator const &rhs) const { return __i > rhs.__i; }bool operator<=(iterator const &rhs) const { return __i <= rhs.__i; }bool operator>=(iterator const &rhs) const { return __i >= rhs.__i; }iterator &operator++() { return ++__i, *this; }iterator &operator--() { return --__i, *this; }difference_type operator-(iterator const &rhs) const {return __i - rhs.__i;}/*** @brief** @return reference*/reference operator*() const { return __p->operator[](__i); }};using value_type = typename iterator::value_type;using reference = typename iterator::reference;iterator begin() { return {this, 0}; }iterator end() { return {this, size_orig}; }auto rbegin() { return std::make_reverse_iterator(end()); }auto rend() { return std::make_reverse_iterator(begin()); }protected:size_type size_orig, height, size_ext;container_type data;node &pull(size_type __i) noexcept {if (!data[__i]) data[__i] = *pull(__i << 1) + *pull(__i << 1 | 1);return data[__i];}void push(size_type __i) {if (auto &__lz = data[__i].__z) {apply(data[__i << 1], *__lz);apply(data[__i << 1 | 1], *__lz);__lz.reset();}}void sync(size_type __i) {if (!data[__i])data[__i] = *pull(__i << 1) + *pull(__i << 1 | 1);else if (data[__i].__z) {apply(data[__i << 1], *data[__i].__z);apply(data[__i << 1 | 1], *data[__i].__z);data[__i].__z.reset();}}template <class _End = _Endomorphism>void apply(node &__nd, _End const &endo) {*__nd = *__nd * endo;__nd.__z = __nd.__z ? *__nd.__z * endo : endo;}// template <class _End = _Endomorphism>// void apply_top(size_t __i, _End const &endo) {// auto &__nd = pull(__i);// *__nd = *__nd * endo;// __nd.__z = __nd.__z ? *__nd.__z * endo : endo;// }template <class Pred>constexpr decltype(std::declval<Pred>()(_Monoid{})) pass_args(Pred pred, _Monoid const &_1, [[maybe_unused]] size_type _2) {return pred(_1);}template <class Pred>constexpr decltype(std::declval<Pred>()(_Monoid{}, size_type{})) pass_args(Pred pred, _Monoid const &_1, size_type _2) {return pred(_1, _2);}template <class Pred>size_type left_partition_subtree(size_type __i, _Monoid mono, size_type step,Pred pred) {assert(__i);while (__i < size_ext) {if constexpr (__support_lazy) push(__i);const _Monoid tmp = *pull((__i <<= 1) | 1) + mono;if (pass_args(pred, tmp, ((__i | 1) << --step) ^ size_ext))mono = tmp;else++__i;}return ++__i -= size_ext;}template <class Pred>size_type right_partition_subtree(size_type __i, _Monoid mono, size_type step,Pred pred) {assert(__i);while (__i < size_ext) {if constexpr (__support_lazy) push(__i);const _Monoid tmp = mono + *pull(__i <<= 1);if (pass_args(pred, tmp, ((__i | 1) << --step) ^ size_ext))++__i, mono = tmp;}return (__i -= size_ext) < size_orig ? __i : size_orig;}public:/*** @brief Construct a new segment tree object.** @param __n Number of elements.*/segment_tree(size_type __n = 0): size_orig{__n},height(__n > 1 ? 64 - __builtin_clzll(__n - 1) : 0),size_ext{size_type{1} << height} {if constexpr (std::is_constructible<container_type, size_t>::value)data = container_type(size_ext << 1);data[0].reset();}/*** @brief Construct a new segment tree object.** @param __n Number of elements.* @param __x*/segment_tree(size_type __n, const value_type &__x) : segment_tree(__n) {for (auto __i = begin(); __i != end(); ++__i) *__i = __x;}/*** @brief Construct a new segment tree object.** @param __n Number of elements.* @param __x*/template <class _Tp>segment_tree(size_type __n, _Tp &&__x) : segment_tree(__n) {for (auto __i = begin(); __i != end(); ++__i) *__i = __x;}/*** @brief Construct a new segment tree object.** @param __first* @param __last*/template <class _Iterator, typename = std::_RequireInputIter<_Iterator>>segment_tree(_Iterator __first, _Iterator __last): segment_tree(std::distance(__first, __last)) {for (auto __i = begin(); __first != __last; ++__i, ++__first)*__i = *__first;}/*** @brief Conversion to container_type.*/operator Container_tmpl<value_type>() const {Container_tmpl<value_type> __c(size());for (size_type __i = 0; __i != size(); ++__i)__c[__i] = *data[__i | size_ext];return __c;}/*** @return Number of elements.*/size_type size() const { return size_orig; }/*** @return Whether %segment_tree is empty.*/bool empty() const { return !size(); }/*** @brief Subscripting ( @c [] ) access.** @param __i Index of the element* @return Reference to the element.*/reference operator[](size_type __i) {assert(__i < size_orig);reference __ref = *data[__i |= size_ext];if constexpr (__support_lazy) {for (size_t __h{height}; __h; --__h) {push(__i >> __h);data[__i >> __h].reset();}} else {while (data[__i >>= 1]) data[__i].reset();}return __ref;}/*** @param first Left end, inclusive* @param last Right end, exclusive* @return Sum of elements in the interval.*/value_type fold(size_type first, size_type last) {assert(last <= size_orig);if (!(first < last)) return {};first += size_ext, last += size_ext;value_type left{}, right{};for (size_t l = first, r = last--; l != r; l >>= 1, r >>= 1) {if (l & 1) left = left + *pull(l++);if (r & 1) right = *pull(--r) + right;if constexpr (__support_lazy) {if (data[first >>= 1].__z) left = left * *data[first].__z;if (data[last >>= 1].__z) right = right * *data[last].__z;}}if constexpr (__support_lazy) {while (first >>= 1, last >>= 1) {if (data[first].__z) left = left * *data[first].__z;if (data[last].__z) right = right * *data[last].__z;}}// if (first >= last) return _Monoid{};// first += size_ext, last += size_ext - 1;// _Monoid left{}, right{};// for (size_t l = first, r = last + 1; last; l >>= 1, r >>= 1) {// if (l < r) {// if (l & 1) left = left + data[l++];// if (r & 1) right = data[--r] + right;// }// if (first >>= 1, last >>= 1) {// left = left * lazy[first];// right = right * lazy[last];// }// }// return left + right;return left + right;}/*** @return The whole sum.*/value_type fold() { return *pull(1); }template <class _End = _Endomorphism>void update(size_type first, size_type last, _End const &endo) {static_assert(__support_lazy);assert(last <= size_orig);if (!(first < last)) return;first += size_ext, last += size_ext;--last;for (auto i = height; i; --i) push(first >> i), push(last >> i);++last;for (auto l = first, r = last; l < r; l >>= 1, r >>= 1) {if (l & 1) apply(pull(l++), endo);if (r & 1) apply(pull(--r), endo);}for (first >>= __builtin_ffs(first); data[first]; first >>= 1)data[first].reset();for (last >>= __builtin_ffs(last); data[last]; last >>= 1)data[last].reset();}/*** @brief Binary search for the partition point.* @param right Right fixed end of the interval, exclusive* @param pred Predicate in the form of either 'bool(_Monoid)' or* 'bool(_Monoid, size_type)'* @return Left end of the extremal interval satisfying the condition,* inclusive.*/template <class Pred> size_type left_partition(size_type right, Pred pred) {assert(right <= size_orig);right += size_ext;if constexpr (__support_lazy)for (size_t i{height}; i; --i) push(right >> i);_Monoid mono{};for (size_type left{size_ext}, step{}; left != right;left >>= 1, right >>= 1, ++step) {if ((left & 1) != (right & 1)) {_Monoid tmp = *pull(--right) + mono;if (!pass_args(pred, tmp, (right << step) ^ size_ext))return left_partition_subtree(right, mono, step, pred);mono = tmp;}}return 0;}/*** @brief Binary search for the partition point.* @param left Left fixed end of the interval, inclusive* @param pred Predicate in the form of either 'bool(_Monoid)' or* 'bool(_Monoid, size_type)'* @return Right end of the extremal interval satisfying the condition,* exclusive.*/template <class Pred> size_type right_partition(size_type left, Pred pred) {assert(left <= size_orig);left += size_ext;if constexpr (__support_lazy)for (size_t i{height}; i; --i) push(left >> i);_Monoid mono{};for (size_type right{size_ext << 1}, step{}; left != right;left >>= 1, right >>= 1, ++step) {if ((left & 1) != (right & 1)) {_Monoid tmp = mono + *pull(left);if (!pass_args(pred, tmp, ((left + 1) << step) ^ size_ext))return right_partition_subtree(left, mono, step, pred);mono = tmp;++left;}}return size_orig;}};template <class _Iterator, typename = std::_RequireInputIter<_Iterator>>segment_tree(_Iterator, _Iterator)-> segment_tree<typename std::iterator_traits<_Iterator>::value_type>;template <class _Tp, typename = require_binary_plus<_Tp>>segment_tree(typename segment_tree<_Tp>::size_type, _Tp &&)-> segment_tree<_Tp>;} // namespace workspace#line 2 "Library\\src\\modular\\modint.hpp"/*** @file modint.hpp** @brief Modular Arithmetic*/#line 10 "Library\\src\\modular\\modint.hpp"#include <iostream>#line 12 "Library\\src\\modular\\modint.hpp"#line 2 "Library\\src\\number_theory\\sqrt_mod.hpp"/*** @file sqrt_mod.hpp* @brief Tonelli-Shanks Algorithm*/#line 2 "Library\\src\\number_theory\\pow_mod.hpp"/*** @file mod_pow.hpp* @brief Modular Exponentiation*/#line 9 "Library\\src\\number_theory\\pow_mod.hpp"#line 11 "Library\\src\\number_theory\\pow_mod.hpp"namespace workspace {/*** @brief Compile time modular exponentiation.** @param __x* @param __n Exponent* @param __mod Modulus* @return*/template <class _Tp>constexpr std::enable_if_t<(is_integral_ext<_Tp>::value), _Tp> pow_mod(_Tp __x, _Tp __n, _Tp __mod) noexcept {assert(__mod > 0);using mul_type = typename multiplicable_uint<_Tp>::type;if ((__x %= __mod) < 0) __x += __mod;mul_type __y{1};while (__n) {if (__n & 1) (__y *= __x) %= __mod;__x = (mul_type)__x * __x % __mod;__n >>= 1;}return __y;};} // namespace workspace#line 10 "Library\\src\\number_theory\\sqrt_mod.hpp"namespace workspace {/*** @brief Compile time modular square root.** @param __x* @param __mod Modulus* @return One if it exists. Otherwise -1.*/template <class _Tp>constexpr std::enable_if_t<(is_integral_ext<_Tp>::value), _Tp> sqrt_mod(_Tp __x, _Tp __mod) noexcept {assert(__mod > 0);using mul_type = typename multiplicable_uint<_Tp>::type;if ((__x %= __mod) < 0) __x += __mod;if (!__x) return 0;if (__mod == 2) return __x;if (pow_mod(__x, __mod >> 1, __mod) != 1) return -1;_Tp __z = __builtin_ctz(__mod - 1), __q = __mod >> __z;mul_type __a = pow_mod(__x, (__q + 1) >> 1, __mod), __b = 2;while (pow_mod<_Tp>(__b, __mod >> 1, __mod) == 1) ++__b;__b = pow_mod<_Tp>(__b, __q, __mod);_Tp __shift = 0;for (auto __r = __a * __a % __mod * pow_mod(__x, __mod - 2, __mod) % __mod;__r != 1; (__r *= (__b *= __b) %= __mod) %= __mod) {auto __bsf = __z;for (auto __e = __r; __e != 1; --__bsf) (__e *= __e) %= __mod;while (++__shift != __bsf) (__b *= __b) %= __mod;(__a *= __b) %= __mod;}return __a;};} // namespace workspace#line 15 "Library\\src\\modular\\modint.hpp"namespace workspace {namespace _modint_impl {template <auto _Mod, unsigned _Storage> struct modint {static_assert(is_integral_ext<decltype(_Mod)>::value,"_Mod must be integral type.");using mod_type = std::make_signed_t<typename std::conditional<0 < _Mod, std::add_const_t<decltype(_Mod)>, decltype(_Mod)>::type>;using value_type = std::decay_t<mod_type>;using mul_type = typename multiplicable_uint<value_type>::type;// Modulusstatic mod_type mod;static unsigned storage;private:value_type value = 0;struct direct_ctor_t {};constexpr static direct_ctor_t direct_ctor_tag{};// Direct constructortemplate <class _Tp>constexpr modint(_Tp __n, direct_ctor_t) noexcept : value(__n) {}public:constexpr modint() noexcept = default;template <class _Tp, typename = std::enable_if_t<is_integral_ext<_Tp>::value>>constexpr modint(_Tp __n) noexcept: value((__n %= mod) < 0 ? __n += mod : __n) {}constexpr modint(bool __n) noexcept : value(__n) {}constexpr operator value_type() const noexcept { return value; }// unary operators {{constexpr modint operator++(int) noexcept {modint __t{*this};operator++();return __t;}constexpr modint operator--(int) noexcept {modint __t{*this};operator--();return __t;}constexpr modint &operator++() noexcept {if (++value == mod) value = 0;return *this;}constexpr modint &operator--() noexcept {if (!value)value = mod - 1;else--value;return *this;}constexpr modint operator+() const noexcept { return *this; }constexpr modint operator-() const noexcept {return {value ? mod - value : 0, direct_ctor_tag};}// }} unary operators// operator+= {{constexpr modint &operator+=(const modint &__x) noexcept {if ((value += __x.value) >= mod) value -= mod;return *this;}template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> &operator+=(_Tp const &__x) noexcept {if (((value += __x) %= mod) < 0) value += mod;return *this;}// }} operator+=// operator+ {{template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> operator+(_Tp const &__x) const noexcept {return modint{*this} += __x;}constexpr modint operator+(modint __x) const noexcept { return __x += *this; }template <class _Tp>constexpr friend std::enable_if_t<is_integral_ext<_Tp>::value, modint>operator+(_Tp const &__x, modint __y) noexcept {return __y += __x;}// }} operator+// operator-= {{constexpr modint &operator-=(const modint &__x) noexcept {if ((value -= __x.value) < 0) value += mod;return *this;}template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> &operator-=(_Tp __x) noexcept {if (((value -= __x) %= mod) < 0) value += mod;return *this;}// }} operator-=// operator- {{template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> operator-(_Tp const &__x) const noexcept {return modint{*this} -= __x;}constexpr modint operator-(const modint &__x) const noexcept {return modint{*this} -= __x;}template <class _Tp>constexpr friend std::enable_if_t<is_integral_ext<_Tp>::value, modint>operator-(_Tp __x, const modint &__y) noexcept {if (((__x -= __y.value) %= mod) < 0) __x += mod;return {__x, direct_ctor_tag};}// }} operator-// operator*= {{constexpr modint &operator*=(const modint &__x) noexcept {value =static_cast<value_type>(value * static_cast<mul_type>(__x.value) % mod);return *this;}template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> &operator*=(_Tp __x) noexcept {value = static_cast<value_type>(value * mul_type((__x %= mod) < 0 ? __x + mod : __x) % mod);return *this;}// }} operator*=// operator* {{constexpr modint operator*(const modint &__x) const noexcept {return {static_cast<mul_type>(value) * __x.value % mod, direct_ctor_tag};}template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> operator*(_Tp __x) const noexcept {__x %= mod;if (__x < 0) __x += mod;return {static_cast<mul_type>(value) * __x % mod, direct_ctor_tag};}template <class _Tp>constexpr friend std::enable_if_t<is_integral_ext<_Tp>::value, modint>operator*(_Tp __x, const modint &__y) noexcept {__x %= mod;if (__x < 0) __x += mod;return {static_cast<mul_type>(__x) * __y.value % mod, direct_ctor_tag};}// }} operator*protected:static value_type _mem(value_type __x) {static std::vector<value_type> __m{0, 1};static value_type __i = (__m.reserve(storage), 1);while (__i < __x) {++__i;__m.emplace_back(mod - mul_type(mod / __i) * __m[mod % __i] % mod);}return __m[__x];}static value_type _div(mul_type __r, value_type __x) noexcept {assert(__x != value_type(0));if (!__r) return 0;std::make_signed_t<value_type> __v{};bool __neg = __x < 0 ? __x = -__x, true : false;if (static_cast<decltype(storage)>(__x) < storage)__v = _mem(__x);else {value_type __y{mod}, __u{1}, __t;while (__x)__t = __y / __x, __y ^= __x ^= (__y -= __t * __x) ^= __x,__v ^= __u ^= (__v -= __t * __u) ^= __u;if (__y < 0) __neg ^= 1;}if (__neg)__v = 0 < __v ? mod - __v : -__v;else if (__v < 0)__v += mod;return __r == mul_type(1) ? static_cast<value_type>(__v): static_cast<value_type>(__r * __v % mod);}public:// operator/= {{constexpr modint &operator/=(const modint &__x) noexcept {if (value) value = _div(value, __x.value);return *this;}template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> &operator/=(_Tp __x) noexcept {if (value) value = _div(value, __x %= mod);return *this;}// }} operator/=// operator/ {{constexpr modint operator/(const modint &__x) const noexcept {if (!value) return {};return {_div(value, __x.value), direct_ctor_tag};}template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> operator/(_Tp __x) const noexcept {if (!value) return {};return {_div(value, __x %= mod), direct_ctor_tag};}template <class _Tp>constexpr friend std::enable_if_t<is_integral_ext<_Tp>::value, modint>operator/(_Tp __x, const modint &__y) noexcept {if (!__x) return {};if ((__x %= mod) < 0) __x += mod;return {_div(__x, __y.value), direct_ctor_tag};}// }} operator/constexpr modint inv() const noexcept { return _div(1, value); }template <class _Tp>constexpr std::enable_if_t<is_integral_ext<_Tp>::value, modint> pow(_Tp __e) const noexcept {modint __r{1, direct_ctor_tag};for (modint __b{__e < 0 ? __e = -__e, _div(1, value) : value,direct_ctor_tag};__e; __e >>= 1, __b *= __b)if (__e & 1) __r *= __b;return __r;}template <class _Tp>constexpr friend std::enable_if_t<is_integral_ext<_Tp>::value, modint> pow(modint __b, _Tp __e) noexcept {if (__e < 0) {__e = -__e;__b.value = _div(1, __b.value);}modint __r{1, direct_ctor_tag};for (; __e; __e >>= 1, __b *= __b)if (__e & 1) __r *= __b;return __r;}constexpr modint sqrt() const noexcept {return {sqrt_mod(value, mod), direct_ctor_tag};}friend constexpr modint sqrt(const modint &__x) noexcept {return {sqrt_mod(__x.value, mod), direct_ctor_tag};}template <class _Os>friend _Os &operator<<(_Os &__os, const modint &__x) noexcept {return __os << __x.value;}friend std::istream &operator>>(std::istream &__is, modint &__x) noexcept {std::string __s;__is >> __s;bool __neg = false;if (__s.front() == '-') {__neg = true;__s.erase(__s.begin());}__x = 0;for (char __c : __s) __x = __x * 10 + (__c - '0');if (__neg) __x = -__x;return __is;}};template <auto _Mod, unsigned _Storage>typename modint<_Mod, _Storage>::mod_type modint<_Mod, _Storage>::mod =_Mod > 0 ? _Mod : 0;template <auto _Mod, unsigned _Storage>unsigned modint<_Mod, _Storage>::storage = _Storage;} // namespace _modint_impltemplate <auto _Mod, unsigned _Storage = 0,typename = std::enable_if_t<(_Mod > 0)>>using modint = _modint_impl::modint<_Mod, _Storage>;template <unsigned _Id = 0>using modint_runtime = _modint_impl::modint<-(signed)_Id, 0>;} // namespace workspace#line 4 "other-workspace\\y2.cc"// #include "src/utils/py-like/enumerate.hpp"// #include "src/utils/py-like/range.hpp"namespace workspace {using mint = modint<998244353>;using poly = polynomial<mint>;constexpr auto max_value = 3000;struct mono {poly v{1};mono operator+(mono x) const {auto t = v;t *= x.v;t.resize(max_value + 1);return {t};}};using namespace std;using i64 = int_least64_t;void main() {// start here!i64 N;int Q;cin >> N >> Q;vector<tuple<int, int, int>> updates;vector<pair<int, int>> queries;vector<i64> id;for (int i = 0; i < Q; ++i) {i64 k;int a, b, s, t;cin >> k >> a >> b >> s >> t;if (auto f = find(begin(id), end(id), k); f != id.end()) {k = f - id.begin();} else {id.emplace_back(k);k = id.size() - 1;}updates.emplace_back(k, a, b);queries.emplace_back(s, t);}poly f(max_value + 1);{mint c = 1;for (int i = 0; i <= max_value; ++i) {f[i] = c;c *= N - id.size() + i;c /= i + 1;}}segment_tree<mono> sgt(id.size(), {poly(max_value + 1, 1)});for (int i = 0; i < Q; ++i) {auto [k, a, b] = updates[i];{auto &v = sgt[k].v;for (int i = a; i <= b; ++i) {v[i] = 0;}}auto [s, t] = queries[i];auto v = sgt.fold().v * f;mint ans;for (int i = s; i <= t; ++i) {ans += v[i];}cout << ans << "\n";}}} // namespace workspaceint main() { workspace::main(); }