from __future__ import annotations

from collections import deque


class 			UpperCAmelCase__    :



  """simple docstring"""






  def __init__(				self:			Union[str, Any]				,				__lowerCAmelCase:			list[str]   ) -> Dict:




    '''simple docstring'''




    __UpperCAmelCase						    =       []
    self.adlist.append(
        {"value": "", "next_states": [], "fail_state": 0, "output": []}   )

    for keyword in keywords:
      self.add_keyword(__lowerCAmelCase   )
    self.set_fail_transitions()






  def 	_UpperCAmelCase				(				self:			Dict				,				__lowerCAmelCase:			int				,				__lowerCAmelCase:			str   ) -> int | None:




    '''simple docstring'''




    for state in self.adlist[current_state]["next_states"]:
      if char == self.adlist[state]["value"]:
        return state
    return None






  def 	_UpperCAmelCase				(				self:			Union[str, Any]				,				__lowerCAmelCase:			str   ) -> None:




    '''simple docstring'''




    __UpperCAmelCase						    =       0
    for character in keyword:
      __UpperCAmelCase						    =       self.find_next_state(__lowerCAmelCase				,				__lowerCAmelCase   )
      if next_state is None:
        self.adlist.append(
            {
                "value": character,
                "next_states": [],
                "fail_state": 0,
                "output": [],
            }   )
        self.adlist[current_state]["next_states"].append(len(self.adlist   ) - 1   )
        __UpperCAmelCase						    =       len(self.adlist   ) - 1
      else:
        __UpperCAmelCase						    =       next_state
    self.adlist[current_state]["output"].append(__lowerCAmelCase   )






  def 	_UpperCAmelCase				(				self:			Optional[int]   ) -> None:




    '''simple docstring'''




    __UpperCAmelCase						    =       deque()
    for node in self.adlist[0]["next_states"]:
      q.append(__lowerCAmelCase   )
      __UpperCAmelCase						    =       0
    while q:
      __UpperCAmelCase						    =       q.popleft()
      for child in self.adlist[r]["next_states"]:
        q.append(__lowerCAmelCase   )
        __UpperCAmelCase						    =       self.adlist[r]["fail_state"]
        while (
            self.find_next_state(__lowerCAmelCase				,				self.adlist[child]["value"]   ) is None
            and state != 0
        ):
          __UpperCAmelCase						    =       self.adlist[state]["fail_state"]
        __UpperCAmelCase						    =       self.find_next_state(
            __lowerCAmelCase				,				self.adlist[child]["value"]   )
        if self.adlist[child]["fail_state"] is None:
          __UpperCAmelCase						    =       0
        __UpperCAmelCase						    =       (
            self.adlist[child]["output"]
            + self.adlist[self.adlist[child]["fail_state"]]["output"]
        )






  def 	_UpperCAmelCase				(				self:			Union[str, Any]				,				__lowerCAmelCase:			str   ) -> dict[str, list[int]]:




    '''simple docstring'''




    __UpperCAmelCase						    =       {}  # returns a dict with keywords and list of its occurrences
    __UpperCAmelCase						    =       0
    for i in range(len(__lowerCAmelCase   )   ):
      while (
          self.find_next_state(__lowerCAmelCase				,				string[i]   ) is None
          and current_state != 0
      ):
        __UpperCAmelCase						    =       self.adlist[current_state]["fail_state"]
      __UpperCAmelCase						    =       self.find_next_state(__lowerCAmelCase				,				string[i]   )
      if next_state is None:
        __UpperCAmelCase						    =       0
      else:
        __UpperCAmelCase						    =       next_state
        for key in self.adlist[current_state]["output"]:
          if key not in result:
            __UpperCAmelCase						    =       []
          result[key].append(i - len(__lowerCAmelCase   ) + 1   )
    return result


if __name__ == "__main__":
       import doctest

       doctest.testmod()




def       __lowerCAmelCase      (						A_   : str					)    ->  Any:
  if not head:
    return True
  # split the list to two parts
  __UpperCAmelCase    ,		__UpperCAmelCase						    =       head.next, head
  while fast and fast.next:
    __UpperCAmelCase						    =       fast.next.next
    __UpperCAmelCase						    =       slow.next
  __UpperCAmelCase						    =       slow.next
  __UpperCAmelCase						    =       None  # Don't forget here! But forget still works!
  # reverse the second part
  __UpperCAmelCase						    =       None
  while second:
    __UpperCAmelCase						    =       second.next
    __UpperCAmelCase						    =       node
    __UpperCAmelCase						    =       second
    __UpperCAmelCase						    =       nxt
  # compare two parts
  # second part has the same or one less node
  while node:
    if node.val != head.val:
      return False
    __UpperCAmelCase						    =       node.next
    __UpperCAmelCase						    =       head.next
  return True




def       __lowerCAmelCase      (						A_   : Optional[Any]					)    ->  Optional[Any]:
  if not head or not head.next:
    return True

  # 1. Get the midpoint (slow)
  __UpperCAmelCase						    =       __UpperCAmelCase						    =       __UpperCAmelCase						    =       head
  while fast and fast.next:
    __UpperCAmelCase    ,		__UpperCAmelCase						    =       fast.next.next, slow.next

  # 2. Push the second half into the stack
  __UpperCAmelCase						    =       [slow.val]
  while slow.next:
    __UpperCAmelCase						    =       slow.next
    stack.append(slow.val					)

  # 3. Comparison
  while stack:
    if stack.pop() != cur.val:
      return False
    __UpperCAmelCase						    =       cur.next

  return True





def       __lowerCAmelCase      (						A_   : int					)    ->  Optional[int]:
  if not head or not head.next:
    return True
  __UpperCAmelCase						    =       {}
  __UpperCAmelCase						    =       0
  while head:
    if head.val in d:
      d[head.val].append(A_					)
    else:
      __UpperCAmelCase						    =       [pos]
    __UpperCAmelCase						    =       head.next
    pos += 1
  __UpperCAmelCase						    =       pos - 1
  __UpperCAmelCase						    =       0
  for v in d.values():
    if len(A_					) % 2 != 0:
      middle += 1
    else:
      __UpperCAmelCase						    =       0
      for i in range(0						,	len(A_					)					):
        if v[i] + v[len(A_					) - 1 - step] != checksum:
          return False
        step += 1
    if middle > 1:
      return False
  return True



