






from typing import Any







class  _lowercase   :
      def __init__(     self				,			a   ):
       snake_case__  :    str							       =data
       snake_case__  :    Optional[int]							       =None



      def __repr__(     self   ):
       return F"Node({self.data})"







class  _lowercase   :
      def __init__(     self   ):
       snake_case__  :    Optional[int]							       =None
      def __iter__(     self   ):
       snake_case__  :    List[Any]							       =self.head
       while node:
        yield node.data
        snake_case__  :    Optional[Any]							       =node.next
      def __len__(     self   ):
       return sum(1 for _ in self   )
      def __repr__(     self   ):
       return "->".join([str(a   ) for item in self]   )
      def __getitem__(     self				,			a   ):
       if not 0 <= index < len(self   ):
        raise ValueError("""list index out of range."""   )
       for i, node in enumerate(self   ):
        if i == index:
         return node
       return None
      def __setitem__(     self				,			a				,			a   ):
       if not 0 <= index < len(self   ):
        raise ValueError("""list index out of range."""   )
       snake_case__  :    List[str]							       =self.head
       for _ in range(a   ):
        snake_case__  :    Optional[int]							       =current.next
       snake_case__  :    List[str]							       =data
      def 						lowercase__					(     self				,			a   ):
       self.insert_nth(len(self   )				,			a   )
      def 						lowercase__					(     self				,			a   ):
       self.insert_nth(0				,			a   )
      def 						lowercase__					(     self				,			a				,			a   ):
       if not 0 <= index <= len(self   ):
        raise IndexError("""list index out of range"""   )
       snake_case__  :    Optional[Any]							       =Node(a   )
       if self.head is None:
        snake_case__  :    Union[str, Any]							       =new_node
       elif index == 0:
        snake_case__  :    Dict							       =self.head  # link new_node to head
        snake_case__  :    Optional[int]							       =new_node
       else:
        snake_case__  :    List[str]							       =self.head
        for _ in range(index - 1   ):
         snake_case__  :    int							       =temp.next
        snake_case__  :    int							       =temp.next
        snake_case__  :    int							       =new_node
      def 						lowercase__					(     self   ):  # print every node data
       print(self   )
      def 						lowercase__					(     self   ):
       return self.delete_nth(0   )
      def 						lowercase__					(     self   ):  # delete from tail
       return self.delete_nth(len(self   ) - 1   )
      def 						lowercase__					(     self				,			a = 0   ):
       if not 0 <= index <= len(self   ) - 1:  # test if index is valid
        raise IndexError("""List index out of range."""   )
       snake_case__  :    Dict							       =self.head  # default first node
       if index == 0:
        snake_case__  :    List[Any]							       =self.head.next
       else:
        snake_case__  :    Dict							       =self.head
        for _ in range(index - 1   ):
         snake_case__  :    List[str]							       =temp.next
        snake_case__  :    List[Any]							       =temp.next
        snake_case__  :    Union[str, Any]							       =temp.next.next
       return delete_node.data
      def 						lowercase__					(     self   ):
       return self.head is None



      def 						lowercase__					(     self   ):
       snake_case__  :    List[str]							       =None
       snake_case__  :    List[Any]							       =self.head

       while current:
        # Store the current node's next node.
        snake_case__  :    List[str]							       =current.next
        # Make the current node's next point backwards
        snake_case__  :    Optional[int]							       =prev
        # Make the previous node be the current node
        snake_case__  :    Any							       =current
        # Make the current node the next node (to progress iteration)
        snake_case__  :    Optional[int]							       =next_node
       # Return prev in order to put the head at the end
       snake_case__  :    Any							       =prev







def 			A__							(      ):





 '''simple docstring'''







 snake_case__  :    Optional[int]							       =LinkedList()
 assert linked_list.is_empty() is True
 assert str(_a	) == ""

 try:
  linked_list.delete_head()
  raise AssertionError  # This should not happen.
 except IndexError:
  assert True  # This should happen.

 try:
  linked_list.delete_tail()
  raise AssertionError  # This should not happen.
 except IndexError:
  assert True  # This should happen.

 for i in range(10	):
  assert len(_a	) == i
  linked_list.insert_nth(_a		,  i + 1	)
 assert str(_a	) == "->".join(str(_a	) for i in range(1		,  11	)	)

 linked_list.insert_head(0	)
 linked_list.insert_tail(11	)
 assert str(_a	) == "->".join(str(_a	) for i in range(0		,  12	)	)

 assert linked_list.delete_head() == 0
 assert linked_list.delete_nth(9	) == 10
 assert linked_list.delete_tail() == 11
 assert len(_a	) == 9
 assert str(_a	) == "->".join(str(_a	) for i in range(1		,  10	)	)

 assert all(linked_list[i] == i + 1 for i in range(0		,  9	)	) is True

 for i in range(0		,  9	):
  snake_case__  :    Dict							       =-i
 assert all(linked_list[i] == -i for i in range(0		,  9	)	) is True

 linked_list.reverse()
 assert str(_a	) == "->".join(str(_a	) for i in range(-8		,  1	)	)







def 			A__							(      ):





 '''simple docstring'''







 snake_case__  :    Tuple							       =[
     -9,
     100,
     Node(77345112	),
     """dlrow olleH""",
     7,
     5555,
     0,
     -1_9_2.5_5_5_5_5,
     """Hello, world!""",
     7_7.9,
     Node(10	),
     None,
     None,
     1_2.2_0,
 ]
 snake_case__  :    List[Any]							       =LinkedList()

 for i in test_input:
  linked_list.insert_tail(_a	)

 # Check if it's empty or not
 assert linked_list.is_empty() is False
 assert (
     str(_a	) == "-9->100->Node(77345112)->dlrow olleH->7->5555->0->"
     "-192.55555->Hello, world!->77.9->Node(10)->None->None->12.2"
 )

 # Delete the head
 snake_case__  :    List[Any]							       =linked_list.delete_head()
 assert result == -9
 assert (
     str(_a	) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
     "Hello, world!->77.9->Node(10)->None->None->12.2"
 )

 # Delete the tail
 snake_case__  :    Optional[Any]							       =linked_list.delete_tail()
 assert result == 1_2.2
 assert (
     str(_a	) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
     "Hello, world!->77.9->Node(10)->None->None"
 )

 # Delete a node in specific location in linked list
 snake_case__  :    Union[str, Any]							       =linked_list.delete_nth(10	)
 assert result is None
 assert (
     str(_a	) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
     "Hello, world!->77.9->Node(10)->None"
 )

 # Add a Node instance to its head
 linked_list.insert_head(Node("""Hello again, world!"""	)	)
 assert (
     str(_a	)
     == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
     "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None"
 )

 # Add None to its tail
 linked_list.insert_tail(_a	)
 assert (
     str(_a	)
     == "Node(Hello again, world!)->100->Node(77345112)->dlrow olleH->"
     "7->5555->0->-192.55555->Hello, world!->77.9->Node(10)->None->None"
 )

 # Reverse the linked list
 linked_list.reverse()
 assert (
     str(_a	)
     == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
     "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
 )







def 			A__							(      ):





 '''simple docstring'''







 from doctest import testmod

 testmod()

 snake_case__  :    Any							       =LinkedList()
 linked_list.insert_head(input("""Inserting 1st at head """	).strip()	)
 linked_list.insert_head(input("""Inserting 2nd at head """	).strip()	)
 print("""\nPrint list:"""	)
 linked_list.print_list()
 linked_list.insert_tail(input("""\nInserting 1st at tail """	).strip()	)
 linked_list.insert_tail(input("""Inserting 2nd at tail """	).strip()	)
 print("""\nPrint list:"""	)
 linked_list.print_list()
 print("""\nDelete head"""	)
 linked_list.delete_head()
 print("""Delete tail"""	)
 linked_list.delete_tail()
 print("""\nPrint list:"""	)
 linked_list.print_list()
 print("""\nReverse linked list"""	)
 linked_list.reverse()
 print("""\nPrint list:"""	)
 linked_list.print_list()
 print("""\nString representation of linked list:"""	)
 print(_a	)
 print("""\nReading/changing Node data using indexing:"""	)
 print(f"Element at Position 1: {linked_list[1]}"	)
 snake_case__  :    str							       =input("""Enter New Value: """	).strip()
 print("""New list:"""	)
 print(_a	)
 print(f"length of linked_list is : {len(_a	)}"	)


if __name__ == "__main__":
       main()













def 			A__							(      _a  :					Any		,  _a  :					Optional[Any]		,  _a  :					int		,  _a  :					Any	):





 '''simple docstring'''







 if height >= 1:
  move_tower(height - 1		,  _a		,  _a		,  _a	)
  move_disk(_a		,  _a	)
  move_tower(height - 1		,  _a		,  _a		,  _a	)







def 			A__							(      _a  :					Optional[int]		,  _a  :					str	):





 '''simple docstring'''







 print("""moving disk from"""		,  _a		,  """to"""		,  _a	)







def 			A__							(      ):





 '''simple docstring'''







 snake_case__  :    Dict							       =int(input("""Height of hanoi: """	).strip()	)
 move_tower(_a		,  """A"""		,  """B"""		,  """C"""	)


if __name__ == "__main__":
       main()





