#![allow(dead_code, unused_macros, unused_imports)]
use std::{cell::{Cell, RefCell, UnsafeCell}, cmp::{Ordering, Reverse, max, min}, collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque, hash_map::{DefaultHasher, RandomState}}, error::Error, fmt::{Display, Write as FmtWrite}, hash::{BuildHasher, Hash, Hasher}, io::{BufWriter, Read, Stdin, Stdout, Write}, iter::{FromIterator, Peekable}, mem::swap, ops::*, process::exit, rc::Rc, str::{FromStr, from_utf8_unchecked}, time::{Duration, Instant}, convert::TryInto, marker::PhantomData};

const IO_BUF_SIZE: usize = 1 << 16;
type Input = Scanner<Stdin>;
type Output = BufWriter<Stdout>;
fn _init_input() -> Input { Scanner::new(std::io::stdin()) }
fn _init_output() -> Output { BufWriter::with_capacity(IO_BUF_SIZE, std::io::stdout()) }

#[repr(transparent)] struct Unsync<T>(T);
unsafe impl<T> Sync for Unsync<T> {}

type BadLazy<T> = Unsync<UnsafeCell<Option<T>>>;
impl<T> BadLazy<T> {
    const fn new() -> Self { Self(UnsafeCell::new(None)) }
}

static INPUT: BadLazy<Input> = BadLazy::new();
static OUTPUT: BadLazy<Output> = BadLazy::new();

fn inp<F: FnOnce(&mut Input) -> R, R>(f: F) -> R {
    unsafe { f((&mut *INPUT.0.get()).get_or_insert_with(_init_input)) }
}
fn out<F: FnOnce(&mut Output) -> R, R>(f: F) -> R {
    unsafe { f((&mut *OUTPUT.0.get()).get_or_insert_with(_init_output)) }
}

macro_rules! read {
    () => { read() };
    ($t: ty) => { read::<$t>() };
    ($t: ty, $($tt: ty),*) => { (read::<$t>(), $(read::<$tt>(),)*) };
    [$t: ty; $n: expr] => { read_vec::<$t>($n) };
}
macro_rules! println {
    () => { out(|x| { let _ = writeln!(x); }) };
    ($exp: expr) => { out(|x| { let _ = writeln!(x, "{}", $exp); }) };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { let _ = writeln!(x, $fmt, $($arg)*); }) }
}
macro_rules! print {
    ($exp: expr) => { out(|x| { let _ = write!(x, "{}", $exp); }) };
    ($fmt: expr, $($arg : tt )*) => { out(|x| { let _ = write!(x, $fmt, $($arg)*); }) }
}

fn out_flush() { out(|x| { let _ = x.flush(); }); }

fn input_is_eof() -> bool { inp(|x| x.eof()) }
fn read_byte() -> u8 { inp(|x| x.byte()) }
fn read_bytes_no_skip(n: usize) -> Vec<u8> { inp(|x| x.bytes_no_skip(n)) }
fn read_bytes(n: usize) -> Vec<u8> { inp(|x| x.bytes(n)) }
fn read_bytes2(n: usize, m: usize) -> Vec<Vec<u8>> { inp(|x| x.bytes2(n, m)) }
fn read_token() -> Vec<u8> { inp(|x| x.token_bytes()) }
fn read_token_str() -> String { unsafe { String::from_utf8_unchecked(read_token()) } }
fn read_line() -> Vec<u8> { inp(|x| x.line_bytes()) }
fn read_line_str() -> String { unsafe { String::from_utf8_unchecked(read_line()) } }
fn read<T: FromStr>() -> T { read_token_str().parse::<T>().ok().expect("failed parse") }
fn read_vec<T: FromStr>(n: usize) -> Vec<T> { (0..n).map(|_| read()).collect() }
fn read_vec2<T: FromStr>(n: usize, m: usize) -> Vec<Vec<T>> { (0..n).map(|_| read_vec(m)).collect() }

struct Scanner<R: Read> {
    src: R,
    _buf: Vec<u8>,
    _pt: usize, // pointer
    _rd: usize, // bytes read
}

#[allow(dead_code)]
impl<R: Read> Scanner<R> {
    fn new(src: R) -> Scanner<R> {
        Scanner { src, _buf: vec![0; IO_BUF_SIZE], _pt: 1, _rd: 1 }
    }

    fn _check_buf(&mut self) {
        if self._pt == self._rd {
            self._rd = self.src.read(&mut self._buf).unwrap_or(0);
            self._pt = (self._rd == 0) as usize;
        }
    }

    // returns true if end of file
    fn eof(&mut self) -> bool {
        self._check_buf();
        self._rd == 0
    }

    // filters \r, returns \0 if eof
    fn byte(&mut self) -> u8 {
        loop {
            self._check_buf();
            if self._rd == 0 { return 0; }
            let res = self._buf[self._pt];
            self._pt += 1;
            if res != b'\r' { return res; }
        }
    }

    fn bytes_no_skip(&mut self, n: usize) -> Vec<u8> { (0..n).map(|_| self.byte()).collect() }
    fn bytes(&mut self, n: usize) -> Vec<u8> {
        let res = self.bytes_no_skip(n);
        self.byte();
        res
    }
    fn bytes2(&mut self, n: usize, m: usize) -> Vec<Vec<u8>> { (0..n).map(|_| self.bytes(m)).collect() }

    fn token_bytes(&mut self) -> Vec<u8> {
        let mut res = Vec::new();
        let mut c = self.byte();
        while c <= b' ' {
            if c == b'\0' { return res; }
            c = self.byte();
        }
        loop {
            res.push(c);
            c = self.byte();
            if c <= b' ' { return res; }
        }
    }

    fn line_bytes(&mut self) -> Vec<u8> {
        let mut res = Vec::new();
        let mut c = self.byte();
        while c != b'\n' && c != b'\0' {
            res.push(c);
            c = self.byte();
        }
        res
    }
}

trait JoinToStr {
    fn join_to_str(self, sep: &str) -> String;
    fn concat_to_str(self) -> String;
}
impl<T: Display, I: Iterator<Item = T>> JoinToStr for I {
    fn join_to_str(mut self, sep: &str) -> String {
        match self.next() {
            Some(first) => {
                let mut res = first.to_string();
                while let Some(item) = self.next() {
                    res.push_str(sep);
                    res.push_str(&item.to_string());
                }
                res
            }
            None => { String::new() }
        }
    }

    fn concat_to_str(self) -> String {
        let mut res = String::new();
        for item in self { res.push_str(&item.to_string()); }
        res
    }
}
trait AsStr { fn as_str(&self) -> &str; }
impl AsStr for [u8] { fn as_str(&self) -> &str {std::str::from_utf8(self).expect("attempt to convert non-UTF8 byte string.")} }

macro_rules! veci {
    ($n:expr , $i:ident : $gen:expr) => {{
        let _veci_n = $n;
        let mut _veci_list = Vec::with_capacity(_veci_n);
        for $i in 0.._veci_n {
            _veci_list.push($gen);
        }
        _veci_list
    }};
    ($n:expr , $gen:expr) => { veci!($n, _veci_: $gen) }
}

fn abs_diff<T: Sub<Output = T> + PartialOrd>(x: T, y: T) -> T {
    if x < y { y - x } else { x - y }
}

trait CommonNumExt {
    fn div_ceil(self, b: Self) -> Self;
    fn div_floor(self, b: Self) -> Self;
    fn gcd(self, b: Self) -> Self;
    fn highest_one(self) -> Self;
    fn lowest_one(self) -> Self;
    fn sig_bits(self) -> u32;
}

macro_rules! impl_common_num_ext {
    ($($ix:tt = $ux:tt),*) => {
        $(
            impl CommonNumExt for $ux {
                fn div_ceil(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if r != 0 { q + 1 } else { q }
                }
                fn div_floor(self, b: Self) -> Self { self / b }
                fn gcd(self, mut b: Self) -> Self {
                    let mut a = self; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b
                }
                #[inline] fn highest_one(self) -> Self {
                    if self == 0 { 0 } else { const ONE: $ux = 1; ONE << self.sig_bits() - 1 }
                }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
                #[inline] fn sig_bits(self) -> u32 { std::mem::size_of::<$ux>() as u32 * 8 - self.leading_zeros() }
            }

            impl CommonNumExt for $ix {
                fn div_ceil(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if self ^ b >= 0 && r != 0 { q + 1 } else { q }
                }
                fn div_floor(self, b: Self) -> Self {
                    let q = self / b; let r = self % b;
                    if self ^ b < 0 && r != 0 { q - 1 } else { q }
                }
                fn gcd(self, mut b: Self) -> Self {
                    let mut a = self; while a != 0 { swap(&mut a, &mut b); a %= b; }
                    b.abs()
                }
                #[inline] fn highest_one(self) -> Self { (self as $ux).highest_one() as _ }
                #[inline] fn lowest_one(self) -> Self { self & self.wrapping_neg() }
                #[inline] fn sig_bits(self) -> u32 { std::mem::size_of::<$ix>() as u32 * 8 - self.leading_zeros() }
            }
        )*
    }
}
impl_common_num_ext!(i8 = u8, i16 = u16, i32 = u32, i64 = u64, i128 = u128, isize = usize);

trait ChMaxMin<T> {
    fn chmax(&mut self, v: T) -> bool;
    fn chmin(&mut self, v: T) -> bool;
}
impl<T: PartialOrd> ChMaxMin<T> for Option<T> {
    fn chmax(&mut self, v: T) -> bool { if self.is_none() || v > *self.as_ref().unwrap() { *self = Some(v); true } else { false } }
    fn chmin(&mut self, v: T) -> bool { if self.is_none() || v < *self.as_ref().unwrap() { *self = Some(v); true } else { false } }
}
impl<T: PartialOrd> ChMaxMin<T> for T {
    fn chmax(&mut self, v: T) -> bool { if v > *self { *self = v; true } else { false } }
    fn chmin(&mut self, v: T) -> bool { if v < *self { *self = v; true } else { false } }
}

// * end commons * //

#[macro_use]
#[allow(dead_code)]
mod modint {
    use std::{fmt::{Display, Formatter}, marker::PhantomData, mem::swap, ops::*, str::FromStr, cell::Cell};
    use crate::ModInt;

    pub trait RemEuclidU32: Copy {
        /// Calculates `self` _mod_ `modulus` losslessly.
        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);
    #[inline]
    pub fn mul_mod_u32(a: u32, b: u32, m: u32) -> u32 {
        (a as u64 * b as u64 % m as u64) as u32
    }

    // for a, b < m, unspecified otherwise
    #[inline]
    fn add_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        let (r, c) = a.wrapping_sub(m).overflowing_add(b);
        if c { r } else { a + b }
    }
    #[inline]
    fn sub_mod_raw(a: u32, b: u32, m: u32) -> u32 {
        let (r, c) = a.overflowing_sub(b);
        if c { r.wrapping_add(m) } else { r }
    }
    fn pow_mod_raw(a: u32, mut k: u64, m: u32) -> u32 {
        if m == 1 { return 0; }
        let mut a = a as u64;
        let m = m as u64;
        let mut r: u64 = 1;
        while k > 0 {
            if k & 1 == 1 {
                r = r * a % m;
            }
            k >>= 1;
            a = a * a % m;
        }
        r as u32
    }

    /// # Parameters
    /// * `b` `1 <= b`
    /// # Returns
    /// (x, g) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
    fn inv_gcd(a: i64, b: i64) -> (i64, i64) {
        let a = a.rem_euclid(b);
        if a == 0 { return (0, b); }
        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;
            swap(&mut s, &mut t);
            swap(&mut m0, &mut m1);
        }

        if m0 < 0 { m0 += b / s; }
        (m0, s)
    }

    pub trait Modulus: Copy + Eq {
        fn get_modulus() -> u32;
    }

    #[derive(Clone, Copy, PartialEq, Eq, Hash)]
    #[repr(transparent)]
    pub struct ModIntBase<M: Modulus> {
        val: u32,
        _phantom: PhantomData<M>
    }

    impl <M: Modulus> ModIntBase<M> {
        #[inline(always)]
        pub fn modulus() -> u32 { M::get_modulus() }
        #[inline] pub fn new<I: RemEuclidU32>(val: I) -> Self { Self::raw(val.rem_euclid_u32(Self::modulus())) }
        #[inline] pub fn raw(val: u32) -> Self { Self { val, _phantom: PhantomData } }
        pub fn inv(self) -> Self {
            let (x, gcd) = inv_gcd(self.val.into(), Self::modulus().into());
            debug_assert!(gcd == 1, "the multiplicative inverse {}^-1 mod {} does not exist", self.val, Self::modulus());
            Self::raw(x as u32)
        }
        #[inline] pub fn val(self) -> u32 { self.val }
        #[inline] pub fn pow(self, k: u64) -> Self {
            Self::raw(pow_mod_raw(self.val, k, Self::modulus()))
        }
        pub fn powi(self, k: i64) -> Self { if k < 0 { self.inv().pow(-k as _) } else { self.pow(k as _) } }
        pub fn pow_vec(self, n: usize) -> Vec<Self> {
            let mut res = vec![Self::raw(0); n+1];
            res[0] += 1;
            for i in 1..=n {
                res[i] = res[i-1] * self;
            }
            res
        }

        pub fn invs(a: &[Self]) -> Vec<Self> {
            let n = a.len();
            if n == 0 { return vec![]; }
            let mut acc = Self::new(1);
            let mut res = Vec::with_capacity(n);
            for i in 0..n {
                if a[i].val() != 0 { acc *= a[i]; }
                res.push(acc);
            }
            acc = acc.inv();
            for i in (1..n).rev() {
                res[i] = acc * res[i-1];
                if a[i].val() != 0 { acc *= a[i]; }
            }
            res[0] = acc;
            res
        }
    }

    #[inline]
    pub fn mi<I: RemEuclidU32>(val: I) -> ModInt { ModIntBase::new(val) }
    #[inline] pub fn mir(v: u32) -> ModInt { ModIntBase::raw(v) }

    impl<V: RemEuclidU32, M: Modulus> From<V> for ModIntBase<M> {
        #[inline]
        fn from(from: V) -> Self { Self::new(from) }
    }
    impl<M: Modulus> Default for ModIntBase<M> {
        fn default() -> Self { Self::raw(0) }
    }
    impl<M: Modulus> FromStr for ModIntBase<M> {
        type Err = std::convert::Infallible;
        #[inline]
        fn from_str(s: &str) -> Result<Self, Self::Err> {
            Ok(s.parse::<i64>()
            .map(Self::new)
            .unwrap_or_else(|_| todo!("parsing as an arbitrary precision integer?")))
        }
    }
    impl<M: Modulus> Display for ModIntBase<M> {
        #[inline]
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            self.val.fmt(f)
        }
    }
    impl<M: Modulus> std::fmt::Debug for ModIntBase<M> {
        #[inline]
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
            std::fmt::Debug::fmt(&self.val, f)
        }
    }
    impl<M: Modulus> Neg for ModIntBase<M> {
        type Output = Self;

        #[inline]
        fn neg(self) -> Self::Output {
            Self::raw(0) - self
        }
    }

    impl<V: Into<ModIntBase<M>>, M: Modulus> Add<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn add(self, rhs: V) -> Self::Output {
            Self::raw(add_mod_raw(self.val, rhs.into().val, Self::modulus()))
        }
    }
    impl<V: Into<ModIntBase<M>>, M: Modulus> Sub<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn sub(self, rhs: V) -> Self::Output {
            Self::raw(sub_mod_raw(self.val, rhs.into().val, Self::modulus()))
        }
    }
    impl<V: Into<ModIntBase<M>>, M: Modulus> Mul<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn mul(self, rhs: V) -> Self::Output {
            Self::raw(mul_mod_u32(self.val, rhs.into().val, Self::modulus()))
        }
    }
    impl<V: Into<ModIntBase<M>>, M: Modulus> Div<V> for ModIntBase<M> {
        type Output = Self;
        #[inline]
        fn div(self, rhs: V) -> Self::Output { self * rhs.into().inv() }
    }

    impl <V: Into<ModIntBase<M>>, M: Modulus> AddAssign<V> for ModIntBase<M> {
        #[inline]
        fn add_assign(&mut self, rhs: V) { *self = *self + rhs; }
    }
    impl <V: Into<ModIntBase<M>>, M: Modulus> SubAssign<V> for ModIntBase<M> {
        #[inline]
        fn sub_assign(&mut self, rhs: V) { *self = *self - rhs; }
    }
    impl <V: Into<ModIntBase<M>>, M: Modulus> MulAssign<V> for ModIntBase<M> {
        #[inline]
        fn mul_assign(&mut self, rhs: V) { *self = *self * rhs; }
    }
    impl <V: Into<ModIntBase<M>>, M: Modulus> DivAssign<V> for ModIntBase<M> {
        #[inline]
        fn div_assign(&mut self, rhs: V) { *self = *self / rhs; }
    }

    impl <M: Modulus> std::iter::Sum for ModIntBase<M> {
        #[inline] fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(Self::raw(0), Add::add)
        }
    }
    impl <M: Modulus> std::iter::Product for ModIntBase<M> {
        #[inline] fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
            iter.fold(1.into(), Mul::mul)
        }
    }
    impl<'a, M: Modulus> std::iter::Sum<&'a Self> for ModIntBase<M> {
        #[inline] fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> ModIntBase<M> {
            iter.fold(Self::raw(0), |a, &b| a + b)
        }
    }
    impl<'a, M: Modulus> std::iter::Product<&'a Self> for ModIntBase<M> {
        #[inline] fn product<I: Iterator<Item = &'a Self>>(iter: I) -> ModIntBase<M> {
            iter.fold(1.into(), |a, &b| a * b)
        }
    }

    macro_rules! const_modulus {
        ($mint: ident, $name: ident, $modulus: expr) => {
            #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
            pub enum $name {}
            impl Modulus for $name {
                #[inline(always)] fn get_modulus() -> u32 { $modulus }
            }
            pub type $mint = ModIntBase<$name>;
        }
    }

    macro_rules! dynamic_modulus {
        ($mint: ident, $name: ident, $modulus: ident) => {
            static $modulus: crate::Unsync<Cell<u32>> = crate::Unsync(Cell::new(0));
            #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
            pub enum $name {}
            impl Modulus for $name {
                fn get_modulus() -> u32 { $modulus.0.get() }
            }
            impl $name {
                pub fn set_modulus(val: u32) { $modulus.0.set(val) }
            }
            pub type $mint = ModIntBase<$name>;
        }
    }

    const_modulus!(ModInt998_244_353, Mod998_244_353, 998_244_353);
    const_modulus!(ModInt1_000_000_007, Mod1_000_000_007, 1_000_000_007);
    dynamic_modulus!(DynamicModInt, DynamicModulus, DYNAMIC_MODULUS);
}

use crate::modint::*;
type ModInt = ModInt998_244_353;
// type ModInt = ModInt1_000_000_007;
// const_modulus!(ModInt, DefaultModulus, 1_000_000_009);
// type ModInt = DynamicModInt;

fn mod_factorials(maxn: usize) -> Vec<ModInt> {
    let mut res = vec![ModInt::default(); maxn+1];
    res[0] = 1.into();
    for i in 1..=maxn {
        res[i] = res[i-1] * i
    }
    return res;
}

struct ModCombinatorics {
    factorials: Vec<ModInt>,
    inv_factorials: Vec<ModInt>
}
#[allow(non_snake_case)]
impl ModCombinatorics {
    fn new(maxn: usize) -> Self {
        let factorials = mod_factorials(maxn);
        let mut inv = vec![ModInt::default(); maxn+1];
        inv[maxn] = factorials[maxn].inv();
        for i in (1..=maxn).rev() {
            inv[i-1] = inv[i] * i;
        }
        Self { factorials, inv_factorials: inv }
    }
    #[inline]
    fn factorial(&self, n: usize) -> ModInt { self.factorials[n] }
    #[inline]
    fn inv_factorial(&self, n: usize) -> ModInt { self.inv_factorials[n] }
    fn P(&self, n: usize, k: usize) -> ModInt {
        if k > n { ModInt::raw(0) } else { self.factorial(n) * self.inv_factorial(n-k) }
    }
    fn C(&self, n: usize, k: usize) -> ModInt {
        if k > n { ModInt::raw(0) } else { self.factorial(n) * self.inv_factorial(k) * self.inv_factorial(n-k) }
    }

    // multi-choose, be sure to adjust maxn accordingly
    fn M(&self, n: usize, k: usize) -> ModInt {
        if k == 0 { 1.into() } else { self.C(n + k - 1, k) }
    }
}

pub struct ModFft {
    n_inv: ModInt,
    w: Vec<ModInt>
}
impl ModFft {
    pub fn primitive_root() -> ModInt { ModInt::raw(3) /* for 998244353 */}
    pub fn good_len(deg: usize) -> usize { (deg + 1).next_power_of_two() }
    pub fn prepare(arr: &[ModInt], deg: usize) -> Vec<ModInt> {
        let n = Self::good_len(deg);
        let mut res = Vec::with_capacity(n);
        res.extend_from_slice(arr);
        res.resize(n, ModInt::raw(0));
        res
    }

    pub fn new(max_deg: usize) -> Self {
        let n = Self::good_len(max_deg);
        Self {
            n_inv: ModInt::new(n).inv(),
            w: ModInt::pow_vec(Self::primitive_root().pow((ModInt::modulus() - 1) as u64 / n as u64), n-1)
        }
    }

    pub fn transform(&self, a: &mut [ModInt]) { self.transform_impl(a, false) }
    pub fn transform_inv(&self, a: &mut [ModInt]) { self.transform_impl(a, true) }

    pub fn fft(&self, a: &[ModInt]) -> Vec<ModInt> { self.fft_deg(a, a.len() - 1) }
    pub fn fft_deg(&self, a: &[ModInt], deg: usize) -> Vec<ModInt> {
        let mut a = Self::prepare(a, deg);
        self.transform(&mut a);
        a
    }
    pub fn fft_inv(&self, a: &[ModInt]) -> Vec<ModInt> {
        let mut a = Self::prepare(a, a.len() - 1);
        self.transform_inv(&mut a);
        a
    }

    pub fn max_deg(&self) -> usize { self.w.len() - 1 }

    #[inline] fn transform_impl(&self, a: &mut [ModInt], invert: bool) {
        let sz = a.len();
        if sz <= 1 { return }
        let n = self.w.len();
        debug_assert!(sz <= n && sz.is_power_of_two(), "Array size {} must be <= {} and a power of 2", sz, n);
        let sh = sz.leading_zeros() + 1;

        for i in 0..sz {
            let j = i.reverse_bits() >> sh;
            if i < j { a.swap(i, j) }
        }

        let mut len = 2usize;
        let mut ang = (n >> 1) as isize;
        if invert { ang = -ang; }
        while len <= sz {
            let h = len >> 1;
            for i in (0..sz).step_by(len) {
                let mut k = 0usize;
                for j in i..i+h {
                    let u = a[j];
                    let v = a[j+h] * self.w[k];
                    a[j] = u + v;
                    a[j+h] = u - v;
                    k = k.wrapping_add(ang as usize) & (n-1);
                }
            }
            len <<= 1;
            ang >>= 1;
        }

        if invert {
            let sz_inv = self.n_inv * (n / sz);
            for i in 0..sz { a[i] *= sz_inv; }
        }
    }

    pub fn mul(&self, a: &[ModInt], b: &[ModInt]) -> Vec<ModInt> {
        if a.is_empty() || b.is_empty() { return vec![]; }
        let deg = a.len() + b.len() - 2;
        debug_assert!(deg < self.w.len(), "FFT capacity {} too small for polynomial of degree {}", self.w.len(), deg);
        let mut a = Self::prepare(a, deg);
        let mut b = Self::prepare(b, deg);
        self.transform(&mut a);
        self.transform(&mut b);
        for i in 0..a.len() { a[i] *= b[i]; }
        self.transform_inv(&mut a);
        a.truncate(deg + 1);
        a
    }

    pub fn sq(&self, a: &[ModInt]) -> Vec<ModInt> {
        if a.is_empty() { return vec![]; }
        let deg = a.len() * 2 - 2;
        debug_assert!(deg < self.w.len(), "FFT capacity {} too small for polynomial of degree {}", self.w.len(), deg);
        let mut a = Self::prepare(a, deg);
        self.transform(&mut a);
        for i in 0..a.len() { let ai = a[i]; a[i] = ai * ai; }
        self.transform_inv(&mut a);
        a.truncate(deg + 1);
        a
    }

    pub fn pow(&self, a: &[ModInt], exp: usize) -> Vec<ModInt> {
        if a.is_empty() { return vec![]; }
        let deg = (a.len() - 1) * exp;
        debug_assert!(deg < self.w.len(), "FFT capacity {} too small for polynomial of degree {}", self.w.len(), deg);
        let mut a = Self::prepare(a, deg);
        self.transform(&mut a);
        for i in 0..a.len() { a[i] = a[i].pow(exp as u64) }
        self.transform_inv(&mut a);
        a.truncate(deg + 1);
        a
    }

    pub fn product(&self, mut polys: VecDeque<Vec<ModInt>>) -> Vec<ModInt> {
        while let Some(p) = polys.pop_front() {
            if let Some(q) = polys.pop_front() {
                polys.push_back(self.mul(&p, &q));
            } else { return p; }
        }

        vec![ModInt::new(1)]
    }
}

struct FactorMap {
    map: Vec<u32>
}
impl FactorMap {
    pub fn new(limit: usize) -> FactorMap {
        let limit = limit + 1;
        let mut map = vec![0; limit >> 1];
        for p in (3..limit).step_by(2) {
            if map[p >> 1] != 0 { continue; }
            let sq = p * p;
            if sq >= limit { break; }
            for i in (sq..limit).step_by(p*2) {
                if map[i >> 1] == 0 { map[i >> 1] = p as u32; }
            }
        }

        FactorMap { map }
    }

    pub fn least_prime_factor(&self, n: usize) -> usize {
        if n & 1 == 0 { return 2; }
        let p = self.map[n >> 1] as usize;
        if p == 0 { n } else { p }
    }

    pub fn factorize(&self, n: usize) -> FactorIterator {
        FactorIterator { fm: self, n }
    }

    pub fn is_prime(&self, n: usize) -> bool { n > 1 && self.least_prime_factor(n) == n }

    /// lists divisors, unsorted
    pub fn divisors(&self, mut n: usize) -> Vec<usize> {
        let mut res = vec![1];

        while n > 1 {
            let p = self.least_prime_factor(n);
            let mut x = 0;
            loop {
                n /= p;
                x += 1;
                if p != self.least_prime_factor(n) { break; }
            }
            for i in 0..res.len() {
                let mut a = res[i];
                for _ in 0..x {
                    a *= p;
                    res.push(a);
                }
            }
        }

        res
    }

    pub fn new_with_mobius(limit: usize) -> (FactorMap, Vec<i8>) {
        let fm = Self::new(limit);
        let mut mu = vec![1i8; limit + 1];
        mu[0] = 0;

        for i in 2..=limit {
            let p = fm.least_prime_factor(i);
            mu[i] = if p == fm.least_prime_factor(i/p) { 0 } else { -mu[i/p] };
        }

        (fm, mu)
    }
}
struct FactorIterator<'a> {
    fm: &'a FactorMap,
    n: usize
}
impl Iterator for FactorIterator<'_> {
    type Item = usize;

    fn next(&mut self) -> Option<Self::Item> {
        if self.n <= 1 { return None; }
        let p = self.fm.least_prime_factor(self.n);
        self.n /= p;
        Some(p)
    }

    fn size_hint(&self) -> (usize, Option<usize>) { (0, Some(32)) }
}

#[allow(non_snake_case, non_upper_case_globals)]
fn main() {
    let num_cases: usize = 1;//read();

    for _case_num in 1..=num_cases {
        let n = read!(usize);
        let k = read!(usize);

        let mut ans = mi(0);
        if min(n, k) == 1 { ans = mi(1); }
        else {
            let mc = ModCombinatorics::new(min(n, k));
            let ff = ModFft::new(min(n, k) * 2);
            let mu = FactorMap::new_with_mobius(n).1;

            let mut m = 0usize;
            let mut A = mi(0);

            for i in 1..=n {
                if mu[i] == 0 { continue; }
                let mn = n.div_ceil(i);
                if m != mn {
                    m = mn;
                    let l = min(m, k);

                    let P = veci!(l+1, j: if j & 1 == 1 { -mc.inv_factorial(j) } else { mc.inv_factorial(j) });
                    let Q = veci!(l+1, j: mi(j).pow(m as _) * mc.inv_factorial(j));
                    let R = ff.mul(&P, &Q);
                    A = R[2..=l].iter().sum();
                }
                if mu[i] == 1 { ans += A; } else { ans -= A; }
            }
        }

        println!(ans);
    }

    out_flush();
}


//spnauti-rusT {{{
use std::io::*; use std::str::{self,*}; use std::fmt::Debug;
#[allow(unused_imports)] use std::cmp::Ordering::{self,*};
#[allow(unused_imports)] use std::ops::{self,*};
#[allow(unused_imports)] use std::iter::{self,*};
#[allow(unused_imports)] use std::collections::*;
#[allow(unused_imports)] use std::cell::*;
#[allow(unused_macros)] macro_rules! min {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b < *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! max {
	($x:expr,$y:expr) => {{ let b=$y; let a=&mut$x; if b > *a {*a=b; true} else {false} }};
}
#[allow(unused_macros)] macro_rules! l {
	($($v:ident),+ =$e:expr) => {$(let$v=$e;)+};
	($($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;)+};
}
#[allow(unused_macros)] macro_rules! v {
	([$d:expr]$($s:tt)+) => {vec![v!($($s)+);$d]};
	([]) => {Vec::new()}; ([$e:expr]) => {Vec::with_capacity($e)}; (=$e:expr) => {$e};
}
#[allow(unused_macros)] macro_rules! rep { {[$c:expr]$($s:tt)+} => {for _ in 0..$c {$($s)+}} }
#[allow(dead_code)] fn reader() -> WordReaderC { WordReaderC::new() }
#[allow(dead_code)] fn writer() -> BufWriter<Stdout> { BufWriter::new(stdout()) }
struct WordReaderC {buf: Vec<u8>, pos: usize, q: std::io::StdinLock<'static>}//'
#[allow(dead_code)] impl WordReaderC {
	fn new() -> Self {
		let r = unsafe {&*Box::into_raw(Box::new(stdin()))};
		Self { q: r.lock(), buf: Vec::new(), 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 is_ws(c: u8) -> bool {
		c == b' ' || c == b'\r' || c == b'\n' || c == b'\t'
	}
	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 = Vec::with_capacity(8);
		let mut f = false;
		loop {
			if let Some(c) = self.byte() {
				if !Self::is_ws(c) {
					s.push(c);
					f = true;
				} else if f { break; }
			} else { break; }
		}
		s
	}
	fn s(&mut self) -> String { String::from_utf8(self.vb()).expect("invalid utf8") }
	fn i(&mut self) ->    i32 { self.p() }
	fn l(&mut self) ->    i64 { self.p() }
	fn u(&mut self) ->  usize { self.p() }
	fn f(&mut self) ->    f64 { self.p() }
	fn vi(&mut self, n: usize) -> Vec<i32> { self.vp(n) }
	fn vl(&mut self, n: usize) -> Vec<i64> { self.vp(n) }
	fn vu(&mut self, n: usize) -> Vec<usize> { self.vp(n) }
	fn ii(&mut self, n: usize) -> impl Iterator<Item=i32> { self.ip(n).into_iter() }
	fn iu(&mut self, n: usize) -> impl Iterator<Item=usize> { self.ip(n).into_iter() }
	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 vp<T: FromStr>(&mut self, n: usize) -> Vec<T> where T::Err: Debug {
		(0..n).map(|_|self.p()).collect()
	}
	fn ip<T: FromStr>(&mut self, n: usize) -> impl Iterator<Item=T> where T::Err: Debug {
		self.vp(n).into_iter()
	}
}
//------------------- End rusT }}}

fn main() {
	let mut rin = reader();
	let mut rout = writer();
	const INF: i32 = 1000000000;

	l!(n,m = rin.u());
	l!(s,t = rin.vb());
	assert!(s.len() == n);
	if t[0] == t[1] {
		let c = s.into_iter().filter(|&x| x == t[0]).count();
		let x = n.min(c + m);
		let sol = if x <= 1 {0} else {x * (x-1) / 2};
		writeln!(rout, "{}", sol).ok();
		return;
	}
	let mut dp = v!([n+1][n+1][m+2] = -INF);
	dp[0][0][0] = 0;
	for i in 0..n {
		for j in 0..=i {
			for k in 0..=m.min(i) {
				let v = dp[i][j][k];
				if v < 0 {
					continue;
				}
				if s[i] == t[0] {
					max!(dp[i+1][j+1][k], v);
				} else {
					max!(dp[i+1][j+1][k+1], v);
				}
				if s[i] == t[1] {
					max!(dp[i+1][j][k], v + j as i32);
				} else {
					max!(dp[i+1][j][k+1], v + j as i32);
				}
				max!(dp[i+1][j][k], v);
			}
		}
	}
	let mut sol = 0;
	for j in 0..=n {
		for k in 0..=m {
			max!(sol, dp[n][j][k]);
		}
	}
	writeln!(rout, "{}", sol).ok();
}


macro_rules !input {(source =$s :expr ,$($r :tt ) *) =>{let mut iter =$s .split_whitespace () ;let mut next =||{iter .next () .unwrap () } ;input_inner !{next ,$($r ) *} } ;($($r :tt ) *) =>{let stdin =std ::io ::stdin () ;let mut bytes =std ::io ::Read ::bytes (std ::io ::BufReader ::new (stdin .lock () ) ) ;let mut next =move ||->String {bytes .by_ref () .map (|r |r .unwrap () as char ) .skip_while (|c |c .is_whitespace () ) .take_while (|c |!c .is_whitespace () ) .collect () } ;input_inner !{next ,$($r ) *} } ;}
macro_rules !input_inner {($next :expr ) =>{} ;($next :expr ,) =>{} ;($next :expr ,$var :ident :$t :tt $($r :tt ) *) =>{let $var =read_value !($next ,$t ) ;input_inner !{$next $($r ) *} } ;}
macro_rules !read_value {($next :expr ,($($t :tt ) ,*) ) =>{($(read_value !($next ,$t ) ) ,*) } ;($next :expr ,[$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |read_value !($next ,$t ) ) .collect ::<Vec <_ >>() } ;($next :expr ,chars ) =>{read_value !($next ,String ) .chars () .collect ::<Vec <char >>() } ;($next :expr ,usize1 ) =>{read_value !($next ,usize ) -1 } ;($next :expr ,$t :ty ) =>{$next () .parse ::<$t >() .expect ("Parse error" ) } ;}
trait Monoid {
    fn id() -> Self;
    fn f(a: Self, b: Self) -> Self;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum MaxInt {
    Minimal,
    Val(i64),
}
impl std::ops::Mul for MaxInt {
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        if self > other {
            self
        } else {
            other
        }
    }
}
impl MaxInt {
    fn unwrap(self) -> i64 {
        if let Self::Val(x) = self {
            x
        } else {
            panic!();
        }
    }
    fn map<F>(self, f: F) -> Self
    where
        F: Fn(i64) -> i64,
    {
        if let Self::Val(x) = self {
            Self::Val(f(x))
        } else {
            Self::Minimal
        }
    }
}
impl Monoid for MaxInt {
    fn id() -> Self {
        MaxInt::Minimal
    }
    fn f(a: Self, b: Self) -> Self {
        a * b
    }
}
use MaxInt::*;

fn main() {
    input! {
        n: usize,
        k: usize,
        s: String,
        t: String,
    }
    let s = s.chars().map(|c| c as u8).collect::<Vec<_>>();
    let t = t.chars().map(|c| c as u8).collect::<Vec<_>>();
    if t[0] == t[1] {
        let mut ans = 0;
        let mut c = 0;
        let mut k = k;
        for i in 0..n {
            if k != 0 && s[i] != t[0] {
                ans += c;
                c += 1;
                k -= 1;
            }
            if s[i] == t[0] {
                ans += c;
                c += 1;
            }
        }
        println!("{}", ans);
        return;
    }
    if k == 0 {
        let mut ans = 0;
        let mut c = 0;
        for i in 0..n {
            if s[i] == t[0] {
                c += 1;
            }
            if s[i] == t[1] {
                ans += c;
            }
        }
        println!("{}", ans);
        return;
    }

    let mut dp = vec![vec![vec![Minimal; n + 1]; k + 2]; n + 1];
    dp[0][0][0] = Val(0);
    for i in 0..n {
        for k in 0..=k {
            for c in 0..=i {
                if s[i] == t[0] {
                    dp[i + 1][k][c + 1] = dp[i + 1][k][c + 1] * dp[i][k][c];
                } else {
                    dp[i + 1][k + 1][c + 1] = dp[i + 1][k + 1][c + 1] * dp[i][k][c];
                }
                if s[i] == t[1] {
                    dp[i + 1][k][c] = dp[i + 1][k][c] * dp[i][k][c].map(|v| v + c as i64);
                } else {
                    dp[i + 1][k + 1][c] = dp[i + 1][k + 1][c] * dp[i][k][c].map(|v| v + c as i64);
                }
                if s[i] != t[0] && s[i] != t[1] {
                    dp[i + 1][k][c] = dp[i + 1][k][c] * dp[i][k][c];
                }
            }
        }
    }
    let mut ans = Minimal;
    for k in 0..=k {
        for c in 0..=n {
            ans = ans * dp[n][k][c];
        }
    }
    println!("{}", ans.unwrap());
}


use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::*;
use std::str::*;

// scanner from https://codeforces.com/contest/1396/submission/91365784
struct Scanner {
    stdin: Stdin,
    buffer: VecDeque<String>,
}
#[allow(dead_code)]
impl Scanner {
    fn new() -> Self {
        Scanner {
            stdin: stdin(),
            buffer: VecDeque::new(),
        }
    }
    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.is_empty() {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> {
        self.cin::<String>().chars().collect()
    }
    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.cin()).collect()
    }
}

// chmax https://qiita.com/maguro_tuna/items/fab200fdc1efde1612e7
macro_rules! max {
    ($a:expr $(,)*) => {{
        $a
    }};
    ($a:expr, $b:expr $(,)*) => {{
        std::cmp::max($a, $b)
    }};
    ($a:expr, $($rest:expr),+ $(,)*) => {{
        std::cmp::max($a, max!($($rest),+))
    }};
}

macro_rules! chmax {
    ($base:expr, $($cmps:expr),+ $(,)*) => {{
        let cmp_max = max!($($cmps),+);
        if $base < cmp_max {
            $base = cmp_max;
            true
        } else {
            false
        }
    }};
}

// Editorialを見て作成
fn main() {
    let mut scan = Scanner::new();
    let out = &mut BufWriter::new(stdout());
    let n: usize = scan.cin();
    let max_k: usize = scan.cin();
    let s = scan.chars();
    let t = scan.chars();

    let v: Vec<usize> = s
        .iter()
        .map(|&c| {
            if c == t[0] {
                0
            } else if c == t[1] {
                1
            } else {
                2
            }
        })
        .collect();

    if t[0] == t[1] {
        let ct = v.iter().filter(|&x| *x == 0).count();
        let x = min(ct + max_k, n);
        writeln!(out, "{}", x * (x - 1) / 2).ok();
        return;
    }
    // dp[i][k][ct] : [0,i) の範囲で、k回操作して、t[0]の文字がct個ある場合、この範囲にsubsequenceを何通り作れるか
    let mut dp = vec![vec![vec![-1000000i32; n + 2]; n + 2]; n + 2];
    dp[0][0][0] = 0;

    for i in 0..n {
        for k in 0..=max_k {
            for ct in 0..=i {
                let c = ct as i32;
                if v[i] == 0 {
                    //               op       ->0                 ->1
                    chmax!(dp[i + 1][k + 0][ct + 1], dp[i][k][ct] + 0); // 0->0
                    chmax!(dp[i + 1][k + 1][ct + 0], dp[i][k][ct] + c); // 0->1
                } else if v[i] == 1 {
                    chmax!(dp[i + 1][k + 1][ct + 1], dp[i][k][ct] + 0); // 1->0
                    chmax!(dp[i + 1][k + 0][ct + 0], dp[i][k][ct] + c); // 1->1
                } else if v[i] == 2 {
                    chmax!(dp[i + 1][k + 1][ct + 1], dp[i][k][ct] + 0); // 2->0
                    chmax!(dp[i + 1][k + 1][ct + 0], dp[i][k][ct] + c); // 2->1
                    chmax!(dp[i + 1][k + 0][ct + 0], dp[i][k][ct] + 0); // 2->2
                }
            }
        }
    }

    let mut ans = 0;
    for k in 0..=max_k {
        //print!(" k={} : ", k);
        for ct in 0..=n {
            //print!("{} ", dp[i][k][ct]);
            chmax!(ans, dp[n][k][ct]);
        }
        //println!(" ");
    }

    writeln!(out, "{} ", ans).ok();
}


fn main() {
    let (n, k): (usize, usize) = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        let mut iter = buf.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap(),
        )
    };
    let s: Vec<char> = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim_end().chars().collect()
    };
    let t: Vec<char> = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim_end().chars().collect()
    };

    let mut old = vec![vec![std::i32::MIN; n + 1]; k + 1];
    old[0][0] = 0;
    for x in 0..n {
        let mut new = vec![vec![std::i32::MIN; n + 1]; k + 1];
        let trans = |dst: &mut i32, src: i32| {
            *dst = std::cmp::max(*dst, src);
        };
        for i in 0..=k {
            for j in 0..=x {
                if t[0] == t[1] {
                    if s[x] == t[0] {
                        trans(&mut new[i][j + 1], old[i][j] + j as i32);
                    } else {
                        trans(&mut new[i][j], old[i][j]);
                        if i == k { continue; }
                        trans(&mut new[i + 1][j + 1], old[i][j] + j as i32);
                    }
                } else {
                    if s[x] == t[0] {
                        trans(&mut new[i][j + 1], old[i][j]);
                        if i == k { continue; }
                        trans(&mut new[i + 1][j], old[i][j] + j as i32);
                    } else if s[x] == t[1] {
                        trans(&mut new[i][j], old[i][j] + j as i32);
                        if i == k { continue; }
                        trans(&mut new[i + 1][j + 1], old[i][j]);
                    } else {
                        trans(&mut new[i][j], old[i][j]);
                        if i == k { continue; }
                        trans(&mut new[i + 1][j + 1], old[i][j]);
                        trans(&mut new[i + 1][j], old[i][j] + j as i32);
                    }
                }
            }
        }
        old = new;
    }
    let ans = old.iter().map(|v| v.iter().max().unwrap()).max().unwrap();
    println!("{}", ans);
}


#![allow(non_snake_case)]
use std::io::{BufWriter, stdin, stdout, Write};

fn main() {
    let mut scan = Scanner::default();
    let out = &mut BufWriter::new(stdout());
    let t: usize = scan.next();
    for _ in 0..t {
        let x: usize = scan.next();
        let a: Vec<usize> = scan.vec(3);
        let mut doors = vec![false; 4];
        let mut key = x;
        while !doors[key] {
            doors[key] = true;
            if key == 0 { break; }
            key = a[key - 1];
        }
        if (1..=3).fold(true, |flag, i| doors[i] & flag) {
            writeln!(out, "YES").unwrap();
        } else {
            writeln!(out, "NO").unwrap();
        }
    }
}

#[derive(Default)]
pub struct Scanner {
    buffer: Vec<String>
}
impl Scanner {
    fn next<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();
        }
    }

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


#![allow(unused_imports)]
#![allow(unused_must_use)]
#![allow(non_snake_case)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::many_single_char_names)]

use std::cmp::{max, min, Reverse};
use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::{self, prelude::*};
use std::str;

fn solve<R: BufRead, W: Write>(sc: &mut Scanner<R>, wr: &mut W) {
    for _ in 0..sc.tok() {
        let mut x: usize = sc.tok();
        let v: Vec<usize> = (0..3).map(|_| sc.tok()).collect();
        let mut good = true;
        for _ in 0..2 {
            if v[x-1] == 0 {
                good = false;
                break;
            }
            x = v[x-1];
        }
        if good {
            writeln!(wr, "YES");
        } else {
            writeln!(wr, "NO");
        }
    }
}

use std::marker::PhantomData;
macro_rules! recursive_function {
    ($name: ident, $trait: ident, ($($type: ident $arg: ident,)*)) => {
        pub trait $trait<$($type, )*Output> {
            fn call(&mut self, $($arg: $type,)*) -> Output;
        }

        pub struct $name<F, $($type, )*Output>
        where
            F: FnMut(&mut dyn $trait<$($type, )*Output>, $($type, )*) -> Output,
        {
            f: F,
            $($arg: PhantomData<$type>,
            )*
            phantom_output: PhantomData<Output>,
        }

        impl<F, $($type, )*Output> $name<F, $($type, )*Output>
        where
            F: FnMut(&mut dyn $trait<$($type, )*Output>, $($type, )*) -> Output,
        {
            pub fn new(f: F) -> Self {
                Self {
                    f,
                    $($arg: Default::default(),
                    )*
                    phantom_output: Default::default(),
                }
            }
        }

        impl<F, $($type, )*Output> $trait<$($type, )*Output> for $name<F, $($type, )*Output>
        where
            F: FnMut(&mut dyn $trait<$($type, )*Output>, $($type, )*) -> Output,
        {
            fn call(&mut self, $($arg: $type,)*) -> Output {
                let const_ptr = &self.f as *const F;
                let mut_ptr = const_ptr as *mut F;
                unsafe { (&mut *mut_ptr)(self, $($arg, )*) }
            }
        }
    }
}

recursive_function!(RecursiveFunction0, Callable0, ());
recursive_function!(RecursiveFunction, Callable, (Arg arg,));
recursive_function!(RecursiveFunction2, Callable2, (Arg1 arg1, Arg2 arg2,));
recursive_function!(RecursiveFunction3, Callable3, (Arg1 arg1, Arg2 arg2, Arg3 arg3,));
recursive_function!(RecursiveFunction4, Callable4, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4,));
recursive_function!(RecursiveFunction5, Callable5, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5,));
recursive_function!(RecursiveFunction6, Callable6, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6,));
recursive_function!(RecursiveFunction7, Callable7, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7,));
recursive_function!(RecursiveFunction8, Callable8, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8,));
recursive_function!(RecursiveFunction9, Callable9, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9,));

struct Scanner<R> {
    reader: R,
    buf_str: Vec<u8>,
    buf_iter: str::SplitWhitespace<'static>,
}
impl<R: BufRead> Scanner<R> {
    fn new(reader: R) -> Self {
        Self {
            reader,
            buf_str: vec![],
            buf_iter: "".split_whitespace(),
        }
    }
    fn tok<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_whitespace())
            }
        }
    }
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    solve(&mut scan, &mut out);
}


pub mod solution {

use crate::io::input::Input;
use crate::io::output::output;
use crate::numbers::num_traits::bit_ops::BitOps;
use crate::out_line;

fn solve(input: &mut Input, _test_case: usize) {
    let mut x = input.read_usize();
    let behind = input.read_usize_vec(3);

    let mut has = 0;
    while x != 0 {
        has.set_bit(x - 1);
        x = behind[x - 1];
    }
    out_line!(has == 7);
}

pub(crate) fn run(mut input: Input) -> bool {
    #[allow(dead_code)]
    enum TestType {
        Single,
        MultiNumber,
        MultiEof,
    }
    let test_type = TestType::MultiNumber;
    match test_type {
        TestType::Single => solve(&mut input, 1),
        TestType::MultiNumber => {
            let t = input.read();
            for i in 0usize..t {
                solve(&mut input, i + 1);
            }
        }
        TestType::MultiEof => {
            let mut i = 1usize;
            while input.peek().is_some() {
                solve(&mut input, i);
                i += 1;
            }
        }
    }
    output().flush();
    input.skip_whitespace();
    !input.peek().is_some()
}

}
pub mod io {
pub mod input {
use crate::numbers::num_traits::add_sub::AddSub;
use crate::numbers::num_traits::from_u8::FromU8;
use crate::numbers::num_traits::mul_div_rem::Multable;
use crate::numbers::num_traits::sign::IsSigned;
use crate::numbers::num_traits::zero_one::ZeroOne;
use std::fmt::Display;
use std::io::Read;
use std::marker::PhantomData;

macro_rules! read_impl {
    ($t: ty, $read_name: ident, $read_vec_name: ident) => {
        pub fn $read_name(&mut self) -> $t {
            self.read()
        }

        pub fn $read_vec_name(&mut self, len: usize) -> Vec<$t> {
            self.read_vec(len)
        }
    };

    ($t: ty, $read_name: ident, $read_vec_name: ident, $read_pair_vec_name: ident) => {
        read_impl!($t, $read_name, $read_vec_name);

        pub fn $read_pair_vec_name(&mut self, len: usize) -> Vec<($t, $t)> {
            self.read_vec(len)
        }
    };
}

pub struct Input<'s> {
    input: &'s mut dyn Read,
    buf: Vec<u8>,
    at: usize,
    buf_read: usize,
}

impl<'s> Input<'s> {
    const DEFAULT_BUF_SIZE: usize = 4096;

    pub fn new(input: &'s mut dyn Read) -> Self {
        Self {
            input,
            buf: vec![0; Self::DEFAULT_BUF_SIZE],
            at: 0,
            buf_read: 0,
        }
    }

    pub fn new_with_size(input: &'s mut dyn Read, buf_size: usize) -> Self {
        Self {
            input,
            buf: vec![0; buf_size],
            at: 0,
            buf_read: 0,
        }
    }

    pub fn get(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            let res = self.buf[self.at];
            self.at += 1;
            Some(res)
        } else {
            None
        }
    }

    pub fn peek(&mut self) -> Option<u8> {
        if self.refill_buffer() {
            Some(self.buf[self.at])
        } else {
            None
        }
    }

    pub fn skip_whitespace(&mut self) {
        while let Some(b) = self.peek() {
            if !char::from(b).is_whitespace() {
                return;
            }
            self.get();
        }
    }

    pub fn next_token(&mut self) -> Option<Vec<u8>> {
        self.skip_whitespace();
        let mut res = Vec::new();
        while let Some(c) = self.get() {
            if char::from(c).is_whitespace() {
                break;
            }
            res.push(c);
        }
        if res.is_empty() {
            None
        } else {
            Some(res)
        }
    }

    //noinspection RsSelfConvention
    pub fn is_exhausted(&mut self) -> bool {
        self.peek().is_none()
    }

    pub fn read<T: Readable>(&mut self) -> T {
        T::read(self)
    }

    pub fn read_vec<T: Readable>(&mut self, size: usize) -> Vec<T> {
        let mut res = Vec::with_capacity(size);
        for _ in 0usize..size {
            res.push(self.read());
        }
        res
    }

    pub fn read_line(&mut self) -> String {
        let mut res = String::new();
        while let Some(c) = self.get() {
            if c == b'\n' {
                break;
            }
            if c == b'\r' {
                if self.peek() == Some(b'\n') {
                    self.get();
                }
                break;
            }
            res.push(c.into());
        }
        res
    }

    pub fn iter<'t, T: Readable + 't + 's>(&'t mut self) -> InputIterator<'t, 's, T>
    where
        's: 't,
    {
        InputIterator {
            input: self,
            phantom: Default::default(),
        }
    }

    fn read_integer<T: IsSigned + ZeroOne + FromU8 + AddSub + Multable + Display>(&mut self) -> T {
        self.skip_whitespace();
        let mut c = self.get().unwrap();
        let sgn = if c == b'-' {
            if !T::SIGNED {
                panic!("negative integer")
            }
            c = self.get().unwrap();
            true
        } else if c == b'+' {
            c = self.get().unwrap();
            false
        } else {
            false
        };
        let mut res = T::zero();
        loop {
            if !c.is_ascii_digit() {
                panic!(
                    "expected integer, found {}{}{}",
                    if sgn { "-" } else { "" },
                    res,
                    c as char
                );
            }
            res *= T::from_u8(10);
            res += T::from_u8(c - b'0');
            match self.get() {
                None => {
                    break;
                }
                Some(ch) => {
                    if char::from(ch).is_whitespace() {
                        break;
                    } else {
                        c = ch;
                    }
                }
            }
        }
        if sgn {
            debug_assert!(T::SIGNED);
            res = T::zero() - res
        }
        res
    }

    pub fn read_string(&mut self) -> String {
        match self.next_token() {
            None => {
                panic!("Input exhausted");
            }
            Some(res) => unsafe { String::from_utf8_unchecked(res) },
        }
    }

    pub fn read_char(&mut self) -> char {
        self.skip_whitespace();
        self.get().unwrap().into()
    }

    read_impl!(u8, read_u8, read_u8_vec);
    read_impl!(u16, read_u16, read_u16_vec);
    read_impl!(u32, read_unsigned, read_unsigned_vec);
    read_impl!(u64, read_u64, read_u64_vec);
    read_impl!(u128, read_u128, read_u128_vec);
    read_impl!(usize, read_usize, read_usize_vec, read_usize_pair_vec);
    read_impl!(i8, read_i8, read_i8_vec);
    read_impl!(i16, read_i16, read_i16_vec);
    read_impl!(i32, read_int, read_int_vec, read_int_pair_vec);
    read_impl!(i64, read_long, read_long_vec, read_long_pair_vec);
    read_impl!(i128, read_i128, read_i128_vec);
    read_impl!(isize, read_isize, read_isize_vec);
    read_impl!(f64, read_float, read_float_vec);

    fn read_float_impl(&mut self) -> f64 {
        self.read::<String>().parse().unwrap()
    }

    fn refill_buffer(&mut self) -> bool {
        if self.at == self.buf_read {
            self.at = 0;
            self.buf_read = self.input.read(&mut self.buf).unwrap();
            self.buf_read != 0
        } else {
            true
        }
    }
}

pub struct InputIterator<'t, 's: 't, T: Readable + 't + 's> {
    input: &'t mut Input<'s>,
    phantom: PhantomData<T>,
}

impl<'t, 's: 't, T: Readable + 't + 's> Iterator for InputIterator<'t, 's, T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.input.skip_whitespace();
        self.input.peek().map(|_| self.input.read())
    }
}

pub trait Readable {
    fn read(input: &mut Input) -> Self;
}

impl Readable for String {
    fn read(input: &mut Input) -> Self {
        input.read_string()
    }
}

impl Readable for char {
    fn read(input: &mut Input) -> Self {
        input.read_char()
    }
}

impl Readable for f64 {
    fn read(input: &mut Input) -> Self {
        input.read_float_impl()
    }
}

impl<T: Readable> Readable for Vec<T> {
    fn read(input: &mut Input) -> Self {
        let size = input.read();
        input.read_vec(size)
    }
}

macro_rules! read_integer {
    ($($t:ident)+) => {$(
        impl Readable for $t {
            fn read(input: &mut Input) -> Self {
                input.read_integer()
            }
        }
    )+};
}

read_integer!(i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize);

macro_rules! tuple_readable {
    ($($name:ident)+) => {
        impl<$($name: Readable), +> Readable for ($($name,)+) {
            fn read(input: &mut Input) -> Self {
                ($($name::read(input),)+)
            }
        }
    }
}

tuple_readable! {T}
tuple_readable! {T U}
tuple_readable! {T U V}
tuple_readable! {T U V X}
tuple_readable! {T U V X Y}
tuple_readable! {T U V X Y Z}
tuple_readable! {T U V X Y Z A}
tuple_readable! {T U V X Y Z A B}
tuple_readable! {T U V X Y Z A B C}
tuple_readable! {T U V X Y Z A B C D}
tuple_readable! {T U V X Y Z A B C D E}
tuple_readable! {T U V X Y Z A B C D E F}
}
pub mod output {
use std::io::Write;

#[derive(Copy, Clone)]
pub enum BoolOutput {
    YesNo,
    YesNoCaps,
    PossibleImpossible,
    Custom(&'static str, &'static str),
}

impl BoolOutput {
    pub fn output(&self, output: &mut Output, val: bool) {
        (if val { self.yes() } else { self.no() }).write(output);
    }

    fn yes(&self) -> &str {
        match self {
            BoolOutput::YesNo => "Yes",
            BoolOutput::YesNoCaps => "YES",
            BoolOutput::PossibleImpossible => "Possible",
            BoolOutput::Custom(yes, _) => yes,
        }
    }

    fn no(&self) -> &str {
        match self {
            BoolOutput::YesNo => "No",
            BoolOutput::YesNoCaps => "NO",
            BoolOutput::PossibleImpossible => "Impossible",
            BoolOutput::Custom(_, no) => no,
        }
    }
}

pub struct Output {
    output: Box<dyn Write>,
    buf: Vec<u8>,
    at: usize,
    auto_flush: bool,
    pub bool_output: BoolOutput,
}

impl Output {
    const DEFAULT_BUF_SIZE: usize = 4096;

    pub fn new(output: Box<dyn Write>) -> Self {
        Self {
            output,
            buf: vec![0; Self::DEFAULT_BUF_SIZE],
            at: 0,
            auto_flush: false,
            bool_output: BoolOutput::YesNoCaps,
        }
    }

    pub fn new_with_auto_flush(output: Box<dyn Write>) -> Self {
        Self {
            output,
            buf: vec![0; Self::DEFAULT_BUF_SIZE],
            at: 0,
            auto_flush: true,
            bool_output: BoolOutput::YesNoCaps,
        }
    }

    pub fn flush(&mut self) {
        if self.at != 0 {
            self.output.write_all(&self.buf[..self.at]).unwrap();
            self.output.flush().unwrap();
            self.at = 0;
        }
    }

    pub fn print<T: Writable>(&mut self, s: &T) {
        s.write(self);
    }

    pub fn put(&mut self, b: u8) {
        self.buf[self.at] = b;
        self.at += 1;
        if self.at == self.buf.len() {
            self.flush();
        }
    }

    pub fn maybe_flush(&mut self) {
        if self.auto_flush {
            self.flush();
        }
    }

    pub fn print_per_line<T: Writable>(&mut self, arg: &[T]) {
        for i in arg {
            i.write(self);
            self.put(b'\n');
        }
    }

    pub fn print_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
        let mut first = true;
        for e in iter {
            if first {
                first = false;
            } else {
                self.put(b' ');
            }
            e.write(self);
        }
    }

    pub fn print_iter_ref<'a, T: 'a + Writable, I: Iterator<Item = &'a T>>(&mut self, iter: I) {
        let mut first = true;
        for e in iter {
            if first {
                first = false;
            } else {
                self.put(b' ');
            }
            e.write(self);
        }
    }
}

impl Write for Output {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        let mut start = 0usize;
        let mut rem = buf.len();
        while rem > 0 {
            let len = (self.buf.len() - self.at).min(rem);
            self.buf[self.at..self.at + len].copy_from_slice(&buf[start..start + len]);
            self.at += len;
            if self.at == self.buf.len() {
                self.flush();
            }
            start += len;
            rem -= len;
        }
        if self.auto_flush {
            self.flush();
        }
        Ok(buf.len())
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.flush();
        Ok(())
    }
}

pub trait Writable {
    fn write(&self, output: &mut Output);
}

impl Writable for &str {
    fn write(&self, output: &mut Output) {
        output.write_all(self.as_bytes()).unwrap();
    }
}

impl Writable for String {
    fn write(&self, output: &mut Output) {
        output.write_all(self.as_bytes()).unwrap();
    }
}

impl Writable for char {
    fn write(&self, output: &mut Output) {
        output.put(*self as u8);
    }
}

impl<T: Writable> Writable for &[T] {
    fn write(&self, output: &mut Output) {
        output.print_iter_ref(self.iter());
    }
}

impl<T: Writable> Writable for &T {
    fn write(&self, output: &mut Output) {
        T::write(self, output)
    }
}

impl<T: Writable> Writable for Vec<T> {
    fn write(&self, output: &mut Output) {
        (&self[..]).write(output);
    }
}

macro_rules! write_to_string {
    ($($t:ident)+) => {$(
        impl Writable for $t {
            fn write(&self, output: &mut Output) {
                self.to_string().write(output);
            }
        }
    )+};
}

write_to_string!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);

impl<T: Writable, U: Writable> Writable for (T, U) {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
        output.put(b' ');
        self.1.write(output);
    }
}

impl<T: Writable, U: Writable, V: Writable> Writable for (T, U, V) {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
        output.put(b' ');
        self.1.write(output);
        output.put(b' ');
        self.2.write(output);
    }
}

impl<T: Writable, U: Writable, V: Writable, W: Writable> Writable for (T, U, V, W) {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
        output.put(b' ');
        self.1.write(output);
        output.put(b' ');
        self.2.write(output);
        output.put(b' ');
        self.3.write(output);
    }
}

impl<T: Writable, U: Writable, V: Writable, W: Writable, X: Writable> Writable for (T, U, V, W, X) {
    fn write(&self, output: &mut Output) {
        self.0.write(output);
        output.put(b' ');
        self.1.write(output);
        output.put(b' ');
        self.2.write(output);
        output.put(b' ');
        self.3.write(output);
        output.put(b' ');
        self.4.write(output);
    }
}

impl<T: Writable> Writable for Option<T> {
    fn write(&self, output: &mut Output) {
        match self {
            None => (-1).write(output),
            Some(t) => t.write(output),
        }
    }
}

impl Writable for bool {
    fn write(&self, output: &mut Output) {
        let bool_output = output.bool_output;
        bool_output.output(output, *self)
    }
}

pub static mut OUTPUT: Option<Output> = None;

pub fn output() -> &'static mut Output {
    unsafe {
        match &mut OUTPUT {
            None => {
                panic!("Panic");
            }
            Some(output) => output,
        }
    }
}

#[macro_export]
macro_rules! out {
    ($first: expr $(,$args:expr )*) => {
        $crate::io::output::output().print(&$first);
        $($crate::io::output::output().put(b' ');
        $crate::io::output::output().print(&$args);
        )*
        $crate::io::output::output().maybe_flush();
    }
}

#[macro_export]
macro_rules! out_line {
    ($first: expr $(, $args:expr )* ) => {
        $crate::out!($first $(,$args)*);
        $crate::io::output::output().put(b'\n');
        $crate::io::output::output().maybe_flush();
    };
    () => {
        output().put(b'\n');
        output().maybe_flush();
    };
}
}
}
pub mod numbers {
pub mod num_traits {
pub mod add_sub {
use std::ops::{Add, AddAssign, Sub, SubAssign};

pub trait Addable: Add<Output = Self> + AddAssign + Copy {}
impl<T: Add<Output = Self> + AddAssign + Copy> Addable for T {}

pub trait AddSub: Addable + Sub<Output = Self> + SubAssign {}
impl<T: Addable + Sub<Output = Self> + SubAssign> AddSub for T {}
}
pub mod bit_ops {
use crate::numbers::num_traits::zero_one::ZeroOne;
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Shl};
use std::ops::{ShlAssign, Shr, ShrAssign};

pub trait BitOps:
    Copy
    + BitAnd<Output = Self>
    + BitAndAssign
    + BitOr<Output = Self>
    + BitOrAssign
    + BitXor<Output = Self>
    + BitXorAssign
    + Not<Output = Self>
    + Shl<usize, Output = Self>
    + ShlAssign<usize>
    + Shr<usize, Output = Self>
    + ShrAssign<usize>
    + ZeroOne
    + PartialEq
{
    fn bit(at: usize) -> Self {
        Self::one() << at
    }

    fn is_set(&self, at: usize) -> bool {
        (*self >> at & Self::one()) == Self::one()
    }

    fn set_bit(&mut self, at: usize) {
        *self |= Self::bit(at)
    }

    fn unset_bit(&mut self, at: usize) {
        *self &= !Self::bit(at)
    }

    #[must_use]
    fn with_bit(mut self, at: usize) -> Self {
        self.set_bit(at);
        self
    }

    #[must_use]
    fn without_bit(mut self, at: usize) -> Self {
        self.unset_bit(at);
        self
    }

    fn flip_bit(&mut self, at: usize) {
        *self ^= Self::bit(at)
    }

    fn all_bits(n: usize) -> Self {
        let mut res = Self::zero();
        for i in 0..n {
            res.set_bit(i);
        }
        res
    }
}

impl<
        T: Copy
            + BitAnd<Output = Self>
            + BitAndAssign
            + BitOr<Output = Self>
            + BitOrAssign
            + BitXor<Output = Self>
            + BitXorAssign
            + Not<Output = Self>
            + Shl<usize, Output = Self>
            + ShlAssign<usize>
            + Shr<usize, Output = Self>
            + ShrAssign<usize>
            + ZeroOne
            + PartialEq,
    > BitOps for T
{
}

pub trait Bits: BitOps {
    fn bits() -> u32;
}

macro_rules! bits_integer_impl {
    ($($t: ident $bits: expr),+) => {$(
        impl Bits for $t {
            fn bits() -> u32 {
                $bits
            }
        }
    )+};
}

bits_integer_impl!(i128 128, i64 64, i32 32, i16 16, i8 8, isize 64, u128 128, u64 64, u32 32, u16 16, u8 8, usize 64);
}
pub mod from_u8 {
pub trait FromU8 {
    fn from_u8(val: u8) -> Self;
}

macro_rules! from_u8_impl {
    ($($t: ident)+) => {$(
        impl FromU8 for $t {
            fn from_u8(val: u8) -> Self {
                val as $t
            }
        }
    )+};
}

from_u8_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize f32 f64);
}
pub mod mul_div_rem {
use std::ops::{Div, DivAssign, Mul, MulAssign, Rem, RemAssign};

pub trait Multable: Mul<Output = Self> + MulAssign + Copy {}
impl<T: Mul<Output = Self> + MulAssign + Copy> Multable for T {}

pub trait MulDiv: Multable + Div<Output = Self> + DivAssign {}
impl<T: Multable + Div<Output = Self> + DivAssign> MulDiv for T {}

pub trait MulDivRem: MulDiv + Rem<Output = Self> + RemAssign {}
impl<T: MulDiv + Rem<Output = Self> + RemAssign> MulDivRem for T {}
}
pub mod sign {
pub trait IsSigned {
    const SIGNED: bool;
}

pub trait Signed: IsSigned {}

pub trait Unsigned: IsSigned {}

macro_rules! unsigned_impl {
    ($($t: ident)+) => {$(
        impl Unsigned for $t {}

        impl IsSigned for $t {
            const SIGNED: bool = false;
        }
    )+};
}

unsigned_impl!(u128 u64 u32 u16 u8 usize);

macro_rules! signed_impl {
    ($($t: ident)+) => {$(
        impl Signed for $t {}

        impl IsSigned for $t {
            const SIGNED: bool = true;
        }
    )+};
}

signed_impl!(i128 i64 i32 i16 i8 isize f64 f32);
}
pub mod zero_one {
pub trait ZeroOne {
    fn zero() -> Self;
    fn one() -> Self;
}

macro_rules! zero_one_integer_impl {
    ($($t: ident)+) => {$(
        impl ZeroOne for $t {
            fn zero() -> Self {
                0
            }

            fn one() -> Self {
                1
            }
        }
    )+};
}

zero_one_integer_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);

macro_rules! zero_one_float_impl {
    ($($t: ident)+) => {$(
        impl ZeroOne for $t {
            fn zero() -> Self {
                0.
            }

            fn one() -> Self {
                1.
            }
        }
    )+};
}

zero_one_float_impl!(f32 f64);
}
}
}
fn main() {
    let mut sin = std::io::stdin();
    let input = crate::io::input::Input::new(&mut sin);
    unsafe {
        crate::io::output::OUTPUT = Some(crate::io::output::Output::new(Box::new(std::io::stdout())));
    }
    crate::solution::run(input);
}


fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());

    let t: usize = sc.read();
    for _ in 0..t {
        let x = sc.usize0();
        let t: Vec<usize> = sc.vec(3);

        let mut cur = x;
        let key = t[cur];
        if key == 0 {
            println!("NO");
            continue;
        }
        cur = key - 1;
        let key = t[cur];
        if key == 0 {
            println!("NO");
            continue;
        }
        println!("YES");
    }
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        Self(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write_all(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn usize0(&mut self) -> usize {
        self.read::<usize>() - 1
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}


use std::collections::BTreeSet;
use std::io::{self, prelude::*};
use std::iter;

fn solve<R: BufRead, W: Write>(scan: &mut input::Scanner<R>, out: &mut W) {
    let mut keys: BTreeSet<usize> = iter::once(scan.token()).collect();
    let doors: Vec<_> = (1..=3).map(|_| scan.token::<usize>()).collect();
    loop {
        let prev = keys.clone();
        for key in &prev {
            if doors[key - 1] != 0 {
                keys.insert(doors[key - 1]);
            }
        }
        if prev.len() == keys.len() {
            break;
        }
    }
    let answer = if keys.len() == 3 { "YES" } else { "NO" };
    writeln!(out, "{answer}").unwrap();
}

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

    let t: i32 = scan.token();
    for _ in 1..=t {
        solve(&mut scan, &mut out);
    }
}

mod input {
    use std::io::prelude::*;
    use std::mem;
    use std::str;

    pub struct Scanner<R> {
        reader: R,
        buf_str: Vec<u8>,
        buf_iter: str::SplitWhitespace<'static>,
    }
    impl<R: BufRead> Scanner<R> {
        pub fn new(reader: R) -> Self {
            Self {
                reader,
                buf_str: vec![],
                buf_iter: "".split_whitespace(),
            }
        }
        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);
                    mem::transmute(slice.split_whitespace())
                }
            }
        }
    }
}


/* This code was written by
Russell Emerine - linguist,
mathematician, coder,
musician, and metalhead. */

use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Stdin, Stdout, Write};

struct Io<Input, Output>
where
    Input: Read,
    Output: Write,
{
    input: BufReader<Input>,
    output: BufWriter<Output>,
    buffer: Vec<String>,
}

#[allow(dead_code)]
impl<Input, Output> Io<Input, Output>
where
    Input: Read,
    Output: Write,
{
    fn new(input: Input, output: Output) -> Self {
        Self {
            input: BufReader::new(input),
            output: BufWriter::new(output),
            buffer: vec![],
        }
    }

    fn next<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();
            self.input.read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }

    fn print(&mut self, value: impl std::fmt::Display) {
        writeln!(self, "{}", value).ok();
    }

    fn prints(&mut self, items: &[impl std::fmt::Display], sep: &str) {
        writeln!(
            self,
            "{}",
            items
                .iter()
                .map(|x| x.to_string())
                .collect::<Vec<_>>()
                .join(sep)
        )
        .ok();
    }
}

impl<Input, Output> Write for Io<Input, Output>
where
    Input: Read,
    Output: Write,
{
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.output.flush()
    }
}

impl Default for Io<Stdin, Stdout> {
    fn default() -> Self {
        Self::new(stdin(), stdout())
    }
}

fn main() {
    let mut io = Io::default();
    for _ in 0..io.next() {
        let x: usize = io.next();
        let a: &[usize] = &[io.next(), io.next(), io.next()];
        if a[x - 1] == 0 {
            io.print("NO");
        } else if a[a[x - 1] - 1] == 0 {
            io.print("NO");
        } else {
            io.print("YES");
        }
    }
}


use std::{io::{BufRead, BufWriter, Write}, hash::Hash};
#[allow(unused)]
use std::{{collections::*, mem::swap},cmp::Reverse};

fn main() {
    let sin = std::io::stdin();
    let scan = &mut Scanner::new(sin.lock());
    let sout = std::io::stdout();
    let out = &mut BufWriter::new(sout.lock());
    solve_wrapper(scan, out, solve);
}

#[allow(unused)]
#[macro_export]
macro_rules! logln {
    ($($arg:tt)*) => ({
        #[cfg(debug_assertions)]
        println!($($arg)*);
    })
}

trait MapX<K,V:Default> {
    fn update_with<F: FnOnce(&mut V) -> V>(&mut self, key:K, get_new_value:F);
}
macro_rules! update_with { () => {
    fn update_with<F: FnOnce(&mut V) -> V>(&mut self, key:K, get_new_value:F) {
        let v = self.entry(key).or_default();
        let nv = get_new_value(v);
        *v = nv;
    }
} }
impl <K:Ord,V:Default> MapX<K,V> for BTreeMap<K,V> {
    update_with!();
}
impl <K:Hash+Eq,V:Default> MapX<K,V> for HashMap<K,V> {
    update_with!();
}

trait UsizeX {
    fn i64(self) -> i64;
}
impl UsizeX for usize {
    fn i64(self) -> i64 {
        self as i64
    }
}

pub struct Scanner<R> {
    reader: R,
    buffer: Vec<String>,
}
impl<R: ::std::io::BufRead> Scanner<R> {
    pub fn new(reader: R) -> Self {
        Self { reader, buffer: vec![] }
    }
    pub fn token<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();
            self.reader.read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
    pub fn line<T: ::std::str::FromStr>(&mut self) -> Vec<T> {
        if !self.buffer.is_empty() {
            panic!("Consume token buffer before read a line.");
        }
        let mut input = String::new();
        self.reader.read_line(&mut input).expect("Failed read");
        input.split_whitespace().map(|v| v.parse().ok().expect("Failed parse")).collect()
    }
    pub fn line_with<T: ::std::str::FromStr,F: FnMut(&T)->T>(&mut self, f: F) -> Vec<T> {
        return self.line().iter().map(f).collect::<Vec<_>>();
    }
}

#[cfg(test)]
mod abc999x {
    use super::*;

    macro_rules! test_macro {
        ($name:ident, | $input:expr,) => {
            #[test]
            fn $name() {
                let vi = $input.split("\n").collect::<Vec<_>>();
                let vi = &vi[..vi.len()-1];
                let mut inp = String::new();
                let mut cnt=0;
                for &line in vi {
                    if line.starts_with("output") { break; }
                    cnt+=1;
                    if line.starts_with("input") || line.starts_with("Copy") { continue; }
                    inp+=line; inp+="\n";
                }
                let mut exp = String::new();
                for &line in &vi[cnt..] {
                    if line.starts_with("output") || line.starts_with("Copy") { continue; }
                    exp+=line; exp+="\n";
                }
                let output = &mut Vec::new();
                let scan = &mut Scanner::new(inp.as_bytes());
                solve_wrapper(scan, output, solve);
                assert_eq!(exp, std::str::from_utf8(output).unwrap());
            }
        };
        ($name:ident, $($n:ident),*, | $input:expr, $($i:expr),*,) => {
            test_macro!($name, | $input,);
            test_macro!($($n),*, | $($i),*,);
        };
    }

    test_macro!(
est0,
test1,
test2,
test3,
|
// Example 0
"\
inputCopy
",
// Example 1
"\
inputCopy
4
3
0 1 2
1
0 3 2
2
3 1 0
2
1 3 0
outputCopy
YES
NO
YES
NO
",
// Example 2
"\
input
",
// Example 3
"\
input
",
);

}

fn solve_wrapper<B,W,F>(scan: &mut Scanner<B>, out: &mut W, mut solve: F)
    where B: BufRead, W: Write, F:FnMut(&mut Scanner<B>, &mut W)
    {
    //let t = 1;
    let t = scan.token::<usize>();
    for _ in 0..t {
        solve(scan,out);
    }
}

fn solve(scan: &mut Scanner<impl BufRead>, out: &mut impl Write) {
    let mut x = scan.token::<usize>();
    let va = scan.line::<usize>();
    let mut vf = vec![false;3];
    loop {
        vf[x-1] = true;
        x = va[x-1];
        if x == 0 {
            break;
        }
    }
    let ok = vf.iter().all(|&v| v);

    if ok {
        writeln!(out, "YES" ).ok();
    } else {
        writeln!(out, "NO" ).ok();
    }

}


fn solve() {
    input! {
        mut x: usize1,
        d: [usize; 3],
    }
    for _ in 0..2 {
        if d[x] == 0 {
            println!("NO");
            return;
        }
        x = d[x] - 1;
    }
    println!("YES");
}

fn main() {
    input! {
        t: usize,
    }
    for _ in 0..t {
        solve();
    }
}

mod io {
    use std::cell::RefCell;
    use std::io::*;

    std::thread_local! {
        pub static STDIN: RefCell<Stdin> = RefCell::new(stdin());
        pub static STDOUT: RefCell<BufWriter<Stdout>> = RefCell::new(BufWriter::new(stdout()));
    }

    #[macro_export]
    macro_rules! input {
        () => {};
        (mut $var:ident: $t:tt, $($rest:tt)*) => {
            let mut $var = __input_inner!($t);
            input!($($rest)*)
        };
        ($var:ident: $t:tt, $($rest:tt)*) => {
            let $var = __input_inner!($t);
            input!($($rest)*)
        };
        (mut $var:ident: $t:tt) => {
            let mut $var = __input_inner!($t);
        };
        ($var:ident: $t:tt) => {
            let $var = __input_inner!($t);
        };
    }

    #[macro_export]
    macro_rules! __input_inner {
        (($($t:tt),*)) => {
            ($(__input_inner!($t)),*)
        };
        ([$t:tt; $n:expr]) => {
            (0..$n).map(|_| __input_inner!($t)).collect::<Vec<_>>()
        };
        ([$t:tt]) => {{
            let n = __input_inner!(usize);
            (0..n).map(|_| __input_inner!($t)).collect::<Vec<_>>()
        }};
        (chars) => {
            __input_inner!(String).chars().collect::<Vec<_>>()
        };
        (bytes) => {
            __input_inner!(String).into_bytes()
        };
        (usize1) => {
            __input_inner!(usize) - 1
        };
        ($t:ty) => {
            $crate::io::STDIN.with(|r| {
                use std::io::BufRead;
                let r = r.borrow_mut();
                let mut r = r.lock();
                let mut s = vec![];
                loop {
                    let buf = r.fill_buf().unwrap();
                    if buf.is_empty() {
                        break;
                    }
                    if let Some(i) = buf.iter().position(u8::is_ascii_whitespace) {
                        s.extend_from_slice(&buf[..i]);
                        r.consume(i + 1);
                        if !s.is_empty() {
                            break;
                        }
                    } else {
                        s.extend_from_slice(buf);
                        let n = buf.len();
                        r.consume(n);
                    }
                }
                std::str::from_utf8(&s).unwrap().parse::<$t>().unwrap()
            })
        };
    }

    #[macro_export]
    macro_rules! println {
        () => {
            $crate::io::STDOUT.with(|w| {
                use std::io::Write;
                std::writeln!(w.borrow_mut()).unwrap()
            })
        };
        ($($arg:tt)*) => {
            $crate::io::STDOUT.with(|w| {
                use std::io::Write;
                std::writeln!(w.borrow_mut(), $($arg)*).unwrap()
            })
        };
    }

    #[macro_export]
    macro_rules! print {
        ($($arg:tt)*) => {
            $crate::io::STDOUT.with(|w| {
                use std::io::Write;
                std::write!(w.borrow_mut(), $($arg)*).unwrap()
            })
        };
    }

    #[macro_export]
    macro_rules! flush {
        () => {
            $crate::io::STDOUT.with(|w| {
                use std::io::Write;
                w.borrow_mut().flush().unwrap()
            })
        };
    }
}


#![allow(dead_code)]
#![allow(unused_imports)]

use std::cmp::*;
use std::collections::*;
use std::io;
use std::ops;
use std::str::FromStr;

#[derive(Clone, Debug, Default)]
struct ProblemState {
}

impl Problem {
    fn solve(&mut self) {
        let n: u64 = self.scan();

        let mut ans1 = 1u64;
        let mut ans2 = 1u64;

        const MOD: u64 = 1_000_000_007;

        for i in 2..n + 1 {
            ans1 *= i;
            ans1 %= MOD;
            ans2 *= 2;
            ans2 %= MOD;
        }

        println!("{}", (ans1 - ans2 + MOD) % MOD);
    }
}

fn main() {
    Problem::new().solve();
}

struct Problem {
    input_state: InputState,
    problem_state: ProblemState,
}

struct InputState {
    stdin: io::Stdin,
    buffer: String,
    tokens: VecDeque<String>,
}

impl Problem {
    fn new() -> Self {
        Self {
            input_state: InputState {
                stdin: io::stdin(),
                buffer: String::new(),
                tokens: VecDeque::new(),
            },
            problem_state: Default::default(),
        }
    }

    fn solve_cases(&mut self) {
        for _ in 0usize..self.scan() {
            self.solve()
        }
    }

    fn scan<T: FromStr>(&mut self) -> T {
        while self.input_state.tokens.is_empty() {
            self.input_state.stdin.read_line(&mut self.input_state.buffer).unwrap();

            for token in self.input_state.buffer.split_ascii_whitespace() {
                self.input_state.tokens.push_back(token.to_string());
            }

            self.input_state.buffer.clear();
        }

        self.input_state.tokens.pop_front().unwrap().parse().ok().unwrap()
    }

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

    fn scan_line(&mut self) -> String {
        let mut line = String::new();
        self.input_state.stdin.read_line(&mut line).unwrap();
        while line.ends_with('\n') || line.ends_with('\r') { line.pop(); }
        line
    }

    fn scan_line_vec(&mut self, n: usize) -> Vec<String> {
        (0..n).into_iter().map(|_| self.scan_line()).collect()
    }
}

impl ops::Deref for Problem {
    type Target = ProblemState;

    fn deref(&self) -> &ProblemState {
        &self.problem_state
    }
}

impl ops::DerefMut for Problem {
    fn deref_mut(&mut self) -> &mut ProblemState {
        &mut self.problem_state
    }
}


#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(unused_mut)]
#![allow(unused_variables)]
#![allow(dead_code)]

#[allow(unused_macros)]
macro_rules! invec {
    ( $ t : ty ) => {{
        let mut s = String::new();
        match std::io::stdin().read_line(&mut s) {
            Ok(0) => Vec::<$t>::new(),
            Ok(n) => s
                .trim()
                .split_whitespace()
                .map(|s| s.parse::<$t>().unwrap())
                .collect::<Vec<$t>>(),
            Err(_) => Vec::<$t>::new(),
        }
    }};
}

#[allow(unused_macros)]
macro_rules! get {
      ($t:ty) => {
          {
              let mut line: String = String::new();
              std::io::stdin().read_line(&mut line).unwrap();
              line.trim().parse::<$t>().unwrap()
          }
      };
      ($($t:ty),*) => {
          {
              let mut line: String = String::new();
              std::io::stdin().read_line(&mut line).unwrap();
              let mut iter = line.split_whitespace();
              (
                  $(iter.next().unwrap().parse::<$t>().unwrap(),)*
              )
          }
      };
      ($t:ty; $n:expr) => {
          (0..$n).map(|_|
              get!($t)
          ).collect::<Vec<_>>()
      };
      ($($t:ty),*; $n:expr) => {
          (0..$n).map(|_|
              get!($($t),*)
          ).collect::<Vec<_>>()
      };
      ($t:ty ;;) => {
          {
              let mut line: String = String::new();
              std::io::stdin().read_line(&mut line).unwrap();
              line.split_whitespace()
                  .map(|t| t.parse::<$t>().unwrap())
                  .collect::<Vec<_>>()
          }
      };
      ($t:ty ;; $n:expr) => {
          (0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
      };
}

#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
    ($iter:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($next:expr, [$t:tt]) => {
        {
            let len = read_value!($next, usize);
            (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
        }
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
#[cfg(debug_assertions)]
macro_rules! mydbg {
    //($arg:expr) => (dbg!($arg))
    //($arg:expr) => (println!("{:?}",$arg));
      ($($a:expr),*) => {
          eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
      }
}
#[cfg(not(debug_assertions))]
macro_rules! mydbg {
    ($($arg:expr),*) => {};
}

macro_rules! echo {
    ($($a:expr),*) => {
          $(println!("{}",$a))*
      }
}

use std::cmp::*;
use std::collections::*;
use std::ops::{Add, Div, Mul, Sub};

#[allow(dead_code)]
static INF_I64: i64 = i64::max_value() / 2;
#[allow(dead_code)]
static INF_I32: i32 = i32::max_value() / 2;
#[allow(dead_code)]
static INF_USIZE: usize = usize::max_value() / 2;
#[allow(dead_code)]
static M_O_D: usize = 1000000007;
#[allow(dead_code)]
static PAI: f64 = 3.1415926535897932;

trait IteratorExt: Iterator {
    fn toVec(self) -> Vec<Self::Item>;
}

impl<T: Iterator> IteratorExt for T {
    fn toVec(self) -> Vec<Self::Item> {
        self.collect()
    }
}

trait CharExt {
    fn toNum(&self) -> usize;
    fn toAlphabetIndex(&self) -> usize;
    fn toNumIndex(&self) -> usize;
}
impl CharExt for char {
    fn toNum(&self) -> usize {
        return *self as usize;
    }
    fn toAlphabetIndex(&self) -> usize {
        return self.toNum() - 'a' as usize;
    }
    fn toNumIndex(&self) -> usize {
        return self.toNum() - '0' as usize;
    }
}

trait VectorExt {
    fn joinToString(&self, s: &str) -> String;
}
impl<T: ToString> VectorExt for Vec<T> {
    fn joinToString(&self, s: &str) -> String {
        return self
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<_>>()
            .join(s);
    }
}

trait StringExt {
    fn get_reverse(&self) -> String;
}
impl StringExt for String {
    fn get_reverse(&self) -> String {
        self.chars().rev().collect::<String>()
    }
}

trait UsizeExt {
    fn pow(&self, n: usize) -> usize;
}
impl UsizeExt for usize {
    fn pow(&self, n: usize) -> usize {
        return ((*self as u64).pow(n as u32)) as usize;
    }
}

#[derive(Debug, Copy, Clone)]
pub struct ModInt {
    x: i64,
    global_mod: i64,
}
impl ModInt {
    pub fn new(p: i64) -> Self {
        let gm = 1000000007;
        let a = (p % gm + gm) % gm;
        return ModInt {
            x: a,
            global_mod: gm,
        };
    }
    pub fn inv(self) -> Self {
        return self.pow(self.global_mod - 2);
    }
    pub fn pow(self, t: i64) -> Self {
        if (t == 0) {
            return ModInt::new(1);
        };
        let mut a = self.pow(t >> 1);
        a = a * a;
        if (t & 1 != 0) {
            a = a * self
        };
        return a;
    }
}
impl Add for ModInt {
    type Output = ModInt;
    fn add(self, other: ModInt) -> ModInt {
        let ret = self.x + other.x;
        return ModInt::new(ret);
    }
}
impl Sub for ModInt {
    type Output = ModInt;
    fn sub(self, other: ModInt) -> ModInt {
        let ret = self.x - other.x;
        return ModInt::new(ret);
    }
}
impl Mul for ModInt {
    type Output = ModInt;
    fn mul(self, other: ModInt) -> ModInt {
        let ret = self.x * other.x;
        return ModInt::new(ret);
    }
}
impl Div for ModInt {
    type Output = ModInt;
    fn div(self, other: ModInt) -> ModInt {
        let ret = self.x * other.inv().x;
        return ModInt::new(ret);
    }
}
impl std::string::ToString for ModInt {
    fn to_string(&self) -> String {
        return self.x.to_string();
    }
}
pub struct Combination {
    fact: Vec<ModInt>,
    ifact: Vec<ModInt>,
}
impl Combination {
    pub fn new(n: i32) -> Self {
        if n > 3000000 {
            panic!("error");
        }
        let mut fact = vec![ModInt::new(0); (n + 1) as usize];
        let mut ifact = vec![ModInt::new(0); (n + 1) as usize];
        fact[0] = ModInt::new(1);
        for i in 1..n + 1 {
            fact[i as usize] = fact[(i - 1) as usize] * ModInt::new(i as i64)
        }
        ifact[n as usize] = fact[n as usize].inv();
        for i in (1..n + 1).rev() {
            ifact[(i - 1) as usize] = ifact[i as usize] * ModInt::new(i as i64)
        }
        let a = Combination {
            fact: fact,
            ifact: ifact,
        };
        return a;
    }
    #[macro_use]
    pub fn gen(&mut self, n: i32, k: i32) -> ModInt {
        if (k < 0 || k > n) {
            return ModInt::new(0 as i64);
        };
        return self.fact[n as usize] * self.ifact[k as usize] * self.ifact[(n - k) as usize];
    }
    pub fn P(&mut self, n: i32, k: i32) -> ModInt {
        self.fact[n as usize] * self.ifact[(n - k) as usize]
    }
}

fn main() {
    let N = get!(usize);
    let mut ans = ModInt::new(0);
    let mut cmb = Combination::new(1000006);
    for m in 0..N {
        ans = ans + cmb.gen((N - 1) as i32, m as i32);
    }
    let mut a = cmb.P(N as i32, N as i32);
    ans = a - ans;

    echo!(ans.to_string());
}


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

fn main() {
    let mut stdin = io::stdin();
    // From https://keens.github.io/blog/2017/10/05/rustdekousokunahyoujunshutsuryoku/
    let stdout = io::stdout();
    let mut output = BufWriter::new(stdout.lock());
    let mut input_str = String::new();
    let _ = stdin.read_to_string(&mut input_str);
    let mut input_iter = input_str.split_ascii_whitespace();
    // From https://github.com/rust-lang-ja/atcoder-rust-resources/wiki/2020-Update#proconio
    sub_main(&mut input_iter, &mut output);
}

fn sub_main(input_iter: &mut dyn Iterator<Item = &str>, output: &mut dyn Write) {
    macro_rules! read(() => (input_iter.next().unwrap().parse().unwrap()));
    macro_rules! print(( $( $x:expr ),*) => (write!(output, $($x,)*).unwrap()));
    macro_rules! println(( $( $x:expr ),*) => (writeln!(output, $($x,)*).unwrap()));
    // Deal with each case
    let n: usize = read!();
    let non_cyclic = ModP(2).pow(n - 1);
    let mut total_num = ModP(1);
    for i in 1..=n {
        total_num = total_num * ModP(i as u64);
    }
    let ans = total_num - non_cyclic;
    println!("{}", ans.0);
}

use std::ops::{Add, Div, Mul, Sub};

const MODULUS: u64 = 1000000007;

#[derive(Clone, Copy, PartialEq, Debug)]
struct ModP(u64);

impl Add for ModP {
    type Output = Self;
    fn add(self, rhs: Self) -> Self {
        return ModP((self.0 + rhs.0) % MODULUS);
    }
}
impl Sub for ModP {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self {
        return ModP((self.0 + MODULUS - rhs.0) % MODULUS);
    }
}
impl Mul for ModP {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self {
        return ModP((self.0 * rhs.0) % MODULUS);
    }
}
impl Div for ModP {
    type Output = Self;
    fn div(self, rhs: Self) -> Self {
        if rhs.0 == 0 {
            panic!("Tried to divide by ModP(0)!");
        }
        let rhs_inv = rhs.pow((MODULUS - 2) as usize);
        return self * rhs_inv;
    }
}

impl ModP {
    fn pow(&self, n: usize) -> Self {
        if n == 0 {
            return ModP(1);
        } else if n == 1 {
            return *self;
        } else {
            let half = self.pow(n / 2);
            if n % 2 == 0 {
                return half * half;
            } else {
                return half * half * (*self);
            }
        }
    }
}


use std::io;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let n: u32 = input.trim().parse().unwrap();
    let mut pow = 1u32;
    let p = 1000000007u32;
    for _i in 0..(n-1) {
        pow = (pow as u64 * 2u64 % p as u64) as u32;
    }
//     println!("{}", pow);
    let mut fact = 1u32;
    for i in 2..(n+1) {
        fact = (fact as u64 * i as u64 % p as u64) as u32;
    }
//     println!("{}", fact);
    let ans;
    if fact < pow {
        ans = fact + p - pow;
    } else {
        ans = fact - pow;
    }
    println!("{}", ans);
}


use std::io;
use std::str;

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

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

    pub fn token<T: 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();
            self.reader.read_line(&mut input).expect("Failed read");
            self.buffer = input.split_whitespace().rev().map(String::from).collect();
        }
    }
}

const MOD: i64 = 1_000_000_007;

fn f(n: i64) -> i64 {
    let mut prod_n = 1;
    let mut prod_2 = 1;
    for i in 1..=n {
        prod_n = (prod_n * i) % MOD;
    }
    for i in 1..n {
        prod_2 = (prod_2 * 2) % MOD;
    }
    (prod_n - prod_2).rem_euclid(MOD)
}

fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
    let n: i64 = scan.token();
    let ans = f(n);
    writeln!(out, "{}", ans).ok();
}

fn main() {
    let (stdin, stdout) = (io::stdin(), io::stdout());
    let mut scan = Scanner::new(stdin.lock());
    let mut out = io::BufWriter::new(stdout.lock());
    solve(&mut scan, &mut out);
}