import macros macro Please(x): untyped = nnkStmtList.newTree() Please use Nim-ACL Please use Nim-ACL Please use Nim-ACL #[ include daylight/base ]# when not declared DAYLIGHT_BASE_HPP: const DAYLIGHT_BASE_HPP* = 1 import system import macros import algorithm import tables import sets import lists import intsets import critbits import sequtils import strutils import std/math import strformat import sugar let readToken* = iterator(oneChar: bool = false): string {.closure.}= while true: var line = stdin.readLine.split for s in line: if oneChar: for i in 0.. b: a = b return true return false proc chmax*[T](a: var T, b: T): bool {.discardable.} = if a < b: a = b return true return false const INF* = (1e9+100).int const LINF* = (4e18 + 100).int discard #[ import atcoder/dsu ]# when not declared ATCODER_DSU_HPP: const ATCODER_DSU_HPP* = 1 import std/sequtils type DSU* = ref object n: int par_or_siz: seq[int] proc initDSU*(n: int): DSU {.inline.} = return DSU(n: n, par_or_siz: newSeqWith(n, -1)) proc leader*(self: DSU; a: int): int {.inline.} = if self.par_or_siz[a] < 0: return a self.par_or_siz[a] = self.leader(self.par_or_siz[a]) return self.par_or_siz[a] proc same*(self: DSU; a, b: int): bool {.inline.} = self.leader(a) == self.leader(b) proc size*(self: DSU; a: int): int {.inline.} = - self.par_or_siz[self.leader(a)] proc merge*(self: DSU; a, b: int): int {.inline, discardable.} = var x = self.leader(a) y = self.leader(b) if x == y: return x if self.par_or_siz[x] > self.par_or_siz[y]: swap(x, y) self.par_or_siz[x] += self.par_or_siz[y] self.par_or_siz[y] = x return x proc groups*(self: DSU): seq[seq[int]] {.inline.} = var leaderBuf = newSeq[int](self.n) groupsize = newSeq[int](self.n) for i in 0 ..< self.n: leaderBuf[i] = self.leader(i) groupsize[leaderBuf[i]].inc result = (0 ..< self.n).mapIt(newSeqOfCap[int](groupsize[it])) for i, ldr in leaderBuf: result[ldr].add i result.keepItIf(it.len > 0) discard #[ import atcoder/modint ]# when not declared ATCODER_MODINT_HPP: const ATCODER_MODINT_HPP* = 1 import std/macros #[ import atcoder/generate_definitions ]# when not declared ATCODER_GENERATE_DEFINITIONS_NIM: const ATCODER_GENERATE_DEFINITIONS_NIM* = 1 import std/macros type hasInv* = concept x x.inv() template generateDefinitions*(name, l, r, typeObj, typeBase, body: untyped): untyped {.dirty.} = proc name*(l, r: typeObj): auto {.inline.} = type T = l.type body proc name*(l: typeBase; r: typeObj): auto {.inline.} = type T = r.type body proc name*(l: typeObj; r: typeBase): auto {.inline.} = type T = l.type body template generatePow*(name) {.dirty.} = proc pow*(m: name; p: SomeInteger): name {.inline.} = when name is hasInv: if p < 0: return pow(m.inv(), -p) else: doAssert p >= 0 if (p.type)(0) <= p: var p = p.uint m = m result = m.unit() while p > 0'u: if (p and 1'u) != 0'u: result *= m m *= m p = p shr 1'u proc `^`*[T:name](m: T; p: SomeInteger): T {.inline.} = m.pow(p) macro generateConverter*(name, from_type, to_type) = let fname = ident("to" & $`name` & "OfGenerateConverter") quote do: type `name`* = `to_type` converter `fname`*(a:`from_type`):`name` {.used.} = `name`.init(a) discard type StaticModInt*[M: static[int]] = object a:uint32 DynamicModInt*[T: static[int]] = object a:uint32 type ModInt* = StaticModInt or DynamicModInt proc isStaticModInt*(T:typedesc[ModInt]):bool = T is StaticModInt proc isDynamicModInt*(T:typedesc[ModInt]):bool = T is DynamicModInt proc isStatic*(T:typedesc[ModInt]):bool = T is StaticModInt #[ import atcoder/internal_math ]# when not declared ATCODER_INTERNAL_MATH_HPP: const ATCODER_INTERNAL_MATH_HPP* = 1 import std/math type Barrett* = object m*, im*:uint proc initBarrett*(m:uint):auto = Barrett(m:m, im:cast[uint](-1) div m + 1) proc umod*(self: Barrett):uint = self.m {.emit: """ inline unsigned long long calc_mul(const unsigned long long &a, const unsigned long long &b){ return (unsigned long long)(((unsigned __int128)(a)*b) >> 64); } """.} proc calc_mul*(a,b:culonglong):culonglong {.importcpp: "calc_mul(#,#)", nodecl, inline.} proc quo*(self: Barrett, n:int | uint):int = let n = n.uint let x = calc_mul(n.culonglong, self.im.culonglong).uint let r = n - x * self.m return int(if self.m <= r: x - 1 else: x) proc rem*(self: Barrett, n:int | uint):int = let n = n.uint let x = calc_mul(n.culonglong, self.im.culonglong).uint let r = n - x * self.m return int(if self.m <= r: r + self.m else: r) proc quorem*(self: Barrett, n:int | uint):(int, int) = let n = n.uint let x = calc_mul(n.culonglong, self.im.culonglong).uint let r = n - x * self.m return if self.m <= r: (int(x - 1), int(r + self.m)) else: (int(x), int(r)) proc pow*(self: Barrett, n:uint | int, p:int):int = var a = self.rem(n) r:uint = if self.m == 1: 0 else: 1 p = p while p > 0: if (p and 1) != 0: r = self.mul(r, a.uint) a = self.mul(a.uint, a.uint).int p = p shr 1 return int(r) proc mul*(self: Barrett, a:uint, b:uint):uint {.inline.} = let z = a * b return self.rem(z).uint proc pow_mod_constexpr*(x, n, m:int):int = if m == 1: return 0 var r = 1 y = floorMod(x, m) n = n while n != 0: if (n and 1) != 0: r = (r * y) mod m y = (y * y) mod m n = n shr 1 return r.int proc is_prime_constexpr*(n:int):bool = if n <= 1: return false if n == 2 or n == 7 or n == 61: return true if n mod 2 == 0: return false var d = n - 1 while d mod 2 == 0: d = d div 2 for a in [2, 7, 61]: var t = d y = pow_mod_constexpr(a, t, n) while t != n - 1 and y != 1 and y != n - 1: y = y * y mod n t = t shl 1 if y != n - 1 and t mod 2 == 0: return false return true proc is_prime*[n:static[int]]():bool = is_prime_constexpr(n) proc inv_gcd*(a, b:int):(int,int) = var a = floorMod(a, b) if a == 0: return (b, 0) var s = b t = a m0 = 0 m1 = 1 while t != 0: var u = s div t s -= t * u; m0 -= m1 * u; # |m1 * u| <= |m1| * s <= b var tmp = s s = t;t = tmp; tmp = m0;m0 = m1;m1 = tmp; if m0 < 0: m0 += b div s return (s, m0) proc primitive_root_constexpr*(m:int):int = if m == 2: return 1 if m == 167772161: return 3 if m == 469762049: return 3 if m == 754974721: return 11 if m == 998244353: return 3 var divs:array[20, int] divs[0] = 2 var cnt = 1 var x = (m - 1) div 2 while x mod 2 == 0: x = x div 2 var i = 3 while i * i <= x: if x mod i == 0: divs[cnt] = i cnt.inc while x mod i == 0: x = x div i i += 2 if x > 1: divs[cnt] = x cnt.inc var g = 2 while true: var ok = true for i in 0..= m: result += n * (n - 1) div 2 * (a div m) a = a mod m if b >= m: result += n * (b div m) b = b mod m let y_max = a * n + b if y_max < m: break n = y_max div m b = y_max mod m swap(m, a) discard proc getBarrett*[T:static[int]](t:typedesc[DynamicModInt[T]]):ptr Barrett = var Barrett_of_DynamicModInt {.global.} = initBarrett(998244353.uint) return Barrett_of_DynamicModInt.addr proc getMod*[T:static[int]](t:typedesc[DynamicModInt[T]]):uint32 {.inline.} = (t.getBarrett)[].m.uint32 proc setMod*[T:static[int]](t:typedesc[DynamicModInt[T]], M:SomeInteger){.inline.} = (t.getBarrett)[] = initBarrett(M.uint) proc val*(m: ModInt): int {.inline.} = int(m.a) proc `$`*(m: StaticModInt or DynamicModInt): string {.inline.} = $(m.val()) template umod*[T:ModInt](self: typedesc[T] or T):uint32 = when T is typedesc: when T is StaticModInt: T.M.uint32 elif T is DynamicModInt: T.getMod() else: static: assert false else: T.umod template `mod`*[T:ModInt](self:typedesc[T] or T):int = T.umod.int proc init*[T:ModInt](t:typedesc[T], v: SomeInteger or T): auto {.inline.} = when v is T: return v else: when v is SomeUnsignedInt: if v.uint < T.umod: return T(a:v.uint32) else: return T(a:(v.uint mod T.umod.uint).uint32) else: var v = v.int if 0 <= v: if v < T.mod: return T(a:v.uint32) else: return T(a:(v mod T.mod).uint32) else: v = v mod T.mod if v < 0: v += T.mod return T(a:v.uint32) proc unit*[T:ModInt](t:typedesc[T] or T):T = T.init(1) template initModInt*(v: SomeInteger or ModInt; M: static[int] = 1_000_000_007): auto = StaticModInt[M].init(v) proc raw*[T:ModInt](t:typedesc[T], v:SomeInteger):auto = T(a:v) proc inv*[T:ModInt](v:T):T {.inline.} = var a = v.a.int b = T.mod u = 1 v = 0 while b > 0: let t = a div b a -= t * b;swap(a, b) u -= t * v;swap(u, v) return T.init(u) proc `-`*[T:ModInt](m: T): T {.inline.} = if int(m.a) == 0: return m else: return T(a:m.umod() - m.a) proc `+=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} = m.a += T.init(n).a if m.a >= T.umod: m.a -= T.umod return m proc `-=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} = m.a -= T.init(n).a if m.a >= T.umod: m.a += T.umod return m proc `*=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} = when T is StaticModInt: m.a = (m.a.uint * T.init(n).a.uint mod T.umod).uint32 elif T is DynamicModInt: m.a = T.getBarrett[].mul(m.a.uint, T.init(n).a.uint).uint32 else: static: assert false return m proc `/=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} = m.a = (m.a.uint * T.init(n).inv().a.uint mod T.umod).uint32 return m generateDefinitions(`+`, m, n, ModInt, SomeInteger): result = T.init(m) result += n generateDefinitions(`-`, m, n, ModInt, SomeInteger): result = T.init(m) result -= n generateDefinitions(`*`, m, n, ModInt, SomeInteger): result = T.init(m) result *= n generateDefinitions(`/`, m, n, ModInt, SomeInteger): result = T.init(m) result /= n generateDefinitions(`==`, m, n, ModInt, SomeInteger): result = (T.init(m).val() == T.init(n).val()) proc inc*(m: var ModInt):ModInt {.inline discardable.} = m.a.inc if m.a == m.umod.uint32: m.a = 0 return m proc `++`*(m: var ModInt):ModInt {.inline discardable.} = m.inc proc dec*(m: var ModInt):ModInt {.inline discardable.} = if m.a == 0.uint32: m.a = m.umod - 1 else: m.a.dec return m proc `--`*(m: var ModInt):ModInt {.inline discardable.} = m.dec generatePow(ModInt) template useStaticModint*(name, M) = generateConverter(name, int, StaticModInt[M]) template useDynamicModInt*(name, M) = generateConverter(name, int, DynamicModInt[M]) useStaticModInt(modint998244353, 998244353) useStaticModInt(modint1000000007, 1000000007) useDynamicModInt(modint, -1) import std/math as math_lib_modint proc estimateRational*(a:ModInt, ub:int = int(sqrt(float(ModInt.mod))), output_stderr:static[bool] = false):string = var v:seq[tuple[s, n, d: int]] for d in 1 .. ub: var n = (a * d).val if n * 2 > a.mod: n = - (a.mod - n) if gcd(n, d) > 1: continue v.add((n.abs + d, n, d)) v.sort when output_stderr: stderr.write "estimation result: ", v return $v[0].n & "/" & $v[0].d discard type mint = modint998244353 proc solve() = var N = read(int) Q = read(int) dsu = initDSU(2 * N) dsu2 = initDSU(N) for i in 0..