import macros;macro ImportExpand(s:untyped):untyped = parseStmt($s[2]) # source: src/cplib/tmpl/sheep.nim ImportExpand "cplib/tmpl/sheep" <=== "when not declared CPLIB_TMPL_SHEEP:\n const CPLIB_TMPL_SHEEP* = 1\n {.warning[UnusedImport]: off.}\n {.hint[XDeclaredButNotUsed]: off.}\n import algorithm\n import sequtils\n import tables\n import macros\n import math\n import sets\n import strutils\n import strformat\n import sugar\n import heapqueue\n import streams\n import deques\n import bitops\n import std/lenientops\n import options\n #入力系\n proc scanf(formatstr: cstring){.header: \"\", varargs.}\n proc getchar(): char {.importc: \"getchar_unlocked\", header: \"\", discardable.}\n proc ii(): int {.inline.} = scanf(\"%lld\\n\", addr result)\n proc lii(N: int): seq[int] {.inline.} = newSeqWith(N, ii())\n proc si(): string {.inline.} =\n result = \"\"\n var c: char\n while true:\n c = getchar()\n if c == ' ' or c == '\\n' or c == '\\255':\n break\n result &= c\n \n # 出力系\n # 1. 実際の処理を行う proc (openArray を受け取る)\n proc print_internal(prop: tuple[f: File, sepc: string, endc: string, flush: bool], args: openArray[string]) =\n for i in 0 ..< args.len:\n prop.f.write(args[i])\n if i != args.len - 1:\n prop.f.write(prop.sepc)\n else:\n prop.f.write(prop.endc)\n if prop.flush:\n prop.f.flushFile()\n\n # 2. ユーザーが呼び出すためのインターフェース (varargs を受け取る)\n proc print*(prop: tuple[f: File, sepc: string, endc: string, flush: bool], args: varargs[string, `$`]) =\n # varargs は内部では openArray として扱えるので、そのまま渡せる\n print_internal(prop, args)\n\n proc print*(args: varargs[string, `$`]) =\n # こちらも内部用の proc を呼ぶ\n print_internal((f: stdout, sepc: \" \", endc: \"\\n\", flush: false), args)\n macro getSymbolName(x: typed): string = x.toStrLit\n macro debug*(args: varargs[untyped]): untyped =\n when defined(debug):\n result = newNimNode(nnkStmtList, args)\n template prop(e: string = \"\"): untyped = (f: stderr, sepc: \"\", endc: e, flush: true)\n for i, arg in args:\n if arg.kind == nnkStrLit:\n result.add(quote do: print(prop(), \"\\\"\", `arg`, \"\\\"\"))\n else:\n result.add(quote do: print(prop(\": \"), getSymbolName(`arg`)))\n result.add(quote do: print(prop(), `arg`))\n if i != args.len - 1: result.add(quote do: print(prop(), \", \"))\n else: result.add(quote do: print(prop(), \"\\n\"))\n else:\n return (quote do: discard)\n #chmin,chmax\n template `max=`(x, y) = x = max(x, y)\n template `min=`(x, y) = x = min(x, y)\n proc chmin[T](x: var T, y: T):bool=\n if x > y:\n x = y\n return true\n return false\n proc chmax[T](x: var T, y: T):bool=\n if x < y:\n x = y\n return true\n return false\n #bit演算\n proc `%`*(x: int, y: int): int =\n result = x mod y\n if y > 0 and result < 0: result += y\n if y < 0 and result > 0: result += y\n proc `//`*(x: int, y: int): int{.inline.} =\n result = x div y\n if y > 0 and result * y > x: result -= 1\n if y < 0 and result * y < x: result -= 1\n proc `%=`(x: var int, y: int): void = x = x%y\n proc `//=`(x: var int, y: int): void = x = x//y\n proc `**`(x: int, y: int): int = x^y\n proc `**=`(x: var int, y: int): void = x = x^y\n proc `^`(x: int, y: int): int = x xor y\n proc `|`(x: int, y: int): int = x or y\n proc `&`(x: int, y: int): int = x and y\n proc `>>`(x: int, y: int): int = x shr y\n proc `<<`(x: int, y: int): int = x shl y\n proc `~`(x: int): int = not x\n proc `^=`(x: var int, y: int): void = x = x ^ y\n proc `&=`(x: var int, y: int): void = x = x & y\n proc `|=`(x: var int, y: int): void = x = x | y\n proc `>>=`(x: var int, y: int): void = x = x >> y\n proc `<<=`(x: var int, y: int): void = x = x << y\n proc `[]`(x: int, n: int): bool = (x and (1 shl n)) != 0\n #便利な変換\n proc `!`(x: char, a = '0'): int = int(x)-int(a)\n #定数\n when not declared CPLIB_UTILS_CONSTANTS:\n const CPLIB_UTILS_CONSTANTS* = 1\n const INF32*: int32 = 1001000027.int32\n const INF64*: int = int(3300300300300300491)\n \n const INF = INF64\n #converter\n\n #range\n iterator range(start: int, ends: int, step: int): int =\n var i = start\n if step < 0:\n while i > ends:\n yield i\n i += step\n elif step > 0:\n while i < ends:\n yield i\n i += step\n iterator range(ends: int): int = (for i in 0.. r[i]:\n return false\n elif l[i] < r[i]:\n return true\n return len(l) < len(r)\n \n # Yes/No\n proc yes*(b: bool = true): void = print(if b: \"Yes\" else: \"No\")\n proc oo*(b: bool = true): void = yes(not b)\n\n proc takahashi(b:bool = true) : void = print(if b: \"Takahashi\" else: \"Aoki\")\n proc aoki(b:bool = true) : void = takahashi(not b)\n\n template dblock(body: untyped) =\n when defined(debug):\n body\n" # source: src/atcoder/modint.nim ImportExpand "atcoder/modint" <=== "when not declared ATCODER_MODINT_HPP:\n const ATCODER_MODINT_HPP* = 1\n import std/macros\n when not declared ATCODER_GENERATE_DEFINITIONS_NIM:\n const ATCODER_GENERATE_DEFINITIONS_NIM* = 1\n import std/macros\n \n type hasInv* = concept x\n x.inv()\n \n template generateDefinitions*(name, l, r, typeObj, typeBase, body: untyped): untyped {.dirty.} =\n proc name*(l, r: typeObj): auto {.inline.} =\n type T = l.type\n body\n proc name*(l: typeBase; r: typeObj): auto {.inline.} =\n type T = r.type\n body\n proc name*(l: typeObj; r: typeBase): auto {.inline.} =\n type T = l.type\n body\n \n template generatePow*(name) {.dirty.} =\n proc pow*(m: name; p: SomeInteger): name {.inline.} =\n when name is hasInv:\n if p < 0: return pow(m.inv(), -p)\n else:\n doAssert p >= 0\n if (p.type)(0) <= p:\n var\n p = p.uint\n m = m\n result = m.unit()\n while p > 0'u:\n if (p and 1'u) != 0'u: result *= m\n m *= m\n p = p shr 1'u\n proc `^`*[T:name](m: T; p: SomeInteger): T {.inline.} = m.pow(p)\n \n macro generateConverter*(name, from_type, to_type) =\n let fname = ident(\"to\" & $`name` & \"OfGenerateConverter\")\n quote do:\n type `name`* = `to_type`\n converter `fname`*(a:`from_type`):`name` {.used.} =\n `name`.init(a)\n \n\n type\n StaticModInt*[M: static[int]] = object\n a:uint32\n DynamicModInt*[T: static[int]] = object\n a:uint32\n\n type ModInt* = StaticModInt or DynamicModInt\n# type ModInt* = concept x, type T\n# T is StaticModInt or T is DynamicModInt\n\n proc isStaticModInt*(T:typedesc[ModInt]):bool = T is StaticModInt\n proc isDynamicModInt*(T:typedesc[ModInt]):bool = T is DynamicModInt\n #proc isModInt*(T:typedesc):bool = T.isStaticModInt or T.isDynamicModInt\n proc isStatic*(T:typedesc[ModInt]):bool = T is StaticModInt\n proc getMod*[M:static[int]](t:typedesc[StaticModInt[M]]):int {.inline.} = M\n\n\n when not declared ATCODER_INTERNAL_MATH_HPP:\n const ATCODER_INTERNAL_MATH_HPP* = 1\n import std/math\n \n # Fast moduler by barrett reduction\n # Reference: https:#en.wikipedia.org/wiki/Barrett_reduction\n # NOTE: reconsider after Ice Lake\n type Barrett* = object\n m*, im*:uint\n \n # @param m `1 <= m`\n proc initBarrett*(m:uint):auto = Barrett(m:m, im:cast[uint](-1) div m + 1)\n \n # @return m\n proc umod*(self: Barrett):uint =\n self.m\n \n {.emit: \"\"\"\n #include\n inline unsigned long long calc_mul(const unsigned long long &a, const unsigned long long &b){\n return (unsigned long long)(((unsigned __int128)(a)*b) >> 64);\n }\n \"\"\".}\n proc calc_mul*(a,b:culonglong):culonglong {.importcpp: \"calc_mul(#,#)\", nodecl, inline.}\n # @param a `0 <= a < m`\n # @param b `0 <= b < m`\n # @return `a * b % m`\n proc quo*(self: Barrett, n:int | uint):int =\n let n = n.uint\n let x = calc_mul(n.culonglong, self.im.culonglong).uint\n let r = n - x * self.m\n return int(if self.m <= r: x - 1 else: x)\n proc rem*(self: Barrett, n:int | uint):int =\n let n = n.uint\n let x = calc_mul(n.culonglong, self.im.culonglong).uint\n let r = n - x * self.m\n return int(if self.m <= r: r + self.m else: r)\n proc quorem*(self: Barrett, n:int | uint):(int, int) =\n let n = n.uint\n let x = calc_mul(n.culonglong, self.im.culonglong).uint\n let r = n - x * self.m\n return if self.m <= r: (int(x - 1), int(r + self.m)) else: (int(x), int(r))\n \n proc pow*(self: Barrett, n:uint | int, p:int):int =\n var\n a = self.rem(n)\n r:uint = if self.m == 1: 0 else: 1\n p = p\n while p > 0:\n if (p and 1) != 0: r = self.mul(r, a.uint)\n a = self.mul(a.uint, a.uint).int\n p = p shr 1\n return int(r)\n \n proc mul*(self: Barrett, a:uint, b:uint):uint {.inline.} =\n # [1] m = 1\n # a = b = im = 0, so okay\n \n # [2] m >= 2\n # im = ceil(2^64 / m)\n # -> im * m = 2^64 + r (0 <= r < m)\n # let z = a*b = c*m + d (0 <= c, d < m)\n # a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im\n # c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2\n # ((ab * im) >> 64) == c or c + 1\n let z = a * b\n # #ifdef _MSC_VER\n # unsigned long long x;\n # _umul128(z, im, &x);\n # #else\n # unsigned long long x =\n # (unsigned long long)(((unsigned __int128)(z)*im) >> 64);\n # #endif\n #let x = calc_mul(z.culonglong, self.im.culonglong).uint\n #result = z - x * self.m\n #if self.m <= result: result += self.m\n return self.rem(z).uint\n \n # @param n `0 <= n`\n # @param m `1 <= m`\n # @return `(x ** n) % m`\n proc pow_mod_constexpr*(x, n, m:int):int =\n if m == 1: return 0\n var\n r = 1\n y = floorMod(x, m)\n n = n\n while n != 0:\n if (n and 1) != 0: r = (r * y) mod m\n y = (y * y) mod m\n n = n shr 1\n return r.int\n \n # Reference:\n # M. Forisek and J. Jancina,\n # Fast Primality Testing for Integers That Fit into a Machine Word\n # @param n `0 <= n`\n proc is_prime_constexpr*(n:int):bool =\n if n <= 1: return false\n if n == 2 or n == 7 or n == 61: return true\n if n mod 2 == 0: return false\n var d = n - 1\n while d mod 2 == 0: d = d div 2\n for a in [2, 7, 61]:\n var\n t = d\n y = pow_mod_constexpr(a, t, n)\n while t != n - 1 and y != 1 and y != n - 1:\n y = y * y mod n\n t = t shl 1\n if y != n - 1 and t mod 2 == 0:\n return false\n return true\n proc is_prime*[n:static[int]]():bool = is_prime_constexpr(n)\n # \n # # @param b `1 <= b`\n # # @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g\n proc inv_gcd*(a, b:int):(int,int) =\n var a = floorMod(a, b)\n if a == 0: return (b, 0)\n \n # Contracts:\n # [1] s - m0 * a = 0 (mod b)\n # [2] t - m1 * a = 0 (mod b)\n # [3] s * |m1| + t * |m0| <= b\n var\n s = b\n t = a\n m0 = 0\n m1 = 1\n \n while t != 0:\n var u = s div t\n s -= t * u;\n m0 -= m1 * u; # |m1 * u| <= |m1| * s <= b\n \n # [3]:\n # (s - t * u) * |m1| + t * |m0 - m1 * u|\n # <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)\n # = s * |m1| + t * |m0| <= b\n \n var tmp = s\n s = t;t = tmp;\n tmp = m0;m0 = m1;m1 = tmp;\n # by [3]: |m0| <= b/g\n # by g != b: |m0| < b/g\n if m0 < 0: m0 += b div s\n return (s, m0)\n \n # Compile time primitive root\n # @param m must be prime\n # @return primitive root (and minimum in now)\n proc primitive_root_constexpr*(m:int):int =\n if m == 2: return 1\n if m == 167772161: return 3\n if m == 469762049: return 3\n if m == 754974721: return 11\n if m == 998244353: return 3\n var divs:array[20, int]\n divs[0] = 2\n var cnt = 1\n var x = (m - 1) div 2\n while x mod 2 == 0: x = x div 2\n var i = 3\n while i * i <= x:\n if x mod i == 0:\n divs[cnt] = i\n cnt.inc\n while x mod i == 0:\n x = x div i\n i += 2\n if x > 1:\n divs[cnt] = x\n cnt.inc\n var g = 2\n while true:\n var ok = true\n for i in 0..= m:\n result += n * (n - 1) div 2 * (a div m)\n a = a mod m\n if b >= m:\n result += n * (b div m)\n b = b mod m\n \n let y_max = a * n + b\n if y_max < m: break\n # y_max < m * (n + 1)\n # floor(y_max / m) <= n\n n = y_max div m\n b = y_max mod m\n swap(m, a)\n \n\n proc getBarrett*[T:static[int]](t:typedesc[DynamicModInt[T]]):ptr Barrett =\n {.cast(noSideEffect).}:\n var Barrett_of_DynamicModInt {.global.} = initBarrett(998244353.uint)\n return Barrett_of_DynamicModInt.addr\n \n proc getMod*[T:static[int]](t:typedesc[DynamicModInt[T]]):uint32 {.inline.} =\n (t.getBarrett)[].m.uint32\n proc setMod*[T:static[int]](t:typedesc[DynamicModInt[T]], M:SomeInteger){.inline.} =\n (t.getBarrett)[] = initBarrett(M.uint)\n\n proc val*(m: ModInt): int {.inline.} = int(m.a)\n\n proc `$`*(m: StaticModInt or DynamicModInt): string {.inline.} = $(m.val())\n\n template umod*[T:ModInt](self: typedesc[T] or T):uint32 =\n when T is typedesc:\n when T is StaticModInt:\n T.M.uint32\n elif T is DynamicModInt:\n T.getMod()\n else:\n static: assert false\n else: T.umod\n\n template `mod`*[T:ModInt](self:typedesc[T] or T):int = T.umod.int\n\n proc init*[T:ModInt](t:typedesc[T], v: SomeInteger or T): auto {.inline.} =\n when v is T: return v\n else:\n when v is SomeUnsignedInt:\n if v.uint < T.umod:\n return T(a:v.uint32)\n else:\n return T(a:(v.uint mod T.umod.uint).uint32)\n else:\n var v = v.int\n if 0 <= v:\n if v < T.mod: return T(a:v.uint32)\n else: return T(a:(v mod T.mod).uint32)\n else:\n v = v mod T.mod\n if v < 0: v += T.mod\n return T(a:v.uint32)\n proc unit*[T:ModInt](t:typedesc[T] or T):T = T.init(1)\n\n template initModInt*(v: SomeInteger or ModInt; M: static[int] = 1_000_000_007): auto =\n StaticModInt[M].init(v)\n\n# TODO\n# converter toModInt[M:static[int]](n:SomeInteger):StaticModInt[M] {.inline.} = initModInt(n, M)\n\n# proc initModIntRaw*(v: SomeInteger; M: static[int] = 1_000_000_007): auto {.inline.} =\n# ModInt[M](v.uint32)\n proc raw*[T:ModInt](t:typedesc[T], v:SomeInteger):auto = T(a:v)\n\n proc inv*[T:ModInt](v:T):T {.inline.} =\n var\n a = v.a.int\n b = T.mod\n u = 1\n v = 0\n while b > 0:\n let t = a div b\n a -= t * b;swap(a, b)\n u -= t * v;swap(u, v)\n return T.init(u)\n\n\n proc `-`*[T:ModInt](m: T): T {.inline.} =\n if int(m.a) == 0: return m\n else: return T(a:m.umod() - m.a)\n\n proc `+=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} =\n m.a += T.init(n).a\n if m.a >= T.umod: m.a -= T.umod\n return m\n\n proc `-=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} =\n m.a -= T.init(n).a\n if m.a >= T.umod: m.a += T.umod\n return m\n\n proc `*=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} =\n when T is StaticModInt:\n m.a = (m.a.uint * T.init(n).a.uint mod T.umod).uint32\n elif T is DynamicModInt:\n m.a = T.getBarrett[].mul(m.a.uint, T.init(n).a.uint).uint32\n else:\n static: assert false\n return m\n\n proc `/=`*[T:ModInt](m: var T; n: SomeInteger | T):T {.inline discardable.} =\n m.a = (m.a.uint * T.init(n).inv().a.uint mod T.umod).uint32\n return m\n\n generateDefinitions(`+`, m, n, ModInt, SomeInteger):\n result = T.init(m)\n result += n\n\n generateDefinitions(`-`, m, n, ModInt, SomeInteger):\n result = T.init(m)\n result -= n\n\n generateDefinitions(`*`, m, n, ModInt, SomeInteger):\n result = T.init(m)\n result *= n\n\n generateDefinitions(`/`, m, n, ModInt, SomeInteger):\n result = T.init(m)\n result /= n\n\n generateDefinitions(`==`, m, n, ModInt, SomeInteger):\n result = (T.init(m).val() == T.init(n).val())\n\n proc inc*(m: var ModInt):ModInt {.inline discardable.} =\n m.a.inc\n if m.a == m.umod.uint32:\n m.a = 0\n return m\n proc `++`*(m: var ModInt):ModInt {.inline discardable.} = m.inc\n\n proc dec*(m: var ModInt):ModInt {.inline discardable.} =\n if m.a == 0.uint32:\n m.a = m.umod - 1\n else:\n m.a.dec\n return m\n proc `--`*(m: var ModInt):ModInt {.inline discardable.} = m.dec\n\n generatePow(ModInt)\n \n # TODO: intのところはSomeIntegerに拡張したいがそうするとSystem.nimのuintのconverterとバッティングする。。。\n template useStaticModint*(name, M) =\n generateConverter(name, int, StaticModInt[M])\n template useDynamicModInt*(name, M) =\n generateConverter(name, int, DynamicModInt[M])\n\n # TODO: Nimのstatic[int]を使うconverterがバグっていて個々に宣言しないとconverterが使えない\n # したがって、下記以外のmodintを使う場合はuseStaticModIntあるいはuseDynamicModIntで宣言が必要\n useStaticModInt(modint998244353, 998244353)\n useStaticModInt(modint1000000007, 1000000007)\n useDynamicModInt(modint, -1)\n\n import std/math as math_lib_modint\n proc estimateRational*(a:ModInt, ub:int = int(sqrt(float(ModInt.mod))), output_stderr:static[bool] = false):string =\n var v:seq[tuple[s, n, d: int]]\n for d in 1 .. ub:\n var n = (a * d).val\n # n or mod - n\n if n * 2 > a.mod:\n n = - (a.mod - n)\n if gcd(n, d) > 1: continue\n v.add((n.abs + d, n, d))\n v.sort\n when output_stderr:\n stderr.write \"estimation result: \", v\n return $v[0].n & \"/\" & $v[0].d\n\n # TODO:\n # Modint -> intのconverterあるとmint(2) * 3みたいなのがintになっちゃう\n # converter toInt*(m: ModInt):int {.inline.} = m.val\n\n\n" # source: src/cplib/graph/graph.nim ImportExpand "cplib/graph/graph" <=== "when not declared CPLIB_GRAPH_GRAPH:\n const CPLIB_GRAPH_GRAPH* = 1\n\n import sequtils\n import math\n type DynamicGraph*[T] = ref object of RootObj\n edges*: seq[seq[(int32, T)]]\n len*: int\n type StaticGraph*[T] = ref object of RootObj\n src*, dst*: seq[int32]\n cost*: seq[T]\n elist*: seq[(int32, T)]\n start*: seq[int32]\n len*: int\n\n type WeightedDirectedGraph*[T] = ref object of DynamicGraph[T]\n type WeightedUnDirectedGraph*[T] = ref object of DynamicGraph[T]\n type UnWeightedDirectedGraph* = ref object of DynamicGraph[int]\n type UnWeightedUnDirectedGraph* = ref object of DynamicGraph[int]\n type WeightedDirectedStaticGraph*[T] = ref object of StaticGraph[T]\n type WeightedUnDirectedStaticGraph*[T] = ref object of StaticGraph[T]\n type UnWeightedDirectedStaticGraph* = ref object of StaticGraph[int]\n type UnWeightedUnDirectedStaticGraph* = ref object of StaticGraph[int]\n\n type GraphTypes*[T] = DynamicGraph[T] or StaticGraph[T]\n type DirectedGraph* = WeightedDirectedGraph or UnWeightedDirectedGraph or WeightedDirectedStaticGraph or UnWeightedDirectedStaticGraph\n type UnDirectedGraph* = WeightedUnDirectedGraph or UnWeightedUnDirectedGraph or WeightedUnDirectedStaticGraph or UnWeightedUnDirectedStaticGraph\n type WeightedGraph*[T] = WeightedDirectedGraph[T] or WeightedUnDirectedGraph[T] or WeightedDirectedStaticGraph[T] or WeightedUnDirectedStaticGraph[T]\n type UnWeightedGraph* = UnWeightedDirectedGraph or UnWeightedUnDirectedGraph or UnWeightedDirectedStaticGraph or UnWeightedUnDirectedStaticGraph\n type DynamicGraphTypes* = WeightedDirectedGraph or UnWeightedDirectedGraph or WeightedUnDirectedGraph or UnWeightedUnDirectedGraph\n type StaticGraphTypes* = WeightedDirectedStaticGraph or UnWeightedDirectedStaticGraph or WeightedUnDirectedStaticGraph or UnWeightedUnDirectedStaticGraph\n\n proc add_edge_dynamic_impl*[T](g: DynamicGraph[T], u, v: int, cost: T, directed: bool) =\n g.edges[u].add((v.int32, cost))\n if not directed: g.edges[v].add((u.int32, cost))\n\n proc initWeightedDirectedGraph*(N: int, edgetype: typedesc = int): WeightedDirectedGraph[edgetype] =\n result = WeightedDirectedGraph[edgetype](edges: newSeq[seq[(int32, edgetype)]](N), len: N)\n proc add_edge*[T](g: var WeightedDirectedGraph[T], u, v: int, cost: T) =\n g.add_edge_dynamic_impl(u, v, cost, true)\n\n proc initWeightedUnDirectedGraph*(N: int, edgetype: typedesc = int): WeightedUnDirectedGraph[edgetype] =\n result = WeightedUnDirectedGraph[edgetype](edges: newSeq[seq[(int32, edgetype)]](N), len: N)\n proc add_edge*[T](g: var WeightedUnDirectedGraph[T], u, v: int, cost: T) =\n g.add_edge_dynamic_impl(u, v, cost, false)\n\n proc initUnWeightedDirectedGraph*(N: int): UnWeightedDirectedGraph =\n result = UnWeightedDirectedGraph(edges: newSeq[seq[(int32, int)]](N), len: N)\n proc add_edge*(g: var UnWeightedDirectedGraph, u, v: int) =\n g.add_edge_dynamic_impl(u, v, 1, true)\n\n proc initUnWeightedUnDirectedGraph*(N: int): UnWeightedUnDirectedGraph =\n result = UnWeightedUnDirectedGraph(edges: newSeq[seq[(int32, int)]](N), len: N)\n proc add_edge*(g: var UnWeightedUnDirectedGraph, u, v: int) =\n g.add_edge_dynamic_impl(u, v, 1, false)\n\n proc len*[T](G: WeightedGraph[T]): int = G.len\n proc len*(G: UnWeightedGraph): int = G.len\n\n iterator `[]`*[T](g: WeightedDirectedGraph[T] or WeightedUnDirectedGraph[T], x: int): (int, T) =\n for e in g.edges[x]: yield (e[0].int, e[1])\n iterator `[]`*(g: UnWeightedDirectedGraph or UnWeightedUnDirectedGraph, x: int): int =\n for e in g.edges[x]: yield e[0].int\n\n proc add_edge_static_impl*[T](g: StaticGraph[T], u, v: int, cost: T, directed: bool) =\n g.src.add(u.int32)\n g.dst.add(v.int32)\n g.cost.add(cost)\n if not directed:\n g.src.add(v.int32)\n g.dst.add(u.int32)\n g.cost.add(cost)\n\n proc build_impl*[T](g: StaticGraph[T]) =\n g.start = newSeqWith(g.len + 1, 0.int32)\n for i in 0.. 0, \"Static Graph must be initialized before use.\"\n\n iterator `[]`*[T](g: WeightedDirectedStaticGraph[T] or WeightedUnDirectedStaticGraph[T], x: int): (int, T) =\n g.static_graph_initialized_check()\n for i in g.start[x].. hld.PD[v]:\n u = hld.P[hld.PP[u]]\n while hld.PP[u] != hld.PP[v]:\n u = hld.P[hld.PP[u]]\n v = hld.P[hld.PP[v]]\n if hld.D[u] > hld.D[v]:\n return v\n u\n proc dist*(hld: HeavyLightDecomposition, u: int, v: int): int =\n hld.depth(u) + hld.depth(v) - hld.depth(hld.lca(u, v)) * 2\n proc path*(hld: HeavyLightDecomposition, r: int, c: int, include_root: bool, reverse_path: bool): seq[(int, int)] =\n var (r, c) = (r, c)\n var k = hld.PD[c] - hld.PD[r] + 1\n if k <= 0:\n return @[]\n var res = newSeqWith(k, (0, 0))\n for i in 0.. hld.D[c]:\n return @[]\n var root_off = int(not include_root)\n res[^1] = (hld.rangeL[r]+root_off, hld.rangeL[c]+1)\n if res[^1][0] == res[^1][1]:\n discard res.pop()\n k -= 1\n if reverse_path:\n for i in 0.. 0 and hld.toSeq2Out(stack[^1]) < hld.toseq2In(v[i]):\n discard stack.pop()\n if len(stack) != 0:\n result.add_edge(stack[^1],v[i])\n stack.add(v[i])\n \n proc initAuxiliaryWeightedTree*(hld:HeavyLightDecomposition,v:seq[int]):WeightedUnDirectedTableGraph[int,int]=\n var v = v.sortedByit(hld.toseq(it))\n for i in 0..<(len(v)-1):\n v.add(hld.lca(v[i],v[i+1]))\n v = v.sortedByIt(hld.toseq(it)).deduplicate(true)\n var stack :seq[int]\n result = initWeightedUnDirectedTableGraph(v,int)\n stack.add(v[0])\n for i in 1.. 0 and hld.toSeq2Out(stack[^1]) < hld.toseq2In(v[i]):\n discard stack.pop()\n if len(stack) != 0:\n result.add_edge(stack[^1],v[i],hld.depth(v[i])-hld.depth(stack[^1]))\n stack.add(v[i])\n\n" type mint = modint998244353 # 根付き木が与えられる。 # 以下を満たすようなAの個数 mod998 # N 頂点それぞれに1つずつ非負整数を書き込んでいく。 # 部分木のmexはA_iである。 # コレを満たすような書き方が存在するようなAならok # 自明なこと # mexはうまくやったとしても部分木サイズくらいまでしか行かない。 # iの子をjとしたときに、必ずA[i] >= A[j]が成立する # mexより大きかったような頂点数とかが欲しくなるわけでありますね? # DP[i][mexに関与しなかったような頂点数] = mod998 # 2乗の木DP var N = ii() var P = lii(N) var G = initUnWeightedUnDirectedGraph(N) for i in 0..<(N-1): G.add_edge(P[i]-1,i+1) var T = initHld(G,0) var DP = newseq[seq[mint]](N) proc dfs(x:int)= var now = newseqwith(1,mint(1)) for y in T.children(x): dfs(y) var (l,r) = T.subtree(y) var sz = r-l var nxt = newseqwith(len(DP[y])+len(now)-1,mint(0)) for i in 0..