Problem:
Score : 800 points

Problem Statement

Given is a positive even number N.

Find the number of strings s of length N consisting of A, B, and C that satisfy the following condition:

s can be converted to the empty string by repeating the following operation:

Choose two consecutive characters in s and erase them. However, choosing AB or BA is not allowed.

For example, ABBC satisfies the condition for N=4, because we can convert it as follows: ABBC → (erase BB) → AC → (erase AC) → (empty).

The answer can be enormous, so compute the count modulo 998244353.

Constraints

2 \leq N \leq 10^7

N is an even number.

Input

Input is given from Standard Input in the following format:

N

Output

Print the number of strings that satisfy the conditions, modulo 998244353.

Sample Input 1

2

Sample Output 1

7

Except AB and BA, all possible strings satisfy the conditions.

Sample Input 2

10

Sample Output 2

50007

Sample Input 3

1000000

Sample Output 3

210055358

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;

#[allow(unused_imports)]
use proconio::marker::{Bytes, Chars, Usize1};
#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::ops::*;
#[derive(Clone, Debug, Default)]
struct Struct;



//
// ModInt
//

const M: i64 = 998244353;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct ModInt {
    val: i64,
}
const M0: ModInt = ModInt{val:0};
const M1: ModInt = ModInt{val:1};
const M_ERROR: ModInt = ModInt{val:-1};

impl ModInt {
    fn new(v: i64) -> ModInt {
        let t = v % M;
        ModInt{ val: if t < 0 {t+M} else {t} }
    }

    fn pow(self, exp: i64) -> ModInt {
        if exp == 0 {
            M1
        }
        else {
            let x = self.pow(exp / 2);
            if exp % 2 == 0 {
                x * x
            }
            else {
                self * x * x
            }
        }
    }

    fn inv(self) -> ModInt {
        self.pow(M - 2)
    }
}

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, rhs: ModInt) -> ModInt {
        let t = self.val + rhs.val;
        ModInt { val: if t >= M {t-M} else {t} }
    }
}
impl std::ops::Add<i64> for ModInt {
    type Output = ModInt;
    fn add(self, rhs: i64) -> ModInt {
        ModInt::new( self.val+rhs )
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: ModInt) -> ModInt {
        let t = self.val + M - rhs.val;
        ModInt { val: if t >= M {t-M} else {t} }
    }
}
impl std::ops::Sub<i64> for ModInt {
    type Output = ModInt;
    fn sub(self, rhs: i64) -> ModInt {
        self - ModInt::new(rhs)
    }
}
impl std::ops::Neg for ModInt {
    type Output = ModInt;
    fn neg(self) -> ModInt {
        ModInt { val: if self.val == 0 { 0 } else { M - self.val } }
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: ModInt) -> ModInt {
        ModInt { val: self.val * rhs.val % M }
    }
}
impl std::ops::Mul<i64> for ModInt {
    type Output = ModInt;
    fn mul(self, rhs: i64) -> ModInt {
        self * ModInt::new(rhs)
    }
}

impl std::ops::Div for ModInt {
    type Output = ModInt;
    fn div(self, rhs: ModInt) -> ModInt {
        self * rhs.inv()
    }
}
impl std::ops::Div<i64> for ModInt {
    type Output = ModInt;
    fn div(self, rhs: i64) -> ModInt {
        self / ModInt::new(rhs)
    }
}

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




//
// nCr
//
#[derive(Debug, Clone)]
struct Comb {
    fac: Vec<ModInt>,
    finv: Vec<ModInt>,
    inv: Vec<ModInt>,
}

impl Comb {
    fn new(size: usize) -> Comb {
        let mut fac = vec![M1; size];
        let mut finv = vec![M1; size];
        let mut inv = vec![M1; size];

        for i in 2..size {
            fac[i] = fac[i - 1] * (i as i64);
            inv[i] = -inv[M as usize % i] * (M / (i as i64));
            finv[i] = finv[i - 1] * inv[i];
        }

        return Comb {
            fac: fac,
            finv: finv,
            inv: inv,
        };
    }
}
trait CombC<T> {
    fn c(&self, n: T, k: T) -> ModInt;
    fn p(&self, n: T, k: T) -> ModInt;
}

impl CombC<usize> for Comb {
    fn c(&self, n: usize, k: usize) -> ModInt {
        if n < k {
            M0
        } else {
            self.fac[n] * self.finv[k] * self.finv[n - k]
        }
    }
    fn p(&self, n: usize, k: usize) -> ModInt {
        if n < k {
            M0
        } else {
            self.fac[n] * self.finv[n - k]
        }
    }
}



//#[proconio::fastout]
fn main() {
    input! {
        n:usize,
    }

    /* 奇数番目のAとBを入れ替える A<->B と、
       ABとBAは消せない → AAとBBは消せない になる。
       条件を満たす = (Aの文字数 <= N/2 && Bの文字数 <= N/2)
    */
    
    /* f(a,b,c) = (a+b+c)!/a!b!c! とする
       ans = Σ f(a,b,c) where 0<=a<=N/2 && 0<=b<=N/2
           = Σ f(a,b,c) where 1  -  Σ f(a,b,c) where N/2<a  -  Σ f(a,b,c) where N/2<b  

        Σ f(x,y,z) where N/2<x =   Σ ncr(n,x)*2^(n-x) where  N/2<x =   Σ ncr(n,y)*2^y where  y<N/2
    */

    let comb = Comb::new(n+1);
    let mut sum = M0;
    let mut p2 = M1;
    for y in 0..n/2 {
        sum = sum + comb.c(n,y)*p2;
        p2 = p2 + p2;
    }

    let p3 = ModInt::new(3).pow(n as i64);

    println!("{}", p3 - sum*2);
}