#![allow(unused_imports)] fn main() { input! { n: usize, s: [Chars; n], } let mut dp = HashMap::new(); for i in 0..n { dp.insert((n-1-i, i, n-1-i, i), 1); } for _ in 0..n-1 { let mut ndp = HashMap::new(); for ((a, b, c, d), v) in dp { for (da, db) in [(-1, 0), (0, -1)] { for (dc, dd) in [(1, 0), (0, 1)] { let na = a.wrapping_add_signed(da); let nb = b.wrapping_add_signed(db); let nc = c.wrapping_add_signed(dc); let nd = d.wrapping_add_signed(dd); if na < n && nb < n && nc < n && nd < n && s[na][nb] == s[nc][nd] { let e = ndp.entry((na, nb, nc, nd)).or_default(); *e = (*e + v) % 998244353; } } } } dp = ndp; } println!("{}", dp.get(&(0, 0, n-1, n-1)).unwrap_or(&0)); } use proconio::{input, marker::*}; use std::{cmp::Reverse, collections::*}; #[macro_export] macro_rules! chmax { ($a:expr, $b:expr) => {{ let tmp = $b; if $a < tmp { $a = tmp; true } else { false } }}; } #[macro_export] macro_rules! chmin { ($a:expr, $b:expr) => {{ let tmp = $b; if $a > tmp { $a = tmp; true } else { false } }}; } #[macro_export] /// mvec![] macro_rules! mvec { ($val:expr; ()) => { $val }; ($val:expr; ($size:expr $(,$rest:expr)*)) => { vec![mvec![$val; ($($rest),*)]; $size] }; }