from typing import Any



class     _A   :






  def __init__(self   ,				SCREAMING_SNAKE_CASE_	)		->      str:





       '''simple docstring'''





       UpperCamelCase__										=      data
       UpperCamelCase__										=      None






  def __repr__(self	)		->      Dict:





       '''simple docstring'''





       return F"Node({self.data})"



class     _A   :






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





       '''simple docstring'''





       UpperCamelCase__										=      None






  def __iter__(self	)		->      List[Any]:





       '''simple docstring'''





       UpperCamelCase__										=      self.head
       while node:
            yield node.data
            UpperCamelCase__										=      node.next






  def __len__(self	)		->      Tuple:





       '''simple docstring'''





       return sum(1 for _ in self	)






  def __repr__(self	)		->      Union[str, Any]:





       '''simple docstring'''





       return "->".join([str(lowerCamelCase_	) for item in self]	)






  def __getitem__(self   ,				SCREAMING_SNAKE_CASE_	)		->      Optional[int]:





       '''simple docstring'''





       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   ,				SCREAMING_SNAKE_CASE_   ,				SCREAMING_SNAKE_CASE_	)		->      Any:





       '''simple docstring'''





       if not 0 <= index < len(self	):
            raise ValueError('''list index out of range.'''	)
       UpperCamelCase__										=      self.head
       for _ in range(lowerCamelCase_	):
            UpperCamelCase__										=      current.next
       UpperCamelCase__										=      data






  def 		_a					(self   ,				SCREAMING_SNAKE_CASE_	)		->      Optional[int]:





       '''simple docstring'''





       self.insert_nth(len(self	)   ,				lowerCamelCase_	)






  def 		_a					(self   ,				SCREAMING_SNAKE_CASE_	)		->      Optional[Any]:





       '''simple docstring'''





       self.insert_nth(0   ,				lowerCamelCase_	)






  def 		_a					(self   ,				SCREAMING_SNAKE_CASE_   ,				SCREAMING_SNAKE_CASE_	)		->      str:





       '''simple docstring'''





       if not 0 <= index <= len(self	):
            raise IndexError('''list index out of range'''	)
       UpperCamelCase__										=      Node(lowerCamelCase_	)
       if self.head is None:
            UpperCamelCase__										=      new_node
       elif index == 0:
            UpperCamelCase__										=      self.head  # link new_node to head
            UpperCamelCase__										=      new_node
       else:
            UpperCamelCase__										=      self.head
            for _ in range(index - 1	):
                 UpperCamelCase__										=      temp.next
            UpperCamelCase__										=      temp.next
            UpperCamelCase__										=      new_node






  def 		_a					(self	)		->      List[Any]:  # print every node data





       '''simple docstring'''





       print(self	)






  def 		_a					(self	)		->      Any:





       '''simple docstring'''





       return self.delete_nth(0	)






  def 		_a					(self	)		->      List[str]:  # delete from tail





       '''simple docstring'''





       return self.delete_nth(len(self	) - 1	)






  def 		_a					(self   ,				SCREAMING_SNAKE_CASE_ = 0	)		->      Any:





       '''simple docstring'''





       if not 0 <= index <= len(self	) - 1:  # test if index is valid
            raise IndexError('''List index out of range.'''	)
       UpperCamelCase__										=      self.head  # default first node
       if index == 0:
            UpperCamelCase__										=      self.head.next
       else:
            UpperCamelCase__										=      self.head
            for _ in range(index - 1	):
                 UpperCamelCase__										=      temp.next
            UpperCamelCase__										=      temp.next
            UpperCamelCase__										=      temp.next.next
       return delete_node.data






  def 		_a					(self	)		->      Any:





       '''simple docstring'''





       return self.head is None






  def 		_a					(self	)		->      Dict:





       '''simple docstring'''





       UpperCamelCase__										=      None
       UpperCamelCase__										=      self.head

       while current:
            # Store the current node's next node.
            UpperCamelCase__										=      current.next
            # Make the current node's next point backwards
            UpperCamelCase__										=      prev
            # Make the previous node be the current node
            UpperCamelCase__										=      current
            # Make the current node the next node (to progress iteration)
            UpperCamelCase__										=      next_node
       # Return prev in order to put the head at the end
       UpperCamelCase__										=      prev







def  __UpperCamelCase    (						):
     UpperCamelCase__										=      LinkedList()
     assert linked_list.is_empty() is True
     assert str(lowerCamelCase_							) == ""

     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(lowerCamelCase_							) == i
          linked_list.insert_nth(lowerCamelCase_ ,							i + 1							)
     assert str(lowerCamelCase_							) == "->".join(str(lowerCamelCase_							) for i in range(1 ,							11							)							)

     linked_list.insert_head(0							)
     linked_list.insert_tail(11							)
     assert str(lowerCamelCase_							) == "->".join(str(lowerCamelCase_							) 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(lowerCamelCase_							) == 9
     assert str(lowerCamelCase_							) == "->".join(str(lowerCamelCase_							) 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							):
          UpperCamelCase__										=      -i
     assert all(linked_list[i] == -i for i in range(0 ,							9							)							) is True

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







def  __UpperCamelCase    (						):
     UpperCamelCase__										=      [
         -9,
         100,
         Node(77345112							),
         """dlrow olleH""",
         7,
         5555,
         0,
         -1_92.5_55_55,
         """Hello, world!""",
         77.9,
         Node(10							),
         None,
         None,
         12.20,
     ]
     UpperCamelCase__										=      LinkedList()

     for i in test_input:
          linked_list.insert_tail(lowerCamelCase_							)

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

     # Delete the head
     UpperCamelCase__										=      linked_list.delete_head()
     assert result == -9
     assert (
         str(lowerCamelCase_							) == "100->Node(77345112)->dlrow olleH->7->5555->0->-192.55555->"
         "Hello, world!->77.9->Node(10)->None->None->12.2"
     )

     # Delete the tail
     UpperCamelCase__										=      linked_list.delete_tail()
     assert result == 12.2
     assert (
         str(lowerCamelCase_							) == "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
     UpperCamelCase__										=      linked_list.delete_nth(10							)
     assert result is None
     assert (
         str(lowerCamelCase_							) == "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(lowerCamelCase_							)
         == "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(lowerCamelCase_							)
     assert (
         str(lowerCamelCase_							)
         == "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(lowerCamelCase_							)
         == "None->None->Node(10)->77.9->Hello, world!->-192.55555->0->5555->"
         "7->dlrow olleH->Node(77345112)->100->Node(Hello again, world!)"
     )







def  __UpperCamelCase    (						):
     from doctest import testmod

     testmod()

     UpperCamelCase__										=      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(lowerCamelCase_							)
     print('''\nReading/changing Node data using indexing:'''							)
     print(f"Element at Position 1: {linked_list[1]}"							)
     UpperCamelCase__										=      input('''Enter New Value: '''							).strip()
     print('''New list:'''							)
     print(lowerCamelCase_							)
     print(f"length of linked_list is : {len(lowerCamelCase_							)}"							)


if __name__ == "__main__":
     main()




def  __UpperCamelCase    (						A = 600851475143							):

     try:
          UpperCamelCase__										=      int(A							)
     except (TypeError, ValueError):
          raise TypeError('''Parameter n must be int or castable to int.'''							)
     if n <= 0:
          raise ValueError('''Parameter n must be greater than or equal to one.'''							)
     UpperCamelCase__										=      1
     UpperCamelCase__										=      2
     while i * i <= n:
          while n % i == 0:
               UpperCamelCase__										=      i
               n //= i
          i += 1
     if n > 1:
          UpperCamelCase__										=      n
     return int(A							)


if __name__ == "__main__":
     print(f"""{solution() = }""")



