use proconio::{fastout, input, marker::Bytes}; #[fastout] fn main() { input! { n: usize, c: [Bytes; n], } println!("{}", output(solve(c))) } fn solve(c: Vec>) -> u32 { let n = c.len(); let mut dp = [vec![vec![0; n]; n], vec![vec![0; n]; n]]; if c[0][0] == c[n - 1][n - 1] { dp[0][0][n - 1] = 1; } for i in 0..(n - 1) { for j in 0..=(i + 1) { dp[(i & 1) ^ 1][j].fill(0); } for j in 0..=i { for k in (n - 1 - i)..=(n - 1) { if c[j][i - j + 1] == c[k][(n - 1) - i + ((n - 1) - k) - 1] { dp[(i & 1) ^ 1][j][k] = (dp[(i & 1) ^ 1][j][k] + dp[i & 1][j][k]) % 998244353; } if c[j + 1][i - j] == c[k][(n - 1) - i + ((n - 1) - k) - 1] { dp[(i & 1) ^ 1][j + 1][k] = (dp[(i & 1) ^ 1][j + 1][k] + dp[i & 1][j][k]) % 998244353; } if c[j][i - j + 1] == c[k - 1][(n - 1) - i + ((n - 1) - k)] { dp[(i & 1) ^ 1][j][k - 1] = (dp[(i & 1) ^ 1][j][k - 1] + dp[i & 1][j][k]) % 998244353; } if c[j + 1][i - j] == c[k - 1][(n - 1) - i + ((n - 1) - k)] { dp[(i & 1) ^ 1][j + 1][k - 1] = (dp[(i & 1) ^ 1][j + 1][k - 1] + dp[i & 1][j][k]) % 998244353; } } } } (0..=(n - 1)) .map(|i| dp[(n - 1) & 1][i][i]) .fold(0, |acc, x| (acc + x) % 998244353) } fn output(ans: u32) -> u32 { ans }