#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]
use std::cmp::min;
use std::io;
use std::{io::prelude::*, io::*, str};

struct IO {
    buffer: Vec<String>,
    out: BufWriter<Stdout>,
}
impl IO {
    fn new() -> Self {
        Self {
            buffer: vec![],
            out: BufWriter::new(stdout()),
        }
    }
    fn read<T: std::str::FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().expect("Failed parse");
            }
            let mut input = String::new();
            stdin().read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
    fn read_vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read::<T>()).collect()
    }
}

const MOD: u64 = 998244353;

fn fastpow(mut a: u64, mut x: u64) -> u64 {
    let mut r = 1;
    while x != 0 {
        if x & 1 != 0 {
            r = (r * a) % MOD;
        }

        a = (a * a) % MOD;
        x >>= 1;
    }
    r
}

fn modinv(x: u64) -> u64 {
    fastpow(x, MOD - 2)
}

fn solve(io: &mut IO) -> Result<()> {
    let (n, x): (usize, usize) = (io.read(), io.read());
    let mut comb = vec![vec![1; n + 1]; n + 1];
    let mut fact = vec![1; n + 1];

    for i in 1..=n {
        fact[i] = (fact[i - 1] * (i as u64)) % MOD;

        for j in 1..=i {
            let rem = (fact[j] * fact[i - j]) % MOD;
            let rinv = modinv(rem);

            comb[i][j] = (fact[i] * rinv) % MOD;
        }
    }

    let mut dp = vec![vec![0; x + 1]; n + 1];
    dp[0] = vec![1; x + 1];

    for k in 2..=n {
        let mut sum = 0u64;
        for y in 1..=min(k - 1, x) {
            dp[k][y] = (fastpow(y as u64, k as u64) + MOD - sum) % MOD;
            sum = (sum + dp[k][y]) % MOD
        }

        for y in k..=x {
            for i in 0..k {
                let mut a = dp[k - i][y - (k - 1)] * fastpow((k - 1) as u64, i as u64) % MOD;
                a = (a * comb[k][i]) % MOD;

                dp[k][y] = (dp[k][y] + a) % MOD;
            }
        }
    }

    let mut cnt = 0;
    for y in 1..=x {
        cnt = (cnt + dp[n][y]) % MOD;
    }

    writeln!(io.out, "{}", cnt % MOD)
    //Ok(())
}

fn main() -> io::Result<()> {
    let mut io = IO::new();

    //for _ in 0..tc {
    solve(&mut io)
    //}
    //Ok(())
}


use std::io::{self, prelude::*, BufWriter};
use std::str::FromStr;

type M = DynamicModInt;

fn solve<R: BufRead, W: Write>(sc: &mut Scanner<R>, out: &mut W) {
    let n: usize = sc.next();
    let mx: usize = sc.next();
    let comb = Comb::<M>::new(n);

    let mut dp = vec![vec![M::zero(); mx + 1]; n + 1];
    dp[1][1..=mx].iter_mut().for_each(|v| *v = M::one());
    let mut p = vec![vec![M::zero(); n]; n];
    for i in 0..n {
        for j in 0..n {
            p[i][j] = M::from(i).pow(j as u64);
        }
    }
    for i in 1..=n {
        for m in 1..=mx {
            let delta = dp[i][m];
            if delta.0 == 0 {
                continue;
            }
            let mut nm = m + i - 1;
            for k in (0..=n - i).take_while(move |_| nm <= mx) {
                dp[i + k][nm] += delta * comb.choose(i + k, i) * p[i + k - 1][k];
                nm += 1;
            }
        }
    }
    let ans = M::from(mx).pow(n as u64) - dp[n].iter().cloned().sum::<M>();
    writeln!(out, "{}", ans).ok();
}

fn main() {
    M::set_modulus(998244353);
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = BufWriter::new(stdout.lock());

    let tests: usize = 1; // scan.next();
    for _ in 0..tests {
        solve(&mut scan, &mut out);
    }
}

// {{{ Scanner
pub struct Scanner<R> {
    reader: R,
    buffer: Vec<String>,
}

impl<R: BufRead> Scanner<R> {
    pub fn new(reader: R) -> Self {
        Self {
            reader,
            buffer: vec![],
        }
    }

    pub fn next<T: FromStr>(&mut self) -> T {
        loop {
            if let Some(token) = self.buffer.pop() {
                return token.parse().ok().unwrap();
            }
            self.buffer = self
                .next_line()
                .split_ascii_whitespace()
                .rev()
                .map(String::from)
                .collect();
        }
    }

    pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.next()).collect()
    }

    pub fn next_line(&mut self) -> String {
        let mut line = String::new();
        self.reader.read_line(&mut line).unwrap();
        line
    }
}
// }}}
// {{{ DynamicModInt
use std::fmt;
use std::iter::{Product, Sum};
use std::ops::*;

#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
pub struct DynamicModInt(pub i32);

impl Default for DynamicModInt {
    fn default() -> Self {
        DynamicModInt(0)
    }
}

impl fmt::Display for DynamicModInt {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl DynamicModInt {
    pub fn set_modulus(modulus: i32) {
        *Self::modulus_ref() = modulus;
    }

    pub fn modulus() -> i32 {
        *Self::modulus_ref()
    }

    fn modulus_ref() -> &'static mut i32 {
        static mut MODULUS: i32 = 1;
        unsafe { &mut MODULUS }
    }

    pub fn raw(val: i32) -> Self {
        DynamicModInt(val)
    }

    #[inline]
    fn canon(val: i32) -> Self {
        DynamicModInt(if val < 0 { val + Self::modulus() } else { val })
    }

    #[inline]
    pub fn zero() -> Self {
        DynamicModInt(0)
    }

    #[inline]
    pub fn one() -> Self {
        DynamicModInt(1)
    }

    #[inline]
    pub fn two() -> Self {
        DynamicModInt(2)
    }

    pub fn pow(self, n: u64) -> Self {
        let mut n = n;
        let mut res = Self::one();
        let mut a = self;
        while n > 0 {
            if n & 1 == 1 {
                res *= a;
            }
            a *= a;
            n >>= 1;
        }

        res
    }

    pub fn inv(self) -> Self {
        self.pow(Self::modulus() as u64 - 2)
    }
}

macro_rules! from_bigger_int {
    ($($int:ident)*) => {$(
        impl From<$int> for DynamicModInt {
            fn from(val: $int) -> Self {
                Self::canon((val % Self::modulus() as $int) as i32)
            }
        }
    )*};
}
from_bigger_int!(u32 usize i64 u64 i128 u128);

macro_rules! from_smaller_int {
    ($($int: ident)*) => {$(
        impl From<$int> for DynamicModInt {
            fn from(val: $int) -> Self {
                Self::canon(val as i32 % Self::modulus())
            }
        }
    )*}
}
from_smaller_int!(i32 i16 u16 i8 u8);

impl Neg for DynamicModInt {
    type Output = Self;
    fn neg(self) -> Self {
        DynamicModInt(if self.0 == 0 {
            0
        } else {
            Self::modulus() - self.0
        })
    }
}

impl Add for DynamicModInt {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        let s = self.0 + other.0;
        let m = Self::modulus();
        DynamicModInt(if s >= m { s - m } else { s })
    }
}

impl Sub for DynamicModInt {
    type Output = Self;
    fn sub(self, other: Self) -> Self {
        Self::canon(self.0 - other.0)
    }
}

impl Mul for DynamicModInt {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        let mul: u64 = (self.0 as u64 * other.0 as u64) % Self::modulus() as u64;
        DynamicModInt(mul as i32)
    }
}

impl Div for DynamicModInt {
    type Output = Self;
    #[allow(clippy::suspicious_arithmetic_impl)]
    fn div(self, other: Self) -> Self {
        self * other.inv()
    }
}

impl AddAssign for DynamicModInt {
    fn add_assign(&mut self, other: Self) {
        *self = *self + other;
    }
}

impl SubAssign for DynamicModInt {
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other;
    }
}

impl MulAssign for DynamicModInt {
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other;
    }
}

impl DivAssign for DynamicModInt {
    fn div_assign(&mut self, other: Self) {
        *self = *self / other;
    }
}

impl Sum for DynamicModInt {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::zero(), Add::add)
    }
}

impl Product for DynamicModInt {
    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::one(), Mul::mul)
    }
}
// }}}
// {{{ Comb
use std::ops::{Add, Div, Mul};

pub struct Comb<F> {
    fac: Vec<F>,
    inv_fac: Vec<F>,
}

impl<F: Copy + From<usize> + Eq + Add + Mul<Output = F> + Div<Output = F>> Comb<F> {
    pub fn new(maxn: usize) -> Self {
        let one = F::from(1);
        let mut fac = vec![one; maxn + 1];
        for i in 1..=maxn {
            fac[i] = fac[i - 1] * F::from(i);
        }
        let mut inv_fac = vec![one; maxn + 1];
        inv_fac[maxn] = one / fac[maxn];
        assert!(fac[maxn] * inv_fac[maxn] == one);
        for i in (1..maxn).rev() {
            inv_fac[i] = inv_fac[i + 1] * F::from(i + 1);
        }
        Comb { fac, inv_fac }
    }

    pub fn choose(&self, n: usize, k: usize) -> F {
        if k > n {
            F::from(0)
        } else {
            self.fac[n] * self.inv_fac[k] * self.inv_fac[n - k]
        }
    }

    pub fn fac(&self, n: usize) -> F {
        self.fac[n]
    }

    pub fn inv_fac(&self, n: usize) -> F {
        self.inv_fac[n]
    }
}
// }}}
//


/*
    date   : 2021 / 4 / 7
    author : quickn (quickn.tech)
    email  : quickwshell@gmail.com
*/

use std::io::{self, BufWriter, Write};

mod scanner {
    use std::{io, str};
    /* https://github.com/EbTech/rust-algorithms */

    /// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts
    /// **REQUIRES** Rust 1.34 or higher
    pub struct UnsafeScanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: str::SplitAsciiWhitespace<'static>,
    }

    impl<R: io::BufRead> UnsafeScanner<R> {
        pub fn new(reader: R) -> Self {
            Self {
                reader,
                buf_str: Vec::new(),
                buf_iter: "".split_ascii_whitespace(),
            }
        }

        /// This function should be marked unsafe, but noone has time for that in a
        /// programming contest. Use at your own risk!
        pub fn token<T: str::FromStr>(&mut self) -> T {
            loop {
                if let Some(token) = self.buf_iter.next() {
                    return token.parse().ok().expect("Failed parse");
                }
                self.buf_str.clear();
                self.reader
                    .read_until(b'\n', &mut self.buf_str)
                    .expect("Failed read");
                self.buf_iter = unsafe {
                    let slice = str::from_utf8_unchecked(&self.buf_str);
                    std::mem::transmute(slice.split_ascii_whitespace())
                }
            }
        }
    }
}

use std::cmp::{min, max};

fn s2vec(s: String) -> Vec<char> {
    s.chars().collect()
}

const MOD: i64 = 998244353;

fn pow_mod(a: i64, x: i64) -> i64 {
    let mut r = 1;
    let mut a_t = a;
    let mut x_t = x;
    while x_t != 0 {
        if x_t % 2 == 1 {
            r *= a_t;
            r %= MOD;
        }
        a_t *= a_t;
        a_t %= MOD;
        x_t /= 2;
    }
    r
}

const MAX: usize = 501;

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let (mut scan, mut sout) = (
        scanner::UnsafeScanner::new(stdin.lock()),
        BufWriter::new(stdout.lock()),
    );
    let n: usize = scan.token();
    let x: usize = scan.token();
    let mut dp: Vec<Vec<i64>> = vec![vec![0;MAX];n+1];
    let mut binom: Vec<Vec<i64>> = vec![vec![0;MAX+1];MAX+1];
    binom[0][0] = 1;
    for i in 1..=MAX {
        binom[i][0] = 1;
        binom[i][i] = 1;
        for j in 1..i {
            binom[i][j] += binom[i-1][j-1];
            binom[i][j] %= MOD;
            binom[i][j] += binom[i-1][j];
            binom[i][j] %= MOD;
        }
    }
    dp[n][0] = 1;
    for r in (1..=n).rev() {
        for lx in 0..=x {
            for y in 0..=(n-r) {
                if lx >= y+r-1 {
                    let d = max(0, min(x-lx+(y+r-1), y+r-1));
                    dp[r][lx] += (((dp[r+y][lx-(y+r-1)]*binom[y+r][y])%MOD)*pow_mod(d as i64, y as i64))%MOD;
                    dp[r][lx] %= MOD;
                }
            }
        }
    }
    let mut all = pow_mod(x as i64, n as i64);
    for lx in 0..=x {
        all -= (dp[1][lx]*((x - lx) as i64))%MOD;
        all += MOD;
        all %= MOD;
    }
    writeln!(sout, "{}", all).ok();
}


//spnauti-rusT {{{
#[allow(unused_imports)]use std::{io::*,collections::*,fmt::Debug,str::{self,*},cmp::*,ops::{self,*},iter::{self,*}};
macro_rules!l{
	($($v:ident),+:$t:ty=$e:expr)=>{$(let$v:$t=$e;)+};(mut $($v:ident),+ =$e:expr)=>{$(let mut$v=$e;)+};
	(mut $($v:ident),+:$t:ty=$e:expr)=>{$(let mut$v:$t=$e;)+};($($v:ident),+ =$e:expr)=>{$(let$v=$e;)+};}
macro_rules!v{
	($(:$t:ty)?=$e:expr)=>{$e$(as$t)?};([$d:expr]$(:$t:ty)?)=>{Vec::$(<$t>::)?with_capacity($d)};
	([]$(:$t:ty)?)=>{Vec::$(<$t>::)?new()};([$d:expr]$($s:tt)+)=>{vec![v!($($s)+);$d]};}
fn rio()->(Reader,BufWriter<Stdout>){(Reader::new(),BufWriter::new(stdout()))}
struct Reader{buf:Vec<u8>,pos:usize,x:*mut Stdin,q:StdinLock<'static>}//'
#[allow(dead_code)]impl Reader{
	fn new()->Self{let x=Box::into_raw(Box::new(stdin()));let q=unsafe{&*x}.lock();Self{x,q,buf:v!([]),pos:0}}
	fn next_line(&mut self)->bool{self.buf.clear();self.pos=0;self.q.read_until(b'\n',&mut self.buf).unwrap_or(0)>0}
	fn byte(&mut self)->Option<u8>{
		if self.pos==self.buf.len(){if!self.next_line(){return None;}}self.pos+=1;Some(self.buf[self.pos-1])}
	fn vb(&mut self)->Vec<u8>{let mut s=v!([10]);let mut f=false;while let Some(c)=self.byte(){
		if!c.is_ascii_whitespace(){s.push(c);f=true;}else if f{break;}}s}
	fn p<T:FromStr>(&mut self)->T where T::Err:Debug{let w=self.vb();str::from_utf8(w.as_ref()).unwrap().parse::<T>().unwrap()}
	fn u(&mut self) ->  usize { self.p() }
}impl Drop for Reader{fn drop(&mut self){unsafe{Box::from_raw(self.x)};}}
//----------}}}

// Field (mod prime) {{{
mod field {
	use std::ops::*;
	#[allow(dead_code)] pub const Z0: Field = Field(0);
	#[allow(dead_code)] pub const Z1: Field = Field(1);
	const P5: i32 = 998_244_353;
	const P6: i64 = P5 as i64;
	#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Default)] pub struct Field(pub i32);
	#[allow(dead_code)] impl Field {
		pub fn new<T: Into<i64>>(a: T) -> Self { Self(Self::cv(a)) }
		pub unsafe fn new_unchecked(a: i32) -> Self { Self(a) }
		fn hi(mut a: i32) -> i32 { if a >= P5 { a -= P5; } a }
		fn lo(mut a: i32) -> i32 { if a < 0 { a += P5; } a }
		fn cv<T: Into<i64>>(a: T) -> i32 { Self::lo((a.into() % P6) as i32) }
		pub fn inv(self) -> Self { self.pow(P5-2) }
		pub fn pow<T: Into<i64>>(self, b: T) -> Self {
			let b = b.into(); if b == 0 { Self(1) } else {
				let mut res = self.pow(b/2); res *= res; if b % 2 == 1 {res *= self;} res
			}
		}
	}
	impl Add for Field { type Output = Self; fn add(self, a: Self) -> Self::Output { Self(Self::hi(self.0 + a.0)) }}
	impl Sub for Field { type Output = Self; fn sub(self, a: Self) -> Self::Output { Self(Self::lo(self.0 - a.0)) }}
	impl Mul for Field { type Output = Self; fn mul(self, a: Self) -> Self::Output { Self(Self::cv(self.0 as i64 * a.0 as i64)) }}
	impl Div for Field { type Output = Self; fn div(self, a: Self) -> Self::Output { self * a.inv() }}
	impl Neg for Field { type Output = Self; fn neg(self) -> Self::Output { Self(Self::lo(-self.0)) }}
	impl AddAssign for Field { fn add_assign(&mut self, a: Self) { *self = *self + a; } }
	impl SubAssign for Field { fn sub_assign(&mut self, a: Self) { *self = *self - a; } }
	impl MulAssign for Field { fn mul_assign(&mut self, a: Self) { *self = *self * a; } }
	impl DivAssign for Field { fn div_assign(&mut self, a: Self) { *self = *self / a; } }
	use std::fmt::{Display, Formatter, Result};
	impl Display for Field { fn fmt(&self, f: &mut Formatter) -> Result { write!(f, "{}", self.0) } }
}
#[allow(unused_imports)] use field::{Field, Field as Z, Z0, Z1};
//}}}

fn main() {
	let (mut rin,mut rout) = rio();
	const N: usize = 1000;

	l!(mut f,fi = v!([N+1] = Z1));
	for i in 2..N {
		f[i] = f[i-1] * Z::new(i as i32);
		fi[i] = f[i].inv();
	}
	let cnr = |n,r| -> Z {
		if r > n {
			Z0
		} else {
			f[n] * fi[n-r] * fi[r]
		}
	};

	l!(n,x = rin.u());
	let mut dp = v!([x+1][n+1] = Z0);
	let mut s = Z0;
	for i in 1..=x {
		dp[i][1] = Z1;
		for j in 2..=n.min(i) {
			let mut res = Z0;
			for k in 1..=j {
				res += dp[i-j+1][k] * Z::new((j-1) as i32).pow((j-k) as i32) * cnr(j-1,k-1);
			}
			dp[i][j] = res;
		}
		s += dp[i][n];
	}
	s *= Z::new(n as i32);
	let ans = Z::new(x as i32).pow(n as i32) - s;
	writeln!(rout, "{}", ans).unwrap();
}


#[allow(unused_imports)]
use std::io::{stdout, BufWriter, Write};
fn main() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());

    inputv! {
        t:usize,
    }
    ModInt::set_modulus(1_000_000_007);
    let mut dpf = DpFactorial::new();

    for _ in 0..t {
        inputv! {
            n:usize,k:usize,
        }
        let mut ans = ModInt::new(0);
        for q in 0..=k {
            ans += dpf.get_combination(k, q) * ModInt::new(n - 1).pow(q as u64);
        }
        writeln!(out, "{}", ans).unwrap();
    }
}

//https://github.com/rust-lang-ja/ac-library-rs
//https://github.com/manta1130/competitive-template-rs

use dpfactorial::*;
use modint::*;

pub mod dpfactorial {
    use crate::modint::*;

    #[derive(Default)]
    pub struct DpFactorial {
        normal: Vec<ModInt>,
        inv: Vec<ModInt>,
    }
    impl DpFactorial {
        #[allow(dead_code)]
        pub fn new() -> DpFactorial {
            let mut obj = DpFactorial {
                normal: Vec::new(),
                inv: Vec::new(),
            };
            obj.normal.push(ModInt::new(1));
            obj.inv.push(ModInt::new(1));
            obj
        }

        #[allow(dead_code)]
        pub fn get_factorial(&mut self, n: usize) -> ModInt {
            if n < self.normal.len() {
                return self.normal[n];
            }
            for z in self.normal.len()..n as usize + 1 {
                let buf = ModInt::new(z);
                let buf = buf * self.normal[z - 1];

                self.normal.push(buf);
            }
            self.normal[n]
        }

        #[allow(dead_code)]
        pub fn get_factorial_inv(&mut self, n: usize) -> ModInt {
            if n < self.inv.len() {
                return self.inv[n];
            }
            for z in self.inv.len()..n + 1 {
                let mut buf = ModInt::new(z);
                buf = buf.inv();
                let buf = buf * self.inv[z - 1];
                self.inv.push(buf);
            }
            self.inv[n]
        }

        #[allow(dead_code)]
        pub fn get_combination(&mut self, n: usize, r: usize) -> ModInt {
            if n < r {
                return ModInt::new(0);
            }
            self.get_factorial(n) * self.get_factorial_inv(n - r) * self.get_factorial_inv(r)
        }

        #[allow(dead_code)]
        pub fn get_permutation(&mut self, n: usize, r: usize) -> ModInt {
            if n < r {
                return ModInt::new(0);
            }
            self.get_factorial(n) * self.get_factorial_inv(n - r)
        }
    }
}
pub mod internal_math {
    #![allow(dead_code)]
    use std::mem::swap;

    /* const */
    pub(crate) fn safe_mod(mut x: i64, m: i64) -> i64 {
        x %= m;
        if x < 0 {
            x += m;
        }
        x
    }

    pub(crate) struct Barrett {
        pub(crate) _m: u32,
        pub(crate) im: u64,
    }

    impl Barrett {
        pub(crate) fn new(m: u32) -> Barrett {
            Barrett {
                _m: m,
                im: (-1i64 as u64 / m as u64).wrapping_add(1),
            }
        }

        pub(crate) fn umod(&self) -> u32 {
            self._m
        }

        #[allow(clippy::many_single_char_names)]
        pub(crate) fn mul(&self, a: u32, b: u32) -> u32 {
            mul_mod(a, b, self._m, self.im)
        }
    }

    #[allow(clippy::many_single_char_names)]
    pub(crate) fn mul_mod(a: u32, b: u32, m: u32, im: u64) -> u32 {
        let mut z = a as u64;
        z *= b as u64;
        let x = (((z as u128) * (im as u128)) >> 64) as u64;
        let mut v = z.wrapping_sub(x.wrapping_mul(m as u64)) as u32;
        if m <= v {
            v = v.wrapping_add(m);
        }
        v
    }

    /* const */
    #[allow(clippy::many_single_char_names)]
    pub(crate) fn pow_mod(x: i64, mut n: i64, m: i32) -> i64 {
        if m == 1 {
            return 0;
        }
        let _m = m as u32;
        let mut r: u64 = 1;
        let mut y: u64 = safe_mod(x, m as i64) as u64;
        while n != 0 {
            if (n & 1) > 0 {
                r = (r * y) % (_m as u64);
            }
            y = (y * y) % (_m as u64);
            n >>= 1;
        }
        r as i64
    }

    /* const */
    pub(crate) fn is_prime(n: i32) -> bool {
        let n = n as i64;
        match n {
            _ if n <= 1 => return false,
            2 | 7 | 61 => return true,
            _ if n % 2 == 0 => return false,
            _ => {}
        }
        let mut d = n - 1;
        while d % 2 == 0 {
            d /= 2;
        }
        for &a in &[2, 7, 61] {
            let mut t = d;
            let mut y = pow_mod(a, t, n as i32);
            while t != n - 1 && y != 1 && y != n - 1 {
                y = y * y % n;
                t <<= 1;
            }
            if y != n - 1 && t % 2 == 0 {
                return false;
            }
        }
        true
    }

    /* const */
    #[allow(clippy::many_single_char_names)]
    pub(crate) fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
        let a = safe_mod(a, b);
        if a == 0 {
            return (b, 0);
        }

        let mut s = b;
        let mut t = a;
        let mut m0 = 0;
        let mut m1 = 1;

        while t != 0 {
            let u = s / t;
            s -= t * u;
            m0 -= m1 * u; // |m1 * u| <= |m1| * s <= b

            swap(&mut s, &mut t);
            swap(&mut m0, &mut m1);
        }
        if m0 < 0 {
            m0 += b / s;
        }
        (s, m0)
    }

    /* const */
    pub(crate) fn primitive_root(m: i32) -> i32 {
        match m {
            2 => return 1,
            167_772_161 => return 3,
            469_762_049 => return 3,
            754_974_721 => return 11,
            998_244_353 => return 3,
            _ => {}
        }

        let mut divs = [0; 20];
        divs[0] = 2;
        let mut cnt = 1;
        let mut x = (m - 1) / 2;
        while x % 2 == 0 {
            x /= 2;
        }
        for i in (3..std::i32::MAX).step_by(2) {
            if i as i64 * i as i64 > x as i64 {
                break;
            }
            if x % i == 0 {
                divs[cnt] = i;
                cnt += 1;
                while x % i == 0 {
                    x /= i;
                }
            }
        }
        if x > 1 {
            divs[cnt] = x;
            cnt += 1;
        }
        let mut g = 2;
        loop {
            if (0..cnt).all(|i| pow_mod(g, ((m - 1) / divs[i]) as i64, m) != 1) {
                break g as i32;
            }
            g += 1;
        }
    }
}
pub mod modint {

    use crate::internal_math;
    use std::{
        cell::RefCell,
        convert::{Infallible, TryInto as _},
        fmt,
        hash::{Hash, Hasher},
        iter::{Product, Sum},
        marker::PhantomData,
        ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
        str::FromStr,
        sync::atomic::{self, AtomicU32, AtomicU64},
        thread::LocalKey,
    };

    pub type ModInt1000000007 = StaticModInt<Mod1000000007>;
    pub type ModInt998244353 = StaticModInt<Mod998244353>;
    pub type ModInt = DynamicModInt<DefaultId>;

    #[derive(Copy, Clone, Eq, PartialEq)]
    #[repr(transparent)]
    pub struct StaticModInt<M> {
        val: u32,
        phantom: PhantomData<fn() -> M>,
    }

    impl<M: Modulus> StaticModInt<M> {
        #[inline(always)]
        pub fn modulus() -> u32 {
            M::VALUE
        }

        #[inline]
        pub fn new<T: RemEuclidU32>(val: T) -> Self {
            Self::raw(val.rem_euclid_u32(M::VALUE))
        }

        #[inline]
        pub fn raw(val: u32) -> Self {
            Self {
                val,
                phantom: PhantomData,
            }
        }

        #[inline]
        pub fn val(self) -> u32 {
            self.val
        }

        #[inline]
        pub fn pow(self, n: u64) -> Self {
            <Self as ModIntBase>::pow(self, n)
        }

        #[inline]
        pub fn inv(self) -> Self {
            if M::HINT_VALUE_IS_PRIME {
                if self.val() == 0 {
                    panic!("attempt to divide by zero");
                }
                debug_assert!(
                    internal_math::is_prime(M::VALUE.try_into().unwrap()),
                    "{} is not a prime number",
                    M::VALUE,
                );
                self.pow((M::VALUE - 2).into())
            } else {
                Self::inv_for_non_prime_modulus(self)
            }
        }
    }

    impl<M: Modulus> ModIntBase for StaticModInt<M> {
        #[inline(always)]
        fn modulus() -> u32 {
            Self::modulus()
        }

        #[inline]
        fn raw(val: u32) -> Self {
            Self::raw(val)
        }

        #[inline]
        fn val(self) -> u32 {
            self.val()
        }

        #[inline]
        fn inv(self) -> Self {
            self.inv()
        }
    }

    pub trait Modulus: 'static + Copy + Eq {
        const VALUE: u32;
        const HINT_VALUE_IS_PRIME: bool;

        fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>>;
    }

    #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
    pub enum Mod1000000007 {}

    impl Modulus for Mod1000000007 {
        const VALUE: u32 = 1_000_000_007;
        const HINT_VALUE_IS_PRIME: bool = true;

        fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>> {
            thread_local! {
                static BUTTERFLY_CACHE: RefCell<Option<ButterflyCache<Mod1000000007>>> = RefCell::default();
            }
            &BUTTERFLY_CACHE
        }
    }

    #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
    pub enum Mod998244353 {}

    impl Modulus for Mod998244353 {
        const VALUE: u32 = 998_244_353;
        const HINT_VALUE_IS_PRIME: bool = true;

        fn butterfly_cache() -> &'static LocalKey<RefCell<Option<ButterflyCache<Self>>>> {
            thread_local! {
                static BUTTERFLY_CACHE: RefCell<Option<ButterflyCache<Mod998244353>>> = RefCell::default();
            }
            &BUTTERFLY_CACHE
        }
    }

    pub struct ButterflyCache<M> {
        pub(crate) sum_e: Vec<StaticModInt<M>>,
        pub(crate) sum_ie: Vec<StaticModInt<M>>,
    }

    #[derive(Copy, Clone, Eq, PartialEq)]
    #[repr(transparent)]
    pub struct DynamicModInt<I> {
        val: u32,
        phantom: PhantomData<fn() -> I>,
    }

    impl<I: Id> DynamicModInt<I> {
        #[inline]
        pub fn modulus() -> u32 {
            I::companion_barrett().umod()
        }

        #[inline]
        pub fn set_modulus(modulus: u32) {
            if modulus == 0 {
                panic!("the modulus must not be 0");
            }
            I::companion_barrett().update(modulus);
        }

        #[inline]
        pub fn new<T: RemEuclidU32>(val: T) -> Self {
            <Self as ModIntBase>::new(val)
        }

        #[inline]
        pub fn raw(val: u32) -> Self {
            Self {
                val,
                phantom: PhantomData,
            }
        }

        #[inline]
        pub fn val(self) -> u32 {
            self.val
        }

        #[inline]
        pub fn pow(self, n: u64) -> Self {
            <Self as ModIntBase>::pow(self, n)
        }

        #[inline]
        pub fn inv(self) -> Self {
            Self::inv_for_non_prime_modulus(self)
        }
    }

    impl<I: Id> ModIntBase for DynamicModInt<I> {
        #[inline]
        fn modulus() -> u32 {
            Self::modulus()
        }

        #[inline]
        fn raw(val: u32) -> Self {
            Self::raw(val)
        }

        #[inline]
        fn val(self) -> u32 {
            self.val()
        }

        #[inline]
        fn inv(self) -> Self {
            self.inv()
        }
    }

    pub trait Id: 'static + Copy + Eq {
        fn companion_barrett() -> &'static Barrett;
    }

    #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
    pub enum DefaultId {}

    impl Id for DefaultId {
        fn companion_barrett() -> &'static Barrett {
            static BARRETT: Barrett = Barrett::default();
            &BARRETT
        }
    }

    pub struct Barrett {
        m: AtomicU32,
        im: AtomicU64,
    }

    impl Barrett {
        #[inline]
        pub const fn new(m: u32) -> Self {
            Self {
                m: AtomicU32::new(m),
                im: AtomicU64::new((-1i64 as u64 / m as u64).wrapping_add(1)),
            }
        }

        #[inline]
        const fn default() -> Self {
            Self::new(998_244_353)
        }

        #[inline]
        fn update(&self, m: u32) {
            let im = (-1i64 as u64 / m as u64).wrapping_add(1);
            self.m.store(m, atomic::Ordering::SeqCst);
            self.im.store(im, atomic::Ordering::SeqCst);
        }

        #[inline]
        fn umod(&self) -> u32 {
            self.m.load(atomic::Ordering::SeqCst)
        }

        #[inline]
        fn mul(&self, a: u32, b: u32) -> u32 {
            let m = self.m.load(atomic::Ordering::SeqCst);
            let im = self.im.load(atomic::Ordering::SeqCst);
            internal_math::mul_mod(a, b, m, im)
        }
    }

    impl Default for Barrett {
        #[inline]
        fn default() -> Self {
            Self::default()
        }
    }

    pub trait ModIntBase:
        Default
        + FromStr
        + From<i8>
        + From<i16>
        + From<i32>
        + From<i64>
        + From<i128>
        + From<isize>
        + From<u8>
        + From<u16>
        + From<u32>
        + From<u64>
        + From<u128>
        + From<usize>
        + Copy
        + Eq
        + Hash
        + fmt::Display
        + fmt::Debug
        + Neg<Output = Self>
        + Add<Output = Self>
        + Sub<Output = Self>
        + Mul<Output = Self>
        + Div<Output = Self>
        + AddAssign
        + SubAssign
        + MulAssign
        + DivAssign
    {
        fn modulus() -> u32;

        fn raw(val: u32) -> Self;

        fn val(self) -> u32;

        fn inv(self) -> Self;

        #[inline]
        fn new<T: RemEuclidU32>(val: T) -> Self {
            Self::raw(val.rem_euclid_u32(Self::modulus()))
        }

        #[inline]
        fn pow(self, mut n: u64) -> Self {
            let mut x = self;
            let mut r = Self::raw(1);
            while n > 0 {
                if n & 1 == 1 {
                    r *= x;
                }
                x *= x;
                n >>= 1;
            }
            r
        }
    }

    pub trait RemEuclidU32 {
        fn rem_euclid_u32(self, modulus: u32) -> u32;
    }

    macro_rules! impl_rem_euclid_u32_for_small_signed {
    ($($ty:tt),*) => {
        $(
            impl RemEuclidU32 for $ty {
                #[inline]
                fn rem_euclid_u32(self, modulus: u32) -> u32 {
                    (self as i64).rem_euclid(i64::from(modulus)) as _
                }
            }
        )*
    }
}

    impl_rem_euclid_u32_for_small_signed!(i8, i16, i32, i64, isize);

    impl RemEuclidU32 for i128 {
        #[inline]
        fn rem_euclid_u32(self, modulus: u32) -> u32 {
            self.rem_euclid(i128::from(modulus)) as _
        }
    }

    macro_rules! impl_rem_euclid_u32_for_small_unsigned {
    ($($ty:tt),*) => {
        $(
            impl RemEuclidU32 for $ty {
                #[inline]
                fn rem_euclid_u32(self, modulus: u32) -> u32 {
                    self as u32 % modulus
                }
            }
        )*
    }
}

    macro_rules! impl_rem_euclid_u32_for_large_unsigned {
    ($($ty:tt),*) => {
        $(
            impl RemEuclidU32 for $ty {
                #[inline]
                fn rem_euclid_u32(self, modulus: u32) -> u32 {
                    (self % (modulus as $ty)) as _
                }
            }
        )*
    }
}

    impl_rem_euclid_u32_for_small_unsigned!(u8, u16, u32);
    impl_rem_euclid_u32_for_large_unsigned!(u64, u128);

    #[cfg(target_pointer_width = "32")]
    impl_rem_euclid_u32_for_small_unsigned!(usize);

    #[cfg(target_pointer_width = "64")]
    impl_rem_euclid_u32_for_large_unsigned!(usize);

    trait InternalImplementations: ModIntBase {
        #[inline]
        fn inv_for_non_prime_modulus(this: Self) -> Self {
            let (gcd, x) = internal_math::inv_gcd(this.val().into(), Self::modulus().into());
            if gcd != 1 {
                panic!("the multiplicative inverse does not exist");
            }
            Self::new(x)
        }

        #[inline]
        fn default_impl() -> Self {
            Self::raw(0)
        }

        #[inline]
        fn from_str_impl(s: &str) -> Result<Self, Infallible> {
            Ok(s.parse::<i64>()
                .map(Self::new)
                .unwrap_or_else(|_| todo!("parsing as an arbitrary precision integer?")))
        }

        #[inline]
        fn hash_impl(this: &Self, state: &mut impl Hasher) {
            this.val().hash(state)
        }

        #[inline]
        fn display_impl(this: &Self, f: &mut fmt::Formatter) -> fmt::Result {
            fmt::Display::fmt(&this.val(), f)
        }

        #[inline]
        fn debug_impl(this: &Self, f: &mut fmt::Formatter) -> fmt::Result {
            fmt::Debug::fmt(&this.val(), f)
        }

        #[inline]
        fn neg_impl(this: Self) -> Self {
            Self::sub_impl(Self::raw(0), this)
        }

        #[inline]
        fn add_impl(lhs: Self, rhs: Self) -> Self {
            let modulus = Self::modulus();
            let mut val = lhs.val() + rhs.val();
            if val >= modulus {
                val -= modulus;
            }
            Self::raw(val)
        }

        #[inline]
        fn sub_impl(lhs: Self, rhs: Self) -> Self {
            let modulus = Self::modulus();
            let mut val = lhs.val().wrapping_sub(rhs.val());
            if val >= modulus {
                val = val.wrapping_add(modulus)
            }
            Self::raw(val)
        }

        fn mul_impl(lhs: Self, rhs: Self) -> Self;

        #[inline]
        fn div_impl(lhs: Self, rhs: Self) -> Self {
            Self::mul_impl(lhs, rhs.inv())
        }
    }

    impl<M: Modulus> InternalImplementations for StaticModInt<M> {
        #[inline]
        fn mul_impl(lhs: Self, rhs: Self) -> Self {
            Self::raw((u64::from(lhs.val()) * u64::from(rhs.val()) % u64::from(M::VALUE)) as u32)
        }
    }

    impl<I: Id> InternalImplementations for DynamicModInt<I> {
        #[inline]
        fn mul_impl(lhs: Self, rhs: Self) -> Self {
            Self::raw(I::companion_barrett().mul(lhs.val, rhs.val))
        }
    }

    macro_rules! impl_basic_traits {
    () => {};
    (impl <$generic_param:ident : $generic_param_bound:tt> _ for $self:ty; $($rest:tt)*) => {
        impl <$generic_param: $generic_param_bound> Default for $self {
            #[inline]
            fn default() -> Self {
                Self::default_impl()
            }
        }

        impl <$generic_param: $generic_param_bound> FromStr for $self {
            type Err = Infallible;

            #[inline]
            fn from_str(s: &str) -> Result<Self, Infallible> {
                Self::from_str_impl(s)
            }
        }

        impl<$generic_param: $generic_param_bound, V: RemEuclidU32> From<V> for $self {
            #[inline]
            fn from(from: V) -> Self {
                Self::new(from)
            }
        }

        #[allow(clippy::derive_hash_xor_eq)]
        impl<$generic_param: $generic_param_bound> Hash for $self {
            #[inline]
            fn hash<H: Hasher>(&self, state: &mut H) {
                Self::hash_impl(self, state)
            }
        }

        impl<$generic_param: $generic_param_bound> fmt::Display for $self {
            #[inline]
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                Self::display_impl(self, f)
            }
        }

        impl<$generic_param: $generic_param_bound> fmt::Debug for $self {
            #[inline]
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                Self::debug_impl(self, f)
            }
        }

        impl<$generic_param: $generic_param_bound> Neg for $self {
            type Output = $self;

            #[inline]
            fn neg(self) -> $self {
                Self::neg_impl(self)
            }
        }

        impl<$generic_param: $generic_param_bound> Neg for &'_ $self {
            type Output = $self;

            #[inline]
            fn neg(self) -> $self {
                <$self>::neg_impl(*self)
            }
        }

        impl_basic_traits!($($rest)*);
    };
}

    impl_basic_traits! {
        impl <M: Modulus> _ for StaticModInt<M> ;
        impl <I: Id     > _ for DynamicModInt<I>;
    }

    macro_rules! impl_bin_ops {
    () => {};
    (for<$($generic_param:ident : $generic_param_bound:tt),*> <$lhs_ty:ty> ~ <$rhs_ty:ty> -> $output:ty { { $lhs_body:expr } ~ { $rhs_body:expr } } $($rest:tt)*) => {
        impl <$($generic_param: $generic_param_bound),*> Add<$rhs_ty> for $lhs_ty {
            type Output = $output;

            #[inline]
            fn add(self, rhs: $rhs_ty) -> $output {
                <$output>::add_impl(apply($lhs_body, self), apply($rhs_body, rhs))
            }
        }

        impl <$($generic_param: $generic_param_bound),*> Sub<$rhs_ty> for $lhs_ty {
            type Output = $output;

            #[inline]
            fn sub(self, rhs: $rhs_ty) -> $output {
                <$output>::sub_impl(apply($lhs_body, self), apply($rhs_body, rhs))
            }
        }

        impl <$($generic_param: $generic_param_bound),*> Mul<$rhs_ty> for $lhs_ty {
            type Output = $output;

            #[inline]
            fn mul(self, rhs: $rhs_ty) -> $output {
                <$output>::mul_impl(apply($lhs_body, self), apply($rhs_body, rhs))
            }
        }

        impl <$($generic_param: $generic_param_bound),*> Div<$rhs_ty> for $lhs_ty {
            type Output = $output;

            #[inline]
            fn div(self, rhs: $rhs_ty) -> $output {
                <$output>::div_impl(apply($lhs_body, self), apply($rhs_body, rhs))
            }
        }

        impl_bin_ops!($($rest)*);
    };
}

    macro_rules! impl_assign_ops {
    () => {};
    (for<$($generic_param:ident : $generic_param_bound:tt),*> <$lhs_ty:ty> ~= <$rhs_ty:ty> { _ ~= { $rhs_body:expr } } $($rest:tt)*) => {
        impl <$($generic_param: $generic_param_bound),*> AddAssign<$rhs_ty> for $lhs_ty {
            #[inline]
            fn add_assign(&mut self, rhs: $rhs_ty) {
                *self = *self + apply($rhs_body, rhs);
            }
        }

        impl <$($generic_param: $generic_param_bound),*> SubAssign<$rhs_ty> for $lhs_ty {
            #[inline]
            fn sub_assign(&mut self, rhs: $rhs_ty) {
                *self = *self - apply($rhs_body, rhs);
            }
        }

        impl <$($generic_param: $generic_param_bound),*> MulAssign<$rhs_ty> for $lhs_ty {
            #[inline]
            fn mul_assign(&mut self, rhs: $rhs_ty) {
                *self = *self * apply($rhs_body, rhs);
            }
        }

        impl <$($generic_param: $generic_param_bound),*> DivAssign<$rhs_ty> for $lhs_ty {
            #[inline]
            fn div_assign(&mut self, rhs: $rhs_ty) {
                *self = *self / apply($rhs_body, rhs);
            }
        }

        impl_assign_ops!($($rest)*);
    };
}

    #[inline]
    fn apply<F: FnOnce(X) -> O, X, O>(f: F, x: X) -> O {
        f(x)
    }

    impl_bin_ops! {
        for<M: Modulus> <StaticModInt<M>     > ~ <StaticModInt<M>     > -> StaticModInt<M>  { { |x| x  } ~ { |x| x  } }
        for<M: Modulus> <StaticModInt<M>     > ~ <&'_ StaticModInt<M> > -> StaticModInt<M>  { { |x| x  } ~ { |&x| x } }
        for<M: Modulus> <&'_ StaticModInt<M> > ~ <StaticModInt<M>     > -> StaticModInt<M>  { { |&x| x } ~ { |x| x  } }
        for<M: Modulus> <&'_ StaticModInt<M> > ~ <&'_ StaticModInt<M> > -> StaticModInt<M>  { { |&x| x } ~ { |&x| x } }
        for<I: Id     > <DynamicModInt<I>    > ~ <DynamicModInt<I>    > -> DynamicModInt<I> { { |x| x  } ~ { |x| x  } }
        for<I: Id     > <DynamicModInt<I>    > ~ <&'_ DynamicModInt<I>> -> DynamicModInt<I> { { |x| x  } ~ { |&x| x } }
        for<I: Id     > <&'_ DynamicModInt<I>> ~ <DynamicModInt<I>    > -> DynamicModInt<I> { { |&x| x } ~ { |x| x  } }
        for<I: Id     > <&'_ DynamicModInt<I>> ~ <&'_ DynamicModInt<I>> -> DynamicModInt<I> { { |&x| x } ~ { |&x| x } }

        for<M: Modulus, T: RemEuclidU32> <StaticModInt<M>     > ~ <T> -> StaticModInt<M>  { { |x| x  } ~ { StaticModInt::<M>::new } }
        for<I: Id     , T: RemEuclidU32> <DynamicModInt<I>    > ~ <T> -> DynamicModInt<I> { { |x| x  } ~ { DynamicModInt::<I>::new } }
    }

    impl_assign_ops! {
        for<M: Modulus> <StaticModInt<M> > ~= <StaticModInt<M>     > { _ ~= { |x| x  } }
        for<M: Modulus> <StaticModInt<M> > ~= <&'_ StaticModInt<M> > { _ ~= { |&x| x } }
        for<I: Id     > <DynamicModInt<I>> ~= <DynamicModInt<I>    > { _ ~= { |x| x  } }
        for<I: Id     > <DynamicModInt<I>> ~= <&'_ DynamicModInt<I>> { _ ~= { |&x| x } }

        for<M: Modulus, T: RemEuclidU32> <StaticModInt<M> > ~= <T> { _ ~= { StaticModInt::<M>::new } }
        for<I: Id,      T: RemEuclidU32> <DynamicModInt<I>> ~= <T> { _ ~= { DynamicModInt::<I>::new } }
    }

    macro_rules! impl_folding {
    () => {};
    (impl<$generic_param:ident : $generic_param_bound:tt> $trait:ident<_> for $self:ty { fn $method:ident(_) -> _ { _($unit:expr, $op:expr) } } $($rest:tt)*) => {
        impl<$generic_param: $generic_param_bound> $trait<Self> for $self {
            #[inline]
            fn $method<S>(iter: S) -> Self
            where
                S: Iterator<Item = Self>,
            {
                iter.fold($unit, $op)
            }
        }

        impl<'a, $generic_param: $generic_param_bound> $trait<&'a Self> for $self {
            #[inline]
            fn $method<S>(iter: S) -> Self
            where
                S: Iterator<Item = &'a Self>,
            {
                iter.fold($unit, $op)
            }
        }

        impl_folding!($($rest)*);
    };
}

    impl_folding! {
        impl<M: Modulus> Sum<_>     for StaticModInt<M>  { fn sum(_)     -> _ { _(Self::raw(0), Add::add) } }
        impl<M: Modulus> Product<_> for StaticModInt<M>  { fn product(_) -> _ { _(Self::raw(1), Mul::mul) } }
        impl<I: Id     > Sum<_>     for DynamicModInt<I> { fn sum(_)     -> _ { _(Self::raw(0), Add::add) } }
        impl<I: Id     > Product<_> for DynamicModInt<I> { fn product(_) -> _ { _(Self::raw(1), Mul::mul) } }
    }
}