結果

問題 No.3095 Many Min Problems
ユーザー 👑 seekworser
提出日時 2025-04-06 17:26:56
言語 Nim
(2.2.0)
結果
AC  
実行時間 1,025 ms / 2,000 ms
コード長 60,869 bytes
コンパイル時間 8,061 ms
コンパイル使用メモリ 138,744 KB
実行使用メモリ 45,376 KB
最終ジャッジ日時 2025-04-06 17:27:21
合計ジャッジ時間 22,857 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 30
権限があれば一括ダウンロードができます

ソースコード

diff #

import macros;macro ImportExpand(s:untyped):untyped = parseStmt($s[2])
# source: https://github.com/kemuniku/cplib/tree/main/src/cplib/tmpl/citrus.nim
ImportExpand "cplib/tmpl/citrus" <=== "when not declared CPLIB_TMPL_CITRUS:\n    const CPLIB_TMPL_CITRUS* = 1\n    {.warning[UnusedImport]: off.}\n    {.hint[XDeclaredButNotUsed]: off.}\n    import os\n    import algorithm\n    import sequtils\n    import tables\n    import macros\n    import std/math\n    import sets\n    import strutils\n    import strformat\n    import sugar\n    import streams\n    import deques\n    import bitops\n    import heapqueue\n    import options\n    import hashes\n    const MODINT998244353* = 998244353\n    const MODINT1000000007* = 1000000007\n    when not declared CPLIB_UTILS_CONSTANTS:\n        const CPLIB_UTILS_CONSTANTS* = 1\n        const INF32*: int32 = 100100111.int32\n        const INF64*: int = int(3300300300300300491)\n    \n    const INFL = INF64\n    type double* = float64\n    let readNext = iterator(getsChar: bool = false): string {.closure.} =\n        while true:\n            var si: string\n            try: si = stdin.readLine\n            except EOFError: yield \"\"\n            for s in si.split:\n                if getsChar:\n                    for i in 0..<s.len():\n                        yield s[i..i]\n                else:\n                    if s.isEmptyOrWhitespace: continue\n                    yield s\n    proc input*(t: typedesc[string]): string = readNext()\n    proc input*(t: typedesc[char]): char = readNext(true)[0]\n    proc input*(t: typedesc[int]): int = readNext().parseInt\n    proc input*(t: typedesc[float]): float = readNext().parseFloat\n    macro input*(t: typedesc, n: varargs[int]): untyped =\n        var repStr = \"\"\n        for arg in n:\n            repStr &= &\"({arg.repr}).newSeqWith \"\n        parseExpr(&\"{repStr}input({t})\")\n    macro input*(ts: varargs[auto]): untyped =\n        var tupStr = \"\"\n        for t in ts:\n            tupStr &= &\"input({t.repr}),\"\n        parseExpr(&\"({tupStr})\")\n    macro input*(n: int, ts: varargs[auto]): untyped =\n        for typ in ts:\n            if typ.typeKind != ntyAnything:\n                error(\"Expected typedesc, got \" & typ.repr, typ)\n        parseExpr(&\"({n.repr}).newSeqWith input({ts.repr})\")\n    proc `fmtprint`*(x: int or string or char or bool): string = return $x\n    proc `fmtprint`*(x: float or float32 or float64): string = return &\"{x:.16f}\"\n    proc `fmtprint`*[T](x: seq[T] or Deque[T] or HashSet[T] or set[T]): string = return x.toSeq.join(\" \")\n    proc `fmtprint`*[T, N](x: array[T, N]): string = return x.toSeq.join(\" \")\n    proc `fmtprint`*[T](x: HeapQueue[T]): string =\n        var q = x\n        while q.len != 0:\n            result &= &\"{q.pop()}\"\n            if q.len != 0: result &= \" \"\n    proc `fmtprint`*[T](x: CountTable[T]): string =\n        result = x.pairs.toSeq.mapIt(&\"{it[0]}: {it[1]}\").join(\" \")\n    proc `fmtprint`*[K, V](x: Table[K, V]): string =\n        result = x.pairs.toSeq.mapIt(&\"{it[0]}: {it[1]}\").join(\" \")\n    proc print*(prop: tuple[f: File, sepc: string, endc: string, flush: bool], args: varargs[string, `fmtprint`]) =\n        for i in 0..<len(args):\n            prop.f.write(&\"{args[i]}\")\n            if i != len(args) - 1: prop.f.write(prop.sepc) else: prop.f.write(prop.endc)\n        if prop.flush: prop.f.flushFile()\n    proc print*(args: varargs[string, `fmtprint`]) = print((f: stdout, sepc: \" \", endc: \"\\n\", flush: false), args)\n    const LOCAL_DEBUG{.booldefine.} = false\n    macro getSymbolName(x: typed): string = x.toStrLit\n    macro debug*(args: varargs[untyped]): untyped =\n        when LOCAL_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    proc `%`*(x: SomeInteger, y: SomeInteger): 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: SomeInteger, y: SomeInteger): int =\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: SomeInteger, y: SomeInteger): int = x xor y\n    proc `&`*(x: SomeInteger, y: SomeInteger): int = x and y\n    proc `|`*(x: SomeInteger, y: SomeInteger): int = x or y\n    proc `>>`*(x: SomeInteger, y: SomeInteger): int = x shr y\n    proc `<<`*(x: SomeInteger, y: SomeInteger): int = x shl y\n    proc `%=`*(x: var SomeInteger, y: SomeInteger): void = x = x % y\n    proc `//=`*(x: var SomeInteger, y: SomeInteger): void = x = x // y\n    proc `^=`*(x: var SomeInteger, y: SomeInteger): void = x = x ^ y\n    proc `&=`*(x: var SomeInteger, y: SomeInteger): void = x = x & y\n    proc `|=`*(x: var SomeInteger, y: SomeInteger): void = x = x | y\n    proc `>>=`*(x: var SomeInteger, y: SomeInteger): void = x = x >> y\n    proc `<<=`*(x: var SomeInteger, y: SomeInteger): void = x = x << y\n    proc `[]`*(x, n: int): bool = (x and (1 shl n)) != 0\n    proc `[]=`*(x: var int, n: int, i: bool) =\n        if i: x = x or (1 << n)\n        else: (if x[n]: x = x xor (1 << n))\n    proc pow*(a, n: int, m = INF64): int =\n        var\n            rev = 1\n            a = a\n            n = n\n        while n > 0:\n            if n % 2 != 0: rev = (rev * a) mod m\n            if n > 1: a = (a * a) mod m\n            n >>= 1\n        return rev\n    when not declared CPLIB_MATH_ISQRT:\n        const CPLIB_MATH_ISQRT* = 1\n        proc isqrt*(n: int): int =\n            var x = n\n            var y = (x + 1) shr 1\n            while y < x:\n                x = y\n                y = (x + n div x) shr 1\n            return x\n    \n    proc chmax*[T](x: var T, y: T): bool {.discardable.} = (if x < y: (x = y; return true; ) return false)\n    proc chmin*[T](x: var T, y: T): bool {.discardable.} = (if x > y: (x = y; return true; ) return false)\n    proc `max=`*[T](x: var T, y: T) = x = max(x, y)\n    proc `min=`*[T](x: var T, y: T) = x = min(x, y)\n    proc at*(x: char, a = '0'): int = int(x) - int(a)\n    proc Yes*(b: bool = true): void = print(if b: \"Yes\" else: \"No\")\n    proc No*(b: bool = true): void = Yes(not b)\n    proc YES_upper*(b: bool = true): void = print(if b: \"YES\" else: \"NO\")\n    proc NO_upper*(b: bool = true): void = Yes_upper(not b)\n    const DXY* = [(0, -1), (0, 1), (-1, 0), (1, 0)]\n    const DDXY* = [(1, -1), (1, 0), (1, 1), (0, -1), (0, 1), (-1, -1), (-1, 0), (-1, 1)]\n    macro exit*(statement: untyped): untyped = (quote do: (`statement`; quit()))\n    proc initHashSet[T](): Hashset[T] = initHashSet[T](0)\n"
# source: https://github.com/zer0-star/Nim-ACL/tree/master/src/atcoder/extra/math/formal_power_series.nim
ImportExpand "atcoder/extra/math/formal_power_series" <=== "when not declared ATCODER_FORMAL_POWER_SERIES:\n  const ATCODER_FORMAL_POWER_SERIES* = 1\n  \n  import std/sequtils\n  import std/strformat\n  import std/options\n  import std/macros\n  import std/tables\n  import std/algorithm\n  when not declared ATCODER_ELEMENT_CONCEPTS_HPP:\n    const ATCODER_ELEMENT_CONCEPTS_HPP* = 1\n    proc inv*[T:SomeFloat](a:T):auto = T(1) / a\n    proc init*(self:typedesc[SomeFloat], a:SomeNumber):auto = self(a)\n    type AdditiveGroupElem* = concept x, y, type T\n      x + y\n      x - y\n      -x\n      T(0)\n    type MultiplicativeGroupElem* = concept x, y, type T\n      x * y\n      x / y\n  #    x.inv()\n      T(1)\n    type RingElem* = concept x, y, type T\n      x + y\n      x - y\n      -x\n      x * y\n      T(0)\n      T(1)\n    type FieldElem* = concept x, y, type T\n      x + y\n      x - y\n      x * y\n      x / y\n      -x\n  #    x.inv()\n      T(0)\n      T(1)\n    type FiniteFieldElem* = concept x, type T\n      T is FieldElem\n      T.mod\n      T.mod() is int\n      x.pow(1000000)\n    type hasInf* = concept x, type T\n      T(Inf)\n  \n\n  type FormalPowerSeries*[T:FieldElem] = seq[T]\n  type Poly*[T:FieldElem] = FormalPowerSeries[T]\n  type FPS*[T:FieldElem] = FormalPowerSeries[T]\n\n  proc `$`*(f:seq): string {.inline.} =\n    var s:seq[int]\n    for i in f.len:\n      s.add $(f[i]) & \" x^\" & i\n    return s.join(\"+\")\n\n\n  template hasFFT*(T:typedesc):bool =\n    mixin fft\n    type hasFFTC = concept x\n      @[x].fft()\n    T is hasFFTC\n\n  template initFormalPowerSeries*[T:FieldElem](n:int):FormalPowerSeries[T] =\n    block:\n      FormalPowerSeries[T](newSeq[T](n))\n  template initFormalPowerSeries*[T:FieldElem;U: not T](data:openArray[U]):FormalPowerSeries[T] =\n    block:\n      var result = newSeq[T](data.len)\n      for i, it in data:\n        result[i] = T(it)\n      FormalPowerSeries[T](result)\n  template initFormalPowerSeries*[T:FieldElem](data:openArray[T]):FormalPowerSeries[T] =\n    block:\n      data\n\n  template init*[T:FieldElem](self:typedesc[FormalPowerSeries[T]], data:typed):auto =\n    initFormalPowerSeries[T](data)\n\n  # {{{ sparseFormalPowerSeries\n\n  type SparseFormalPowerSeries*[T:FieldElem] = seq[tuple[d:int, c:T]] # sorted ascending order\n\n#  converter toSparseFormalPowerSeries*[XI, T](a:array[XI, (int, T)]):SparseFormalPowerSeries[T] = a.toSeq()\n\n  # SparseMonomial {{{\n  type Monomial*[T] = object\n    c:T\n    d:int\n  \n  proc initVar*[T](c = 1, d = 1):SparseFormalPowerSeries[T] = @[(d:d, c:T(c))]\n  \n  proc `^`*[T](f:SparseFormalPowerSeries[T], n:int):SparseFormalPowerSeries[T] =\n    assert f.len == 1\n    result.add(f[0])\n    result[0].d *= n\n    if f[0].c != T.init(1): result[0].c = result[0].c ^ n\n  \n#  converter toSFPS*[T](f:Monomial[T]):SparseFormalPowerSeries[T] = @[(f.d,f.c)]\n\n#  proc `+`*[T](f, g: Monomial[T]):SparseFormalPowerSeries[T] =\n#    return toSFPS(f) + toSFPS(g)\n\n  # }}}\n\n  converter toSFPS*[T](f:Table[int, T]):SparseFormalPowerSeries[T] =\n    for d, c in f:\n      result.add((d, c))\n    result.sort do (x, y:(int, T)) -> int:\n      cmp(x[0], y[0])\n\n#  converter toSFPS*[T](a:T):SparseFormalPowerSeries[T] = @[(0, a)]\n  proc deg*[T](a:SparseFormalPowerSeries[T]):int =\n    if a.len == 0: return int.low\n    else: return a[^1].d\n  proc `+=`*[T](a:var SparseFormalPowerSeries[T], b:SparseFormalPowerSeries[T]) =\n    var r:SparseFormalPowerSeries[T]\n    var i, j = 0\n    while i < a.len or j < b.len:\n      if i < a.len and j < b.len and a[i].d == b[j].d:\n        r.add((a[i].d, a[i].c + b[j].c))\n        i.inc;j.inc\n      else:\n        if j == b.len or (i < a.len and a[i].d < b[j].d):\n          r.add(a[i]);i.inc\n        else:\n          r.add(b[j]);j.inc\n    swap(r, a)\n  proc `+=`*[T](a:var SparseFormalPowerSeries[T], b:T) = a += @[(0, b)]\n  proc `+=`*[T](a:var FormalPowerSeries[T], b:SparseFormalPowerSeries[T]) =\n    for p in b:\n      while a.len <= p.d: a.add(T.init(0))\n      a[p.d] += p.c\n  proc `-=`*[T](a:var SparseFormalPowerSeries[T], b:SparseFormalPowerSeries[T]) =\n    var r:SparseFormalPowerSeries[T]\n    var i, j = 0\n    while i < a.len or j < b.len:\n      if i < a.len and j < b.len and a[i].d == b[j].d:\n        r.add((a[i].d, a[i].c - b[j].c))\n        i.inc;j.inc\n      else:\n        if j == b.len or (i < a.len and a[i].d < b[j].d):\n          r.add(a[i]);i.inc\n        else:\n          r.add((b[j].d, -b[j].c));j.inc\n    swap(r, a)\n  proc `-=`*[T](a:var SparseFormalPowerSeries[T], b:T) = a -= @[(0, b)]\n  proc `-=`*[T](a:var FormalPowerSeries[T], b:SparseFormalPowerSeries[T]) =\n    for p in b:\n      while a.len <= p.d: a.add(T.init(0))\n      a[p.d] -= p.c\n\n  proc `*`*[T](a:FormalPowerSeries[T], b:SparseFormalPowerSeries[T], deg = -1):FormalPowerSeries[T] =\n    var deg = deg\n    if deg == -1:\n      let bdeg = b[^1][0]\n      deg = a.len + bdeg\n    result = initFormalPowerSeries[T](deg)\n    for i in 0..<a.len:\n      for (j, c) in b:\n        let k = i + j\n        if k < deg: result[k] += a[i] * c\n  proc `*=`*[T](a:var SparseFormalPowerSeries[T], b:SparseFormalPowerSeries[T], deg = -1) =\n    var r = initTable[int,T]()\n    for (i, c0) in a:\n      for (j, c1) in b:\n        let k = i + j\n        if deg != -1 and k >= deg: continue\n        if k notin r: r[k] = T.init(0)\n        r[k] += c0 * c1\n    var rs = SparseFormalPowerSeries[T](r)\n    swap(rs, a)\n  proc `*=`*[T](a:var SparseFormalPowerSeries[T], b:T) =\n    for (i, c) in a.mitems:\n      c = c * b\n  proc `*`*[T](a:SparseFormalPowerSeries[T], b:T):SparseFormalPowerSeries[T] =\n    result = a\n    result *= b\n  proc `*`*[T](b:T, a:var SparseFormalPowerSeries[T]):SparseFormalPowerSeries[T] =\n    result = a\n    for (i, c) in result.mitems:\n      c = b * c\n\n  macro declareSparseFormalPowerSeriesOperators(op) =\n    fmt\"\"\"proc `{op}`*[T](self:SparseFormalPowerSeries[T];r:SparseFormalPowerSeries[T] or T):SparseFormalPowerSeries[T] = result = self;result {op}= r\nproc `{op}`*[T](self: not SparseFormalPowerSeries and not Monomial, r:SparseFormalPowerSeries[T]):SparseFormalPowerSeries[T] = result = @[(0, T(self))];result {op}= r\"\"\".parsestmt\n\n  declareSparseFormalPowerSeriesOperators(`+`)\n  declareSparseFormalPowerSeriesOperators(`-`)\n  declareSparseFormalPowerSeriesOperators(`*`)\n\n  proc divMod*[T](a: FormalPowerSeries[T], b:SparseFormalPowerSeries[T]):(FormalPowerSeries[T], FormalPowerSeries[T]) =\n    mixin inv\n    var a = a\n    let\n      max_deg = b[^1][0]\n      inv_max_coef = b[^1][1].inv\n    var q = initFormalPowerSeries[T](a.len - max_deg)\n    for i in countdown(q.len - 1, 0):\n      q[i] = a[i + max_deg] * inv_max_coef\n      for (d, v) in b:\n        a[i + d] -= q[i] * v\n    return (q, a[0..<max_deg])\n  proc `div`*[T:FieldElem](a: FormalPowerSeries[T], b:SparseFormalPowerSeries[T]):auto = a.divMod(b)[0]\n  proc `mod`*[T:FieldElem](a: FormalPowerSeries[T], b:SparseFormalPowerSeries[T]):auto = a.divMod(b)[1]\n\n  proc EQUAL*[T](a, b:T):bool =\n    when T is hasInf:\n      return (abs(a - b) < T(0.0000001))\n    else:\n      return a == b\n\n  macro revise*(a, b) =\n    parseStmt(fmt\"\"\"let {a.repr} = if {a.repr} == -1: {b.repr} else: {a.repr}\"\"\")\n  proc shrink*[T](self: var FormalPowerSeries[T]) =\n    while self.len > 0 and EQUAL(self[^1], T(0)): discard self.pop()\n  proc resize*[T](self: var FormalPowerSeries[T], n:int) =\n    mixin setLen\n    let l = self.len\n    self.setLen(n)\n    if l < n:\n      self.fill(l, n - 1, T(0))\n\n  converter toFPS*[T](f:Monomial[T]):FormalPowerSeries[T] =\n    result = newSeq[T](f.d + 1)\n    result[f.d] = f.c\n  converter toFPS*[T](f:SparseFormalPowerSeries[T]):FormalPowerSeries[T] =\n    let d = f.deg\n    if d < 0: return\n    result.resize(d + 1)\n    result.fill(T(0))\n    for p in f: result[p.d] += p.c\n\n#  proc `+`*[T](f, g: Monomial[T]):FormalPowerSeries[T] =\n#    return toFPS(f) + toFPS(g)\n  \n  proc `*`*[T](f, g:Monomial[T]):Monomial[T] =\n    result.c = f.c * g.c\n    result.d = f.d + g.d\n  proc `*`*[T](a:T, f:Monomial[T]):Monomial[T] =\n    result = f\n    result.c *= a\n  proc `*`*[T](a:SomeInteger, f:Monomial[T]):Monomial[T] =\n    result = f\n    result.c *= T.init(a)\n\n  # operators +=, -=, *=, mod=, -, /= {{{\n  proc `+=`*[T](self: var FormalPowerSeries[T], r:FormalPowerSeries[T]) =\n    if r.len > self.len: self.setlen(r.len)\n    for i in 0..<r.len: self[i] += r[i]\n  proc `+=`*[T](self: var FormalPowerSeries[T], r:T) =\n    if self.len == 0: self.setlen(1)\n    self[0] += r\n  \n  proc `-=`*[T](self: var FormalPowerSeries[T], r:FormalPowerSeries[T]) =\n    if r.len > self.len: self.setlen(r.len)\n    for i in 0..<r.len: self[i] -= r[i]\n#    self.shrink()\n  proc `-=`*[T](self: var FormalPowerSeries[T], r:T) =\n    if self.len == 0: self.setlen(1)\n    self[0] -= r\n#    self.shrink()\n\n  proc `*=`*[T](self: var FormalPowerSeries[T], v:T) = self.applyIt(it * v)\n\n  proc mult_naive*[T](a, b:FormalPowerSeries[T]):FormalPowerSeries[T] =\n    result = initFormalPowerSeries[T](a.len + b.len - 1)\n    for i in 0..<a.len:\n      for j in 0..<b.len:\n        result[i + j] += a[i] * b[j]\n  proc div_naive*[T](a, b:FormalPowerSeries[T], deg = -1):FormalPowerSeries[T] =\n    mixin inv\n    var deg = if deg == -1: a.len else: deg\n    result = newSeq[T](deg)\n    # a = b * result\n    var b0inv = b[0].inv\n    for i in 0 ..< deg:\n      var u = a[i]\n      for j in 1 ..< min(i + 1, b.len):\n        u -= b[j] * result[i - j]\n      u *= b0inv\n      result[i] = u\n\n  proc `*=`*[T](self: var FormalPowerSeries[T],  r: FormalPowerSeries[T]) =\n    if self.len == 0 or r.len == 0:\n      self.setlen(0)\n    else:\n      when T.hasFFT:\n        mixin multiply\n        self = multiply(self, r)\n      else:\n        static:\n          echo(\"Warning: multiply is slow, please write import atcoder/extra/math/ntt\")\n        self = mult_naive(self, r)\n\n  proc `mod=`*[T](self: var FormalPowerSeries[T], r:FormalPowerSeries[T]) =\n    self -= (self div r) * r\n    self.resize(r.len - 1)\n    self.shrink()\n  #proc `divMod`*[T](self, r: FormalPowerSeries[T]):(FPS[T], FPS[T]) =\n  #  var self = self\n  #  let q = self div r\n  #  self -= q * r\n  #  self.resize(r.len - 1)\n  #  self.shrink()\n  #  return (q, self)\n\n  proc `-`*[T](self: FormalPowerSeries[T]):FormalPowerSeries[T] =\n    var ret = self\n    ret.applyIt(-it)\n    return ret\n  proc `/=`*[T](self: var FormalPowerSeries[T], v:T) = self.applyIt(it / v)\n  #}}}\n\n  proc rev*[T](self: FormalPowerSeries[T], deg = -1):auto =\n    result = self\n    if deg != -1: result.setlen(deg)\n    result.reverse\n  \n  proc pre*[T](self: FormalPowerSeries[T], sz:int):auto =\n    result = self\n    result.setlen(min(self.len, sz))\n  \n  proc `shr`*[T](self: FormalPowerSeries[T], sz:int):auto =\n    if self.len <= sz: return initFormalPowerSeries[T](0)\n    result = self\n    if sz >= 1: result.delete(0, sz - 1)\n  proc `shl`*[T](self: FormalPowerSeries[T], sz:int):auto =\n    result = initFormalPowerSeries[T](sz)\n    result = result & self\n  \n  proc diff*[T](self: FormalPowerSeries[T]):auto =\n    let n = self.len\n    result = initFormalPowerSeries[T](max(0, n - 1))\n    for i in 1..<n:\n      result[i - 1] = self[i] * T(i)\n  \n  proc integral*[T](self: FormalPowerSeries[T]):auto =\n    let n = self.len\n    result = initFormalPowerSeries[T](n + 1)\n    result[0] = T(0)\n    for i in 0..<n: result[i + 1] = self[i] / T(i + 1)\n  # F(0) must not be 0\n  proc inv*[T](self: FormalPowerSeries[T], deg = -1):auto =\n    assert(not EQUAL(self[0], T(0)))\n    deg.revise(self.len)\n#    type F = T.get_fft_type()\n#    when T is ModInt:\n    when true:\n      proc invFast[T](self: FormalPowerSeries[T]):auto =\n#        assert(self[0] != T(0))\n        let n = self.len\n        var res = initFormalPowerSeries[T](1)\n        res[0] = T(1) / self[0]\n        var d = 1\n        while d < n:\n          var f, g = initFormalPowerSeries[T](2 * d)\n          for j in 0..<min(n, 2 * d): f[j] = self[j]\n          for j in 0..<d: g[j] = res[j]\n          let g1 = fft(g)\n          f = ifft(dot(fft(f), g1, T), T)\n          for j in 0..<d:\n            f[j] = T(0)\n            f[j + d] = -f[j + d]\n          f = ifft(dot(fft(f), g1, T), T)\n          f[0..<d] = res[0..<d]\n          res = f\n          d = d shl 1\n        return res.pre(n)\n      var ret = self\n      ret.setlen(deg)\n      return ret.invFast()\n    else:\n      var ret = initFormalPowerSeries[T](1)\n      ret[0] = T(1) / self[0]\n      var i = 1\n      while i < deg:\n        ret = (ret + ret - ret * ret * self.pre(i shl 1)).pre(i shl 1)\n        i = i shl 1\n      return ret.pre(deg)\n  proc `/=`*[T](self: var FormalPowerSeries[T], r: FormalPowerSeries[T]) =\n    when T.hasFFT():\n      self *= r.inv()\n    else:\n      static:\n        echo(\"Warning: div is slow, please write import atcoder/extra/math/ntt\")\n      self = self.divNaive(r)\n\n  proc `div=`*[T](self: var FormalPowerSeries[T], r: FormalPowerSeries[T]) =\n    if self.len < r.len:\n      self.resize(0)\n    else:\n      let n = self.len - r.len + 1\n      self = (self.rev().pre(n) * r.rev().inv(n)).pre(n).rev(n)\n\n# operators +, -, *, div, mod {{{\n  macro declareFormalPowerSeriesOperators(op, op_eq) =\n    result = quote do:\n      proc `op`*[T](self:FormalPowerSeries[T];r:FormalPowerSeries[T] or T):FormalPowerSeries[T] = result = self;`op_eq`(result, r)\n      proc `op`*[T](self: not FormalPowerSeries and not Monomial, r:FormalPowerSeries[T]):FormalPowerSeries[T] = result = initFormalPowerSeries[T](@[T(self)]);`op_eq`(result, r)\n\n  declareFormalPowerSeriesOperators(`+`, `+=`)\n  declareFormalPowerSeriesOperators(`-`, `-=`)\n  declareFormalPowerSeriesOperators(`*`, `*=`)\n  declareFormalPowerSeriesOperators(`/`, `/=`)\n  \n  proc `div`*[T](self, r:FormalPowerSeries[T]):FormalPowerSeries[T] = result = self;result.`div=` (r)\n  proc `mod`*[T](self, r:FormalPowerSeries[T]):FormalPowerSeries[T] = result = self;result.`mod=` (r)\n  # }}}\n  \n  # F(0) must be 1\n  proc log*[T](self:FormalPowerSeries[T], deg = -1):auto =\n    assert EQUAL(self[0], T(1))\n    deg.revise(self.len)\n    return (self.diff() * self.inv(deg)).pre(deg - 1).integral()\n\n  proc expFast[T:FieldElem](self: FormalPowerSeries[T], deg:int):auto =\n    deg.revise(self.len)\n    assert EQUAL(self[0], T(0))\n\n    var inv = newSeqOfCap[T](deg + 1)\n    inv.add(T(0))\n    inv.add(T(1))\n\n    proc inplace_integral(F:var FormalPowerSeries[T]) =\n      let\n        n = F.len\n      when T is FiniteFieldElem:\n        let\n          M = T.mod\n      while inv.len <= n:\n        let i = inv.len\n        when T is FiniteFieldElem:\n          inv.add((-inv[M mod i]) * (M div i))\n        else:\n          inv.add(T(1)/T(i))\n      F = @[T(0)] & F\n      for i in 1..n: F[i] *= inv[i]\n\n    proc inplace_diff(F:var FormalPowerSeries[T]):auto =\n      if F.len == 0: return\n      F = F[1..<F.len]\n      var coeff = T(1)\n      let one = T(1)\n      for i in 0..<F.len:\n        F[i] *= coeff\n        coeff += one\n    mixin fft, ifft, dot\n    type FFTType = fft(initFormalPowerSeries[T](0)).type\n    mixin inplace_partial_dot\n    var\n      b = @[T(1), if 1 < self.len: self[1] else: T(0)]\n      c = @[T(1)]\n      z1f:FFTType\n      z2 = @[T(1), T(0)]\n      z2f = z2.fft\n    var m = 2\n    while m < deg:\n      var y = b\n      y.resize(2 * m)\n      var yf = y.fft\n      z1f = z2f\n      var zf = yf\n      zf.setLen(m)\n      inplace_partial_dot(zf, z1f, 0..<m, T)\n      var z = zf.ifft(T)\n      for i in 0..<m div 2: z[i] = T(0)\n      zf = z.fft\n      z = ifft(dot(zf, z1f, T), T)\n      for i in 0..<m:z[i] *= -1\n      c = c & z[m div 2..^1]\n      z2 = c\n      z2.resize(2 * m)\n      z2f = z2.fft\n      var x = self[0..<min(self.len, m)]\n      inplace_diff(x)\n      x.add(T(0))\n      var xf = x.fft\n      inplace_partial_dot(xf, yf, 0..<m, T)\n      x = xf.ifft(T)\n      x -= b.diff()\n      x.resize(2 * m)\n      for i in 0..<m - 1: x[m + i] = x[i]; x[i] = T(0)\n      xf = x.fft\n      inplace_partial_dot(xf, z2f, 0..<2*m, T)\n      x = xf.ifft(T)\n      discard x.pop()\n      inplace_integral(x)\n      for i in m..<min(self.len, 2 * m): x[i] += self[i]\n      for i in 0..<m: x[i] = T(0)\n      xf = x.fft\n      inplace_partial_dot(xf, yf, 0..<2*m, T)\n      x = xf.ifft(T)\n      b = b & x[m..^1]\n      m *= 2\n    return b[0..<deg]\n\n#   F(0) must be 0\n  proc exp*[T](self: FormalPowerSeries[T], deg = -1):auto =\n    assert EQUAL(self[0], T(0))\n    deg.revise(self.len)\n\n    when T is FiniteFieldElem:\n      var self = self\n      self.resize(deg)\n      return self.expFast(deg)\n    else:\n      var\n        ret = initFormalPowerSeries[T](@[T(1)])\n        i = 1\n      while i < deg:\n        ret = (ret * (self.pre(i shl 1) + T(1) - ret.log(i shl 1))).pre(i shl 1)\n        i = i shl 1\n      return ret.pre(deg)\n\n  proc pow*[T:FieldElem](self: FormalPowerSeries[T], k:int, deg = -1):FormalPowerSeries[T] =\n    mixin pow, init\n    var self = self\n    deg.revise(self.len)\n    self.resize(deg)\n    for i in 0..<deg:\n      if not EQUAL(self[i], T(0)):\n        let rev = T(1) / self[i]\n        result = (((self * rev) shr i).log(deg) * T.init(k)).exp() * (self[i].pow(k))\n        if i * k > deg: return initFormalPowerSeries[T](deg)\n        result = (result shl (i * k)).pre(deg)\n        if result.len < deg: result.setlen(deg)\n        return\n    return self\n\n  proc eval*[T](self: FormalPowerSeries[T], x:T):T =\n    var\n      (r, w) = (T(0), T(1))\n    for v in self:\n      r += w * v\n      w *= x\n    return r\n\n  {.push experimental: \"callOperator\".}\n  template `()`*[T](self: FormalPowerSeries[T], x:T):T = self.eval(x)\n  {.pop.}\n\n  proc powMod*[T](self: FormalPowerSeries[T], n:int, M:FormalPowerSeries[T]):auto =\n    assert not EQUAL(M[^1], T(0))\n    let modinv = M.rev().inv()\n    proc getDiv(base:FormalPowerSeries[T]):FormalPowerSeries[T] =\n      var base = base\n      if base.len < M.len:\n        base.setlen(0)\n        return base\n      let n = base.len - M.len + 1\n      return (base.rev().pre(n) * modinv.pre(n)).pre(n).rev(n)\n    var\n      n = n\n      x = self\n    result = initFormalPowerSeries[T](M.len - 1)\n    result[0] = T(1)\n    while n > 0:\n      if (n and 1) > 0:\n        result *= x\n        result -= getDiv(result) * M\n        result = result.pre(M.len - 1)\n      x *= x\n      x -= getDiv(x) * M\n      x = x.pre(M.len - 1)\n      n = n shr 1\n  proc gcdImpl*[T](a, b:FormalPowerSeries[T]):FormalPowerSeries[T] =\n    if a.len < b.len: return gcdImpl(b, a)\n    if b.len == 0: return a\n    let r = a mod b\n    #echo a.len, \" \", b.len, \" \", r.len\n    return gcdImpl(b, r)\n  proc gcd*[T](a, b:FormalPowerSeries[T]):FormalPowerSeries[T] =\n    var (a, b) = (a, b)\n    a.shrink\n    b.shrink\n    return gcdImpl(a, b)\n\n\n\n"
# source: https://github.com/zer0-star/Nim-ACL/tree/master/src/atcoder/extra/math/ntt.nim
ImportExpand "atcoder/extra/math/ntt" <=== "when not declared ATCODER_NTT_HPP:\n  const ATCODER_NTT_HPP* = 1\n  when not declared ATCODER_PARTICULAR_MOD_CONVOLUTION:\n    const ATCODER_PARTICULAR_MOD_CONVOLUTION* = 1\n    when not declared ATCODER_CONVOLUTION_HPP:\n      when not declared ATCODER_CONVOLUTION_HPP:\n        const ATCODER_CONVOLUTION_HPP* = 1\n      \n        import std/math\n        import std/sequtils\n        import std/sugar\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<cstdio>\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..<cnt:\n                if pow_mod_constexpr(g, (m - 1) div divs[i], m) == 1:\n                  ok = false\n                  break\n              if ok: return g\n              g.inc\n          proc primitive_root*[m:static[int]]():auto =\n            primitive_root_constexpr(m)\n        \n          # @param n `n < 2^32`\n          # @param m `1 <= m < 2^32`\n          # @return sum_{i=0}^{n-1} floor((ai + b) / m) (mod 2^64)\n          proc floor_sum_unsigned*(n, m, a, b:uint):uint =\n            result = 0\n            var (n, m, a, b) = (n, m, a, b)\n            while true:\n              if a >= 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        when not declared ATCODER_INTERNAL_BITOP_HPP:\n          const ATCODER_INTERNAL_BITOP_HPP* = 1\n          import std/bitops\n        \n        #ifdef _MSC_VER\n        #include <intrin.h>\n        #endif\n        \n        # @param n `0 <= n`\n        # @return minimum non-negative `x` s.t. `n <= 2**x`\n          proc ceil_pow2*(n:SomeInteger):int =\n            var x = 0\n            while (1.uint shl x) < n.uint: x.inc\n            return x\n        # @param n `1 <= n`\n        # @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`\n          proc bsf*(n:SomeInteger):int =\n            return countTrailingZeroBits(n)\n        \n      \n        type fft_info*[mint:FiniteFieldElem; g, rank2:static[int]] = object\n          root, iroot: array[rank2 + 1, mint]\n          rate2, irate2: array[max(0, rank2 - 2 + 1), mint]\n          rate3, irate3: array[max(0, rank2 - 3 + 1), mint]\n      \n        proc initFFTInfo*[mint:FiniteFieldElem]():auto =\n          const g = primitive_root[mint.mod]()\n          const rank2 = bsf(mint.mod - 1)\n          var root, iroot:array[rank2 + 1, mint]\n          var rate2, irate2: array[max(0, rank2 - 2 + 1), mint]\n          var rate3, irate3: array[max(0, rank2 - 3 + 1), mint]\n          mixin init, inv\n      \n          root[rank2] = mint.init(g).pow((mint.mod - 1) shr rank2)\n          iroot[rank2] = root[rank2].inv()\n          for i in countdown(rank2 - 1, 0):\n            root[i] = root[i + 1] * root[i + 1];\n            iroot[i] = iroot[i + 1] * iroot[i + 1];\n        \n          block:\n            var\n              prod = mint.init(1)\n              iprod = mint.init(1)\n            for i in 0..rank2 - 2:\n              rate2[i] = root[i + 2] * prod\n              irate2[i] = iroot[i + 2] * iprod\n              prod *= iroot[i + 2]\n              iprod *= root[i + 2]\n          block:\n            var\n              prod = mint.init(1)\n              iprod = mint.init(1)\n            for i in 0..rank2 - 3:\n              rate3[i] = root[i + 3] * prod;\n              irate3[i] = iroot[i + 3] * iprod;\n              prod *= iroot[i + 3];\n              iprod *= root[i + 3];\n          return fft_info[mint, g, rank2](root:root, iroot:iroot, rate2:rate2, irate2:irate2, rate3: rate3, irate3:irate3)\n        \n        proc butterfly*[mint:FiniteFieldElem](a:var seq[mint]) =\n          mixin init\n          let n = a.len\n          let h = ceil_pow2(n)\n      \n          const info = initFFTInfo[mint]()\n      \n          var len = 0  # a[i, i+(n>>len), i+2*(n>>len), ..] is transformed\n          while len < h:\n            if h - len == 1:\n              let p = 1 shl (h - len - 1)\n              var rot = mint.init(1)\n              for s in 0..<(1 shl len):\n                var offset = s shl (h - len)\n                for i in 0..<p:\n                  let l = a[i + offset]\n                  let r = a[i + offset + p] * rot\n                  a[i + offset] = l + r\n                  a[i + offset + p] = l - r\n                if s + 1 != (1 shl len):\n                  rot *= info.rate2[bsf(not s.uint)]\n              len.inc\n            else:\n              # 4-base\n              let p = 1 shl (h - len - 2)\n              var\n                rot = mint.init(1)\n                imag = info.root[2]\n              for s in 0..<(1 shl len):\n                let\n                  rot2 = rot * rot\n                  rot3 = rot2 * rot\n                  offset = s shl (h - len)\n                for i in 0..<p:\n                  let\n                    mod2 = (mint.mod() * mint.mod()).uint\n                    a0 = (a[i + offset].val()).uint\n                    a1 = (a[i + offset + p].val() * rot.val()).uint\n                    a2 = (a[i + offset + 2 * p].val() * rot2.val()).uint\n                    a3 = (a[i + offset + 3 * p].val() * rot3.val()).uint\n                    a1na3imag = (mint.init(a1 + mod2 - a3).val() * imag.val()).uint\n                    na2 = mod2 - a2\n                  a[i + offset] = mint.init(a0 + a2 + a1 + a3)\n                  a[i + offset + 1 * p] = mint.init(a0 + a2 + (2.uint * mod2 - (a1 + a3)))\n                  a[i + offset + 2 * p] = mint.init(a0 + na2 + a1na3imag)\n                  a[i + offset + 3 * p] = mint.init(a0 + na2 + (mod2 - a1na3imag))\n                if s + 1 != (1 shl len):\n                  rot *= info.rate3[bsf(not s.uint)]\n              len += 2\n        \n        proc butterfly_inv*[mint:FiniteFieldElem](a:var seq[mint]) =\n          let n = a.len\n          let h = ceilpow2(n)\n          mixin init\n      \n          const info = initFFTInfo[mint]()\n        \n          var len = h;  # a[i, i+(n>>len), i+2*(n>>len), ..] is transformed\n          while len > 0:\n            if len == 1:\n              let p = 1 shl (h - len)\n              var irot = mint.init(1)\n              for s in 0..<(1 shl (len - 1)):\n                let offset = s shl (h - len + 1)\n                for i in 0..<p:\n                  let\n                    l = a[i + offset]\n                    r = a[i + offset + p]\n                  a[i + offset] = l + r\n                  a[i + offset + p] = mint.init((mint.mod() + l.val() - r.val()) * irot.val())\n                if s + 1 != (1 shl (len - 1)):\n                  irot *= info.irate2[bsf(not s.uint)]\n              len.dec\n            else:\n              # 4-base\n              let p = 1 shl (h - len);\n              var irot = mint.init(1)\n              let iimag = info.iroot[2]\n              for s in 0..<(1 shl (len - 2)):\n                let\n                  irot2 = irot * irot\n                  irot3 = irot2 * irot\n                  offset = s shl (h - len + 2)\n                for i in 0..<p:\n                  let\n                    a0 = a[i + offset + 0 * p].val().uint\n                    a1 = a[i + offset + 1 * p].val().uint\n                    a2 = a[i + offset + 2 * p].val().uint\n                    a3 = a[i + offset + 3 * p].val().uint\n                    a2na3iimag = mint.init((mint.mod.uint + a2 - a3) * iimag.val().uint).val().uint\n        \n                  a[i + offset] = mint.init(a0 + a1 + a2 + a3)\n                  a[i + offset + 1 * p] = mint.init((a0 + (mint.mod().uint - a1) + a2na3iimag) * irot.val().uint)\n                  a[i + offset + 2 * p] = mint.init((a0 + a1 + (mint.mod().uint - a2) + (mint.mod().uint - a3)) * irot2.val().uint)\n                  a[i + offset + 3 * p] = mint.init((a0 + (mint.mod().uint - a1) + (mint.mod().uint - a2na3iimag)) * irot3.val().uint)\n                if s + 1 != (1 shl (len - 2)):\n                  irot *= info.irate3[bsf(not s.uint)]\n              len -= 2\n      \n        proc convolution_naive*[mint:FiniteFieldElem](a, b:seq[mint]):seq[mint] =\n          mixin `+=`\n          let (n, m) = (a.len, b.len)\n          result = newSeq[mint](n + m - 1)\n          if n < m:\n            for j in 0..<m:\n              for i in 0..<n:\n                result[i + j] += a[i] * b[j]\n          else:\n            for i in 0..<n:\n              for j in 0..<m:\n                result[i + j] += a[i] * b[j]\n      \n        proc convolution_fft*[mint:FiniteFieldElem](a, b:seq[mint]):seq[mint] =\n          mixin init, inv\n          let\n            (n, m) = (a.len, b.len)\n            z = 1 shl ceil_pow2(n + m - 1)\n          var (a, b) = (a, b)\n          a.setLen(z)\n          butterfly(a)\n          b.setLen(z)\n          butterfly(b)\n          for i in 0..<z:\n            a[i] *= b[i];\n          butterfly_inv(a)\n          a.setLen(n + m - 1)\n          let iz = mint.init(z).inv()\n          for i in 0..<n + m - 1: a[i] *= iz\n          return a\n      \n        proc convolution*[mint:FiniteFieldElem](a, b:seq[mint]):seq[mint] =\n          let (n, m) = (a.len, b.len)\n          if n == 0 or m == 0: return\n          if min(n, m) <= 60: return convolution_naive(a, b)\n          return convolution_fft(a, b)\n      \n        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        \n          proc getBarrett*[T:static[int]](t:typedesc[DynamicModInt[T]]):ptr Barrett =\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        \n        proc convolution*[T:SomeInteger](a, b:seq[T], M:static[uint] = 998244353):seq[T] =\n          let (n, m) = (a.len, b.len)\n          if n == 0 or m == 0: return newSeq[T]()\n        \n          type mint = StaticModInt[M.int]\n          static:\n            assert mint is FiniteFieldElem\n          return convolution(\n            a.map((x:T) => mint.init(x)), \n            b.map((x:T) => mint.init(x))\n          ).map((x:mint) => T(x.val()))\n      \n        proc convolution_ll*(a, b:seq[int]):seq[int] =\n          let (n, m) = (a.len, b.len)\n          if n == 0 or m == 0: return newSeq[int]()\n          const\n            MOD1:uint = 754974721  # 2^24\n            MOD2:uint = 167772161  # 2^25\n            MOD3:uint = 469762049  # 2^26\n            M2M3 = MOD2 * MOD3\n            M1M3 = MOD1 * MOD3\n            M1M2 = MOD1 * MOD2\n            M1M2M3 = MOD1 * MOD2 * MOD3\n      \n            i1 = inv_gcd((MOD2 * MOD3).int, MOD1.int)[1].uint\n            i2 = inv_gcd((MOD1 * MOD3).int, MOD2.int)[1].uint\n            i3 = inv_gcd((MOD1 * MOD2).int, MOD3.int)[1].uint\n          \n          let\n            c1 = convolution(a, b, MOD1)\n            c2 = convolution(a, b, MOD2)\n            c3 = convolution(a, b, MOD3)\n        \n          var c = newSeq[int](n + m - 1)\n          for i in 0..<n + m - 1:\n            var x = 0.uint\n            x += (c1[i].uint * i1) mod MOD1 * M2M3\n            x += (c2[i].uint * i2) mod MOD2 * M1M3\n            x += (c3[i].uint * i3) mod MOD3 * M1M2\n            # B = 2^63, -B <= x, r(real value) < B\n            # (x, x - M, x - 2M, or x - 3M) = r (mod 2B)\n            # r = c1[i] (mod MOD1)\n            # focus on MOD1\n            # r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)\n            # r = x,\n            #   x - M' + (0 or 2B),\n            #   x - 2M' + (0, 2B or 4B),\n            #   x - 3M' + (0, 2B, 4B or 6B) (without mod!)\n            # (r - x) = 0, (0)\n            #       - M' + (0 or 2B), (1)\n            #       -2M' + (0 or 2B or 4B), (2)\n            #       -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)\n            # we checked that\n            #   ((1) mod MOD1) mod 5 = 2\n            #   ((2) mod MOD1) mod 5 = 3\n            #   ((3) mod MOD1) mod 5 = 4\n      #      var diff = c1[i] - floorMod(x.int, MOD1.int)\n            var diff = c1[i] - floorMod(cast[int](x), MOD1.int)\n            if diff < 0: diff += MOD1.int\n            const offset = [0'u, 0'u, M1M2M3, 2'u * M1M2M3, 3'u * M1M2M3]\n            x -= offset[diff mod 5]\n            c[i] = cast[int](x)\n          return c\n      \n      discard\n    import std/sequtils\n    type ParticularModConvolution* = object\n      discard\n    #type ParticularModFFTType*[T:FiniteFieldElem] = seq[T]\n    proc fft*[T:FiniteFieldElem](t:typedesc[ParticularModConvolution], a:seq[T]):seq[T] {.inline.} =\n      result = a\n      butterfly(result)\n    proc inplace_fft*[T:FiniteFieldElem](t:typedesc[ParticularModConvolution], a:var seq[T]) {.inline.} =\n      butterfly(a)\n    proc inplace_partial_dot*[T](t:typedesc[ParticularModConvolution], a:var seq[T], b:seq[T], p:Slice[int]) =\n      for i in p:\n        a[i] *= b[i]\n    proc dot*[T](t:typedesc[ParticularModConvolution], a, b:seq[T]):seq[T] =\n      result = a\n      inplace_partial_dot(t, result, b, 0..<a.len)\n  \n    proc ifft*[T](t:typedesc[ParticularModConvolution], a:seq[T]):seq[T] {.inline.} =\n      mixin init, inv\n      result = a\n      result.butterfly_inv\n      let iz = T.init(a.len).inv()\n      result.applyIt(it * iz)\n    proc inplace_ifft*[T](t:typedesc[ParticularModConvolution], a:var seq[T]) {.inline.} =\n      mixin init, inv\n      a.butterfly_inv\n      let iz = T.init(a.len).inv()\n      a.applyIt(it * iz)\n  \n    proc convolution*[T:FiniteFieldElem](t:typedesc[ParticularModConvolution], a, b:seq[T]):auto {.inline.} = convolution(a, b)\n    proc ntt_doubling*[T](t:typedesc[ParticularModConvolution], a:var seq[T]) =\n      let M = a.len\n      var b = a\n      const fftInfo = initFFTInfo[T]()\n      t.inplace_ifft(b)\n      var\n        r:T = 1\n        zeta:T = T(fftInfo.g).pow((T.getMod() - 1) div (M shl 1))\n      for i in 0 ..< M:\n        b[i] *= r\n        r *= zeta\n      t.inplace_fft(b)\n      a = a & b\n  \n  when not declared ATCODER_ARBITRARY_MOD_CONVOLUTION:\n    const ATCODER_ARBITRARY_MOD_CONVOLUTION* = 1\n    when not declared ATCODER_CONVOLUTION_HPP:\n      discard\n    import std/sequtils\n  \n    type ArbitraryModConvolution* = object\n      discard\n  \n    const\n      m0 = 167772161.uint\n      m1 = 469762049.uint\n      m2 = 754974721.uint\n    type\n      mint0 = StaticModInt[m0.int]\n      mint1 = StaticModInt[m1.int]\n      mint2 = StaticModint[m2.int]\n    type ArbitraryModFFTElem* = (mint0, mint1, mint2)\n    proc setLen*(v:var (seq[mint0], seq[mint1], seq[mint2]), n:int) =\n      v[0].setLen(n)\n      v[1].setLen(n)\n      v[2].setLen(n)\n    \n    proc `*=`(a:var ArbitraryModFFTElem, b:ArbitraryModFFTElem) =\n      a[0] *= b[0];a[1] *= b[1];a[2] *= b[2]\n    proc `-`(a:ArbitraryModFFTElem):auto = (-a[0], -a[1], -a[2])\n  \n    const\n      r01 = mint1.init(m0).inv().val().uint\n      r02 = mint2.init(m0).inv().val().uint\n      r12 = mint2.init(m1).inv().val().uint\n      r02r12 = r02 * r12 mod m2\n  \n    proc fft*[T:ModInt](t:typedesc[ArbitraryModConvolution], a:seq[T]):auto {.inline.} =\n      type F = ParticularModConvolution\n      var\n        v0 = newSeq[mint0](a.len)\n        v1 = newSeq[mint1](a.len)\n        v2 = newSeq[mint2](a.len)\n      for i in 0..<a.len:\n        v0[i] = mint0.init(a[i].val())\n        v1[i] = mint1.init(a[i].val())\n        v2[i] = mint2.init(a[i].val())\n      v0 = F.fft(v0)\n      v1 = F.fft(v1)\n      v2 = F.fft(v2)\n      return (v0,v1,v2)\n    proc inplace_partial_dot*(t:typedesc[ArbitraryModConvolution], a:var (seq[mint0], seq[mint1], seq[mint2]), b:(seq[mint0], seq[mint1], seq[mint2]), p:Slice[int]):auto =\n      for i in p:\n        a[0][i] *= b[0][i]\n        a[1][i] *= b[1][i]\n        a[2][i] *= b[2][i]\n    proc dot*(t:typedesc[ArbitraryModConvolution], a, b:(seq[mint0], seq[mint1], seq[mint2])):auto =\n      result = a\n      t.inplace_partial_dot(result, b, 0..<a[0].len)\n  \n    proc calc_garner[T:ModInt](a0:seq[mint0], a1:seq[mint1], a2:seq[mint2], deg:int):seq[T] =\n      let\n        w1 = m0 mod T.umod\n        w2 = w1 * m1 mod T.umod\n      result = newSeq[T](deg)\n      for i in 0..<deg:\n        let\n          (n0, n1, n2) = (a0[i].val().uint, a1[i].val().uint, a2[i].val().uint)\n          b = (n1 + m1 - n0) * r01 mod m1\n          c = ((n2 + m2 - n0) * r02r12 + (m2 - b) * r12) mod m2\n        result[i] = T.init(n0 + b * w1 + c * w2)\n  \n    proc ifft*[T:ModInt](t:typedesc[ArbitraryModConvolution], a:(seq[mint0], seq[mint1], seq[mint2]), deg = -1):auto {.inline.} =\n      type F = ParticularModConvolution\n      let\n        deg = if deg == -1: a[0].len else: deg\n        a0 = F.ifft(a[0])\n        a1 = F.ifft(a[1])\n        a2 = F.ifft(a[2])\n      return calc_garner[T](a0, a1, a2, deg)\n    proc convolution*[T:ModInt](t:typedesc[ArbitraryModConvolution], a, b:seq[T]):seq[T] {.inline.} =\n      proc f0(x:T):mint0 = mint0.init(x.val())\n      proc f1(x:T):mint1 = mint1.init(x.val())\n      proc f2(x:T):mint2 = mint2.init(x.val())\n      let\n        c0 = convolution(a.map(f0), b.map(f0))\n        c1 = convolution(a.map(f1), b.map(f1))\n        c2 = convolution(a.map(f2), b.map(f2))\n      return calc_garner[T](c0, c1, c2, a.len + b.len - 1)\n  \n  import std/bitops\n\n  template get_fft_type*[T:FiniteFieldElem](self: typedesc[T]):typedesc =\n    when T.isStatic and countTrailingZeroBits(T.mod - 1) >= 20:\n      ParticularModConvolution\n    else:\n      ArbitraryModConvolution\n  proc fft*[T:FiniteFieldElem](a:seq[T]):auto =\n    type fft_type = get_fft_type(T)\n    fft(fft_type, a)\n  proc ifft*(a:auto, T:typedesc[FiniteFieldElem]):auto =\n    type fft_type = get_fft_type(T)\n    ifft[T](fft_type, a)\n  proc dot*(a, b:auto, T:typedesc[FiniteFieldElem]):auto =\n    dot(get_fft_type(T), a, b)\n  proc inplace_partial_dot*(a:var auto, b:auto, p:Slice[int], T:typedesc[FiniteFieldElem]) =\n    inplace_partial_dot(get_fft_type(T), a, b, p)\n  proc multiply*[T:FiniteFieldElem](a, b:seq[T]):seq[T] =\n    convolution(get_fft_type(T), a, b)\n"

# {.checks: off.}
type mint = modint998244353

var n, m = input(int)
var q = newSeq[FormalPowerSeries[mint]]()
for i in 1..m:
    q.add(initFormalPowerSeries[mint](@[mint(1), -mint(i)]))

while q.len > 1:
    var qn = newSeq[FormalPowerSeries[mint]]()
    for i in 0..<(q.len//2):
        qn.add(q[i*2] * q[i*2+1])
    if q.len % 2 == 1:
        qn.add(q[^1])
    swap(q, qn)

var f = -log(q[0], n+1)
debug($q[0])
debug($f)
var ans = mint(0)
for i in 1..n:
    # var ans = f[i] * i
    ans += f[i] * i * mint(m).pow(n-i)
    # debug(ans.val)
print($ans)
0