class TrieNode:
  def __init__(self):
    self.children: dict[str, TrieNode] = {}
    self.isWord = False
class Trie:
  def __init__(self):
    self.root = TrieNode()
  def insert(self, word: str) -> None:
    node: TrieNode = self.root
    for c in word:
      node = node.children.setdefault(c, TrieNode())
    node.isWord = True
  def search(self, word: str, l: int, r: int) -> bool:
    node: TrieNode = self.root
    for i in range(l, r):
      if word[i] not in node.children:
        return False
      node = node.children[word[i]]
    return node.isWord
class Solution:
  def longestValidSubstring(self, word: str, forbidden: list[str]) -> int:
    ans = 0
    trie = Trie()
    for s in forbidden:
      trie.insert(s)
    # r is the rightmost index to make word[l..r] a valid substring.
    r = len(word) - 1
    for l in range(len(word) - 1, -1, -1):
      for end in range(l, min(l + 10, r + 1)):
        if trie.search(word, l, end + 1):
          r = end - 1
          break
      ans = max(ans, r - l + 1)
    return ans