Just a runnable solution
Code\n\nimpl Solution {\n    pub fn find_good_strings(n: i32, s1: String, s2: String, evil: String) -> i32 {\n        let mut dp = vec![vec![vec![vec![0; 2]; 2]
# Code\n```\nimpl Solution {\n    pub fn find_good_strings(n: i32, s1: String, s2: String, evil: String) -> i32 {\n        let mut dp = vec![vec![vec![vec![0; 2]; 2]; evil.len() + 1]; n as usize + 1];\n        let lps = Self::compute_lps(&evil);\n        Self::dfs(0, 0, true, true, n, &s1, &s2, &evil, &lps, &mut dp)\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    fn dfs(\n        i: usize,\n        evil_matched: usize,\n        left_bound: bool,\n        right_bound: bool,\n        n: i32,\n        s1: &String,\n        s2: &String,\n        evil: &String,\n        lps: &Vec<usize>,\n        dp: &mut Vec<Vec<Vec<Vec<i32>>>>,\n    ) -> i32 {\n        if evil_matched == evil.len() {\n            return 0;\n        }\n        if i == n as usize {\n            return 1;\n        }\n        if dp[i][evil_matched][left_bound as usize][right_bound as usize] != 0 {\n            return dp[i][evil_matched][left_bound as usize][right_bound as usize];\n        }\n        let from = if left_bound { s1.as_bytes()[i] } else { b\'a\' };\n        let to = if right_bound { s2.as_bytes()[i] } else { b\'z\' };\n        let mut res = 0;\n        for c in from..=to {\n            let mut j = evil_matched;\n            while j > 0 && evil.as_bytes()[j] != c {\n                j = lps[j - 1];\n            }\n            if evil.as_bytes()[j] == c {\n                j += 1;\n            }\n            res += Self::dfs(\n                i + 1,\n                j,\n                left_bound && (c == from),\n                right_bound && (c == to),\n                n,\n                s1,\n                s2,\n                evil,\n                lps,\n                dp,\n            );\n            res %= 1000000007;\n        }\n        dp[i][evil_matched][left_bound as usize][right_bound as usize] = res;\n        res\n    }\n\n    fn compute_lps(str: &String) -> Vec<usize> {\n        let n = str.len();\n        let mut lps = vec![0; n];\n        for i in 1..n {\n            let mut j = lps[i - 1];\n            while j > 0 && str.as_bytes()[i] != str.as_bytes()[j] {\n                j = lps[j - 1];\n            }\n            if str.as_bytes()[i] == str.as_bytes()[j] {\n                lps[i] = j + 1;\n            }\n        }\n        lps\n    }\n}\n```
['Rust']