use proconio::{ input, marker::{Chars, Usize1}, }; fn main() { input! { n: usize, m: usize, s: Chars, ab: [(Usize1, Usize1); m], } let mut graph = vec![vec![]; n]; for (a, b) in ab { graph[a].push(b); graph[b].push(a); } let question_count = s.iter().filter(|&&x| x == '?').count(); let mut ans = 0; for start in 0..n { if s[start] == 'a' { dfs( start, 0, &mut ans, question_count, &mut vec![false; n], &s, &graph, ); } else if s[start] == '?' { dfs( start, 0, &mut ans, question_count - 1, &mut vec![false; n], &s, &graph, ); } } println!("{}", ans); } fn dfs( pos: usize, count: usize, ans: &mut usize, question_count: usize, visited: &mut Vec, s: &Vec, graph: &Vec>, ) { if count == 2 { *ans += pow(26, question_count); *ans %= 998244353; return; } let target = match count { 0 => 'o', 1 => 'i', _ => unreachable!(), }; for &next in &graph[pos] { if visited[next] { continue; } if s[next] == target { dfs(next, count + 1, ans, question_count, visited, s, graph); } else if s[next] == '?' { visited[next] = true; dfs(next, count + 1, ans, question_count - 1, visited, s, graph); visited[next] = false; } } } fn pow(mut n: usize, mut m: usize) -> usize { let mut r = 1; while m > 0 { if m & 1 == 1 { r *= n; r %= 998244353; } n *= n; n %= 998244353; m >>= 1; } r }