#ifdef LOCAL #include "my_header.h" #else #define PRAGMA_OPTIMIZE(s) _Pragma(#s) PRAGMA_OPTIMIZE(GCC optimize("Ofast")) PRAGMA_OPTIMIZE(GCC optimize("unroll-loops")) // ループ #pragma GCC optimize("fast-math", "no-stack-protector") // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")//浮動小数点 // #pragma GCC target ("avx,avx2,fma")//四則演算 #include #include #include #include using namespace std; #if __has_include() #include using namespace atcoder; using minta = modint998244353; using mintb = modint1000000007; std::ostream&operator<<(std::ostream& os,minta v){os << v.val();return os;} std::istream&operator>>(std::istream&is,minta &v){long long t;is >> t;v=t;return is;} std::ostream&operator<<(std::ostream& os,mintb v){os << v.val();return os;} std::istream&operator>>(std::istream&is,mintb &v){long long t;is >> t;v=t;return is;} istream &operator>>(istream &is, __int128_t &x) { string S; is >> S; x = 0; int flag = 0; for (auto &c : S) { if (c == '-') { flag = true; continue; } x *= 10; x += c - '0'; } if (flag) x = -x; return is; } ostream &operator<<(ostream &os, __int128_t x) { if (x == 0) return os << 0; if (x < 0) os << '-', x = -x; string S; while (x) S.push_back('0' + x % 10), x /= 10; reverse(begin(S), end(S)); return os << S; } templateostream&operator<<(ostream&os,pair v){os << '(' << v.first << ',' << v.second << ')';return os;} templateistream&operator>>(istream&is,pair &v){is >> v.first >> v.second;return is;} templateistream&operator>>(istream&is,vector&v){for(T&in:v)is>>in;return is;} templateostream&operator<<(ostream&os,vectorv){for(int i=0;i struct ob2 { T1 a; T2 b; ob2() : a(), b() {} ob2(T1 a, T2 b) : a(a), b(b) {} friend auto operator<=>(const ob2&, const ob2&) = default; ob2 operator+(const ob2& o) const { return {a + o.a, b + o.b}; } ob2 operator-(const ob2& o) const { return {a - o.a, b - o.b}; } friend std::ostream& operator<<(std::ostream& os, const ob2& p) { return os << "(" << p.a << ", " << p.b << ")"; } friend std::istream& operator>>(std::istream& is, ob2& p) { return is >> p.a >> p.b; } }; template struct ob3 { T1 a; T2 b; T3 c; ob3() : a(), b(), c() {} ob3(T1 a, T2 b, T3 c) : a(a), b(b), c(c) {} friend auto operator<=>(const ob3&, const ob3&) = default; ob3 operator+(const ob3& o) const { return {a + o.a, b + o.b, c + o.c}; } ob3 operator-(const ob3& o) const { return {a - o.a, b - o.b, c - o.c}; } friend std::ostream& operator<<(std::ostream& os, const ob3& p) { return os << "(" << p.a << ", " << p.b << ", " << p.c << ")"; } friend std::istream& operator>>(std::istream& is, ob3& p) { return is >> p.a >> p.b >> p.c; } }; template struct ob4 { T1 a; T2 b; T3 c; T4 d; ob4() : a(), b(), c(), d() {} ob4(T1 a, T2 b, T3 c, T4 d) : a(a), b(b), c(c), d(d) {} friend auto operator<=>(const ob4&, const ob4&) = default; ob4 operator+(const ob4& o) const { return {a + o.a, b + o.b, c + o.c, d + o.d}; } ob4 operator-(const ob4& o) const { return {a - o.a, b - o.b, c - o.c, d - o.d}; } friend std::ostream& operator<<(std::ostream& os, const ob4& p) { return os << "(" << p.a << ", " << p.b << ", " << p.c << ", " << p.d << ")"; } friend std::istream& operator>>(std::istream& is, ob4& p) { return is >> p.a >> p.b >> p.c >> p.d; } }; template struct ob5 { T1 a; T2 b; T3 c; T4 d; T5 e; ob5() : a(), b(), c(), d(), e() {} ob5(T1 a, T2 b, T3 c, T4 d, T5 e) : a(a), b(b), c(c), d(d), e(e) {} friend auto operator<=>(const ob5&, const ob5&) = default; ob5 operator+(const ob5& o) const { return {a + o.a, b + o.b, c + o.c, d + o.d, e + o.e}; } ob5 operator-(const ob5& o) const { return {a - o.a, b - o.b, c - o.c, d - o.d, e - o.e}; } friend std::ostream& operator<<(std::ostream& os, const ob5& p) { return os << "(" << p.a << ", " << p.b << ", " << p.c << ", " << p.d << ", " << p.e << ")"; } friend std::istream& operator>>(std::istream& is, ob5& p) { return is >> p.a >> p.b >> p.c >> p.d >> p.e; } }; template struct ob6 { T1 a; T2 b; T3 c; T4 d; T5 e; T6 f; ob6() : a(), b(), c(), d(), e(), f() {} ob6(T1 a, T2 b, T3 c, T4 d, T5 e, T6 f) : a(a), b(b), c(c), d(d), e(e), f(f) {} friend auto operator<=>(const ob6&, const ob6&) = default; ob6 operator+(const ob6& o) const { return {a + o.a, b + o.b, c + o.c, d + o.d, e + o.e, f + o.f}; } ob6 operator-(const ob6& o) const { return {a - o.a, b - o.b, c - o.c, d - o.d, e - o.e, f - o.f}; } friend std::ostream& operator<<(std::ostream& os, const ob6& p) { return os << "(" << p.a << ", " << p.b << ", " << p.c << ", " << p.d << ", " << p.e << ", " << p.f << ")"; } friend std::istream& operator>>(std::istream& is, ob6& p) { return is >> p.a >> p.b >> p.c >> p.d >> p.e >> p.f; } }; using ll = long long; using ll2 = ob2; using ll3 = ob3; using ll4 = ob4; using ll5 = ob5; using ll6 = ob6; template struct is_ob : std::false_type {}; template struct is_ob> : std::true_type {}; template struct is_ob> : std::true_type {}; template struct is_ob> : std::true_type {}; template struct is_ob> : std::true_type {}; template struct is_ob> : std::true_type {}; struct FastIO { char *p; char out_buf[1 << 21]; int out_pos = 0; std::vector fallback_buf; template struct is_pair : std::false_type {}; template struct is_pair> : std::true_type {}; FastIO() { struct stat st; if (isatty(0)) { p = nullptr; return; } if (fstat(0, &st) == 0 && st.st_size > 0) { void *res = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, 0, 0); if (res != MAP_FAILED) { p = (char*)res; return; } } setup_fallback(); } void setup_fallback() { char buf[4096]; while (true) { ssize_t len = read(0, buf, sizeof(buf)); if (len <= 0) break; fallback_buf.insert(fallback_buf.end(), buf, buf + len); } if (!fallback_buf.empty()) { fallback_buf.push_back('\0'); p = fallback_buf.data(); } else p = nullptr; } ~FastIO() { flush(); } void flush() { if (out_pos > 0) { write(1, out_buf, out_pos); out_pos = 0; } } void write_char(char c) { out_buf[out_pos++] = c; if (out_pos >= (1<<20)) flush(); } // ---------- 入力 ---------- template void read_recursive(T &x) { if (!p) { cin >> x; return; } if constexpr (is_same_v) { long long t; read_recursive(t); x = (t != 0); } else if constexpr ( #if HAS_ACL is_same_v || is_same_v #else false #endif ) { long long t; read_recursive(t); x = t; } else if constexpr (is_same_v) { x = 0; bool neg = false; while (p && *p && (*p < '0' || *p > '9') && *p != '-') p++; if (!p || !*p) return; if (*p == '-') { neg = true; p++; } while (*p >= '0' && *p <= '9') x = x * (__int128_t)10 + (*p++ - '0'); if (neg) x = -x; } else if constexpr (is_same_v) { x = 0; while (p && *p && (*p < '0' || *p > '9')) p++; if (!p || !*p) return; while (*p >= '0' && *p <= '9') x = x * (uint64_t)10 + (uint64_t)(*p++ - '0'); } else if constexpr (is_same_v) { while (p && *p && *p <= ' ') p++; if (p && *p) x = *p++; } else if constexpr (is_integral_v) { x = 0; bool neg = false; while (p && *p && (*p < '0' || *p > '9') && *p != '-') p++; if (!p || !*p) return; if (*p == '-') { neg = true; p++; } while (*p >= '0' && *p <= '9') x = x * 10LL + (*p++ - '0'); if (neg) x = -x; } else if constexpr (is_floating_point_v) { while (p && *p && *p <= ' ') p++; if (!p || !*p) return; char *end; x = (T)strtod(p, &end); p = end; } else if constexpr (is_same_v) { x.clear(); while (p && *p && *p <= ' ') p++; if (!p || !*p) return; while (p && *p && *p > ' ') x += *p++; } else if constexpr (is_pair::value) { read_recursive(x.first); read_recursive(x.second); } else if constexpr (is_same_v>) { // string と同様に空白区切りで1トークン読む x.clear(); while (p && *p && *p <= ' ') p++; if (!p || !*p) return; while (p && *p && *p > ' ') x.push_back(*p++); } else if constexpr (is_same_v>) { for (int i = 0; i < (int)x.size(); i++) { int t; read_recursive(t); x[i] = (bool)t; } } else if constexpr (is_ob::value) { if constexpr (requires { x.a; }) read_recursive(x.a); if constexpr (requires { x.b; }) read_recursive(x.b); if constexpr (requires { x.c; }) read_recursive(x.c); if constexpr (requires { x.d; }) read_recursive(x.d); if constexpr (requires { x.e; }) read_recursive(x.e); if constexpr (requires { x.f; }) read_recursive(x.f); } else { for (auto &it : x) read_recursive(it); } } // ---------- 出力 ---------- void write_int64(long long n) { if (n == 0) { write_char('0'); return; } if (n < 0) { write_char('-'); n = -n; } char tmp[20]; int t = 0; while (n > 0) { tmp[t++] = (char)((n % 10) + '0'); n /= 10; } for (int i = t-1; i >= 0; i--) write_char(tmp[i]); } void write_uint64(uint64_t n) { if (n == 0) { write_char('0'); return; } char tmp[20]; int t = 0; while (n > 0) { tmp[t++] = (char)((n % 10) + '0'); n /= 10; } for (int i = t-1; i >= 0; i--) write_char(tmp[i]); } void write_int128(__int128_t n) { if (n == 0) { write_char('0'); return; } if (n < 0) { write_char('-'); n = -n; } char tmp[40]; int t = 0; while (n > 0) { tmp[t++] = (char)((n % 10) + '0'); n /= 10; } for (int i = t-1; i >= 0; i--) write_char(tmp[i]); } void write_double(double x) { if (std::isnan(x)) { write_char('0'); return; } if (std::isinf(x)) { if (x < 0) write_char('-'); write_char('i'); write_char('n'); write_char('f'); return; } if (x < 0) { write_char('-'); x = -x; } if (x >= 9.2e18) { write_uint64((uint64_t)x); write_char('.'); for (int i = 0; i < 15; i++) write_char('0'); return; } double offset = 0.5; for (int i = 0; i < 15; i++) offset /= 10.0; x += offset; long long int_part = (long long)x; write_int64(int_part); write_char('.'); double fraction = x - (double)int_part; for (int i = 0; i < 15; i++) { fraction *= 10; int d = (int)fraction; write_char('0' + d); fraction -= d; } } // const char* と char[] 用(セパレータなしで文字列として出力) void write_recursive(const char *x) { while (*x) write_char(*x++); } template void write_recursive(const char (&x)[N]) { for (size_t i = 0; i+1 < N && x[i]; i++) write_char(x[i]); } template void write_recursive(const T &x) { if constexpr (is_same_v) { if (x) { write_char('Y'); write_char('e'); write_char('s'); } else { write_char('N'); write_char('o'); } } else if constexpr ( #if HAS_ACL is_same_v || is_same_v #else false #endif ) { write_int64((long long)x.val()); } else if constexpr (is_same_v) { write_int128(x); } else if constexpr (is_same_v) { write_uint64(x); } else if constexpr (is_same_v) { write_char(x); } else if constexpr (is_floating_point_v) { write_double((double)x); } else if constexpr (is_integral_v) { write_int64((long long)x); } else if constexpr (is_same_v || is_same_v>) { // vector も string と同様セパレータなしで出力 for (char c : x) write_char(c); } else if constexpr (is_pair::value) { write_char('('); write_recursive(x.first); write_char(','); write_char(' '); write_recursive(x.second); write_char(')'); } else if constexpr (is_ob::value) { write_char('('); if constexpr (requires { x.a; }) { write_recursive(x.a); } if constexpr (requires { x.b; }) { write_char(','); write_char(' '); write_recursive(x.b); } if constexpr (requires { x.c; }) { write_char(','); write_char(' '); write_recursive(x.c); } if constexpr (requires { x.d; }) { write_char(','); write_char(' '); write_recursive(x.d); } if constexpr (requires { x.e; }) { write_char(','); write_char(' '); write_recursive(x.e); } if constexpr (requires { x.f; }) { write_char(','); write_char(' '); write_recursive(x.f); } write_char(')'); } else { for (int i = 0; i < (int)x.size(); i++) { write_recursive(x[i]); if (i+1 != (int)x.size()) write_char(' '); } } } } io; template void in(Args &...args) { (io.read_recursive(args), ...); } template void out(const Args &...args) { int n = sizeof...(Args), i = 0; ( (io.write_recursive(args), io.write_char(++i == n ? '\n' : ' ')), ... ); } namespace for_debugging{ struct subscript_and_location{ int sub; std::source_location loc; template subscript_and_location(T sub_,std::source_location loc_=std::source_location::current()){ if(!std::is_integral::value){ std::clog << loc_.file_name() << ":(" << loc_.line() << ":" << loc_.column() << "):" << loc_.function_name() << std::endl; std::clog << "subscript is not integer: subscript = " << sub_ << std::endl; exit(EXIT_FAILURE); } sub=sub_; loc=loc_; } void check_out_of_range(size_t sz){ if(sub<0||(int)sz<=sub){ std::clog << loc.file_name() << ":(" << loc.line() << ":" << loc.column() << "):" << loc.function_name() << std::endl; std::clog << "out of range: subscript = " << sub << ", vector_size = " << sz << std::endl; exit(EXIT_FAILURE); } } }; } namespace std{ template> class vector_for_debugging:public std::vector{ using std::vector::vector; public: [[nodiscard]] constexpr std::vector::reference operator[](for_debugging::subscript_and_location n) noexcept(!std::is_same::value){ n.check_out_of_range(this->size()); return std::vector::operator[](n.sub); } [[nodiscard]] constexpr std::vector::const_reference operator[](for_debugging::subscript_and_location n) const noexcept(!std::is_same::value){ n.check_out_of_range(this->size()); return std::vector::operator[](n.sub); } }; namespace pmr{ template using vector_for_debugging=std::vector_for_debugging>; } } #define vfd vector_for_debugging /*//多倍長整数 #include #include namespace mp = boost::multiprecision; // 任意長整数型 using Bint = mp::cpp_int; //仮数部が10進数で1024桁の浮動小数点数型(TLEしたら小さくする) using Real = mp::number>; */ #define rep(i,n) for(long long i=0;i<(long long)n;i++) #define reps(i,n) for(long long i=1;i<=(long long)n;i++) #define repi(i,n) for(int i=0;i<(int)n;i++) #define loop(i,l,r) for(long long i=(long long)l;i<=(long long)r;i++) #define loopi(i,l,r) for(int i=(int)l;i<=(int)r;i++) #define drep(i,n) for(long long i=(long long)n-1;i>=0;i--) #define drepi(i,n) for(int i=(int)n-1;i>=0;i--) #define dreps(i,n) for(int i=(int)n;i>=1;i--) #define dloop(i,l,r) for(long long i=(long long)l;i>=(long long)r;i--) #define dloopi(i,l,r) for(int i=(int)l;i>=(int)r;i--) #define all(v) v.begin(), v.end() #define rall(v) v.rbegin(), v.rend() #define yna(x) cout << (x? "Yes":"No") << endl; #define yn(x) out(bool(x)); #define cou(x) cout << x << endl; #define emp emplace_back #define mp make_pair const long long moda=998244353LL; const long long modb=1000000007LL; const int kaz=1000000005; long long yab=2500000000000000000LL; const long long aho =-yab; const long double eps=1.0e-14L; const long double pi=acosl(-1.0L); using st=string; using P=pair; using tup=tuple; using vi=vector; using vin=vector; using vc=vector; using vb=vector; using vd=vector; using vs=vector; using vp=vector

; using sp=set

; using si=set; using vvi=vector>; using vvin=vector; using vvc=vector; using vvb=vector; using vvvi=vector; using vvvin=vector; const int dx[4]={0,1,0,-1}; const int dy[4]={1,0,-1,0}; const vector ex = {-1, -1, -1, 0, 0, 1, 1, 1}; const vector ey = {-1, 0, 1, -1, 1, -1, 0, 1}; template void co(bool x,T1 y,T2 z){ if(x)cout << y << endl; else cout << z << endl; } long long isqrt(long long n){ long long ok=0,ng=1000000000;//1e9 while(ng-ok>1){ long long mid=(ng+ok)/2; if(mid*mid<=n)ok=mid; else ng=mid; } return ok; } template bool chmax(T &a, T b){ if(a T ceil(T x, U y) { return (x > 0 ? (x + y - 1) / y : x / y); } template T floor(T x, U y) { return (x > 0 ? x / y : (x - y + 1) / y); } template pair,T> unit(T x, T y,U k){ T s=floor(x-1,k); T t=floor(y,k); if(s==t)return make_pair(make_pair(0,0),-1); return make_pair(make_pair(s+1,t),1); } pair,int> jufuku(ll a,ll b,ll c,ll d){ //a<=b,c<=dが保証されているとする if(a>c){ swap(a,c); swap(b,d); } if(c>b)return make_pair(make_pair(0,0),-1); return make_pair(make_pair(c,min(b,d)),1); } template bool chmin(T &a, T b){ if(a>b){ a=b; return true; } return false; } template void her(vector &a){ for(auto &g:a)g--; } template void dec(vector &t,T k=1){ for(auto &i:t)i-=k; } template void inc(vector &t,T k=1){ for(auto &i:t)i+=k; } ll mypow(ll x,ll y,ll MOD){ if(MOD==-1){ MOD=9223372036854775807LL; } ll ret=1; while(y>0){ if(y&1)ret=ret*x%MOD; x=x*x%MOD; y>>=1; } return ret; } struct UnionFind { vector par,siz,mi,ma; UnionFind(int n) : par(n,-1), siz(n,1) {mi.resize(n);ma.resize(n);iota(mi.begin(),mi.end(),0);iota(ma.begin(),ma.end(),0); } int root(int x) { if(par[x]==-1)return x; else return par[x]=root(par[x]); } bool same(int x, int y) { return root(x)==root(y); } bool marge(int x, int y) { int rx = root(x), ry = root(y); if (rx==ry) return false; if(siz[rx] fac,finv,invs; // テーブルを作る前処理 void COMinit(int MAX,ll MOD) { nckmod=MOD; fac.resize(MAX); finv.resize(MAX); invs.resize(MAX); fac[0] = fac[1] = 1; finv[0] = finv[1] = 1; invs[1] = 1; for (int i = 2; i < MAX; i++){ fac[i] = fac[i - 1] * i % MOD; invs[i] = MOD - invs[MOD%i] * (MOD / i) % MOD; finv[i] = finv[i - 1] * invs[i] % MOD; } } // 二項係数計算 long long binom(int n, int k){ if (n < k) return 0; if (n < 0 || k < 0) return 0; return fac[n] * (finv[k] * finv[n - k] % nckmod) % nckmod; } template vector> assyuku(vector &v){ vector> ans; int sum=0; T pos=v[0]; int n=v.size(); for(int i=0;i vector> assyuku2(vector &v,F f){ vector> ans; int sum=0; bool pos=f(v[0]); int n=v.size(); for(int i=0;i