



class 		__SCREAMING_SNAKE_CASE      :






				"""simple docstring"""

				def __init__(				self						,	SCREAMING_SNAKE_CASE__      ):






					"""simple docstring"""

					_snake_case					:							List[Any]					     =   data
					_snake_case					:							Union[str, Any]					     =   None
					_snake_case					:							str					     =   None







				def __str__(				self      ):






					"""simple docstring"""

					return f'''{self.data}'''





class 		__SCREAMING_SNAKE_CASE      :






				"""simple docstring"""

				def __init__(				self      ):






					"""simple docstring"""

					_snake_case					:							str					     =   None
					_snake_case					:							List[str]					     =   None







				def __iter__(				self      ):






					"""simple docstring"""

					_snake_case					:							int					     =   self.head
					while node:
						yield node.data
						_snake_case					:							Dict					     =   node.next







				def __str__(				self      ):






					"""simple docstring"""

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







				def __len__(				self      ):






					"""simple docstring"""

					return sum(1 for _ in self      )







				def 		__lowerCamelCase(				self						,	SCREAMING_SNAKE_CASE__      ):






					"""simple docstring"""

					self.insert_at_nth(0						,	UpperCamelCase__      )







				def 		__lowerCamelCase(				self						,	SCREAMING_SNAKE_CASE__      ):






					"""simple docstring"""

					self.insert_at_nth(len(self      )						,	UpperCamelCase__      )







				def 		__lowerCamelCase(				self						,	SCREAMING_SNAKE_CASE__						,	SCREAMING_SNAKE_CASE__      ):






					"""simple docstring"""

					_snake_case					:							int					     =   len(self      )

					if not 0 <= index <= length:
						raise IndexError("""list index out of range"""      )
					_snake_case					:							Union[str, Any]					     =   Node(UpperCamelCase__      )
					if self.head is None:
						_snake_case					:							Optional[Any]					     =   new_node
					elif index == 0:
						_snake_case					:							Union[str, Any]					     =   new_node
						_snake_case					:							Dict					     =   self.head
						_snake_case					:							List[str]					     =   new_node
					elif index == length:
						_snake_case					:							List[str]					     =   new_node
						_snake_case					:							Union[str, Any]					     =   self.tail
						_snake_case					:							List[Any]					     =   new_node
					else:
						_snake_case					:							List[str]					     =   self.head
						for _ in range(0						,	UpperCamelCase__      ):
							_snake_case					:							List[Any]					     =   temp.next
						_snake_case					:							Tuple					     =   new_node
						_snake_case					:							int					     =   temp.previous
						_snake_case					:							int					     =   temp
						_snake_case					:							Any					     =   new_node







				def 		__lowerCamelCase(				self      ):






					"""simple docstring"""

					return self.delete_at_nth(0      )







				def 		__lowerCamelCase(				self      ):






					"""simple docstring"""

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







				def 		__lowerCamelCase(				self						,	SCREAMING_SNAKE_CASE__      ):






					"""simple docstring"""

					_snake_case					:							Dict					     =   len(self      )

					if not 0 <= index <= length - 1:
						raise IndexError("""list index out of range"""      )
					_snake_case					:							Union[str, Any]					     =   self.head  # default first node
					if length == 1:
						_snake_case					:							Tuple					     =   None
					elif index == 0:
						_snake_case					:							Optional[int]					     =   self.head.next
						_snake_case					:							Union[str, Any]					     =   None
					elif index == length - 1:
						_snake_case					:							str					     =   self.tail
						_snake_case					:							Dict					     =   self.tail.previous
						_snake_case					:							int					     =   None
					else:
						_snake_case					:							Tuple					     =   self.head
						for _ in range(0						,	UpperCamelCase__      ):
							_snake_case					:							Optional[int]					     =   temp.next
						_snake_case					:							List[str]					     =   temp
						_snake_case					:							str					     =   temp.previous
						_snake_case					:							str					     =   temp.next
					return delete_node.data







				def 		__lowerCamelCase(				self						,	SCREAMING_SNAKE_CASE__      ):






					"""simple docstring"""

					_snake_case					:							Union[str, Any]					     =   self.head

					while current.data != data:  # Find the position to delete
						if current.next:
							_snake_case					:							int					     =   current.next
						else:  # We have reached the end an no value matches
							raise ValueError("""No data matching given value"""      )

					if current == self.head:
						self.delete_head()

					elif current == self.tail:
						self.delete_tail()

					else:  # Before: 1 <--> 2(current) <--> 3
						_snake_case					:							Union[str, Any]					     =   current.next  # 1 --> 3
						_snake_case					:							Any					     =   current.previous  # 1 <--> 3
					return data







				def 		__lowerCamelCase(				self      ):






					"""simple docstring"""

					return len(self      ) == 0
def   UpperCAmelCase							(		)							->					None:
	_snake_case					:							Dict					     =   DoublyLinkedList()
	assert linked_list.is_empty() is True
	assert str(__UpperCamelCase     ) == ""

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

	linked_list.insert_at_head(0     )
	linked_list.insert_at_tail(11     )
	assert str(__UpperCamelCase     ) == "->".join(str(__UpperCamelCase     ) for i in range(0				,  12     )     )

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


if __name__ == "__main__":
						from doctest import testmod

						testmod()







def 					SCREAMING_SNAKE_CASE  (   __UpperCamelCase			:    list[int]							)			->							int:

				"""simple docstring"""







				if not isinstance(__UpperCamelCase				,    __UpperCamelCase							) or not all(
				    isinstance(__UpperCamelCase				,    __UpperCamelCase							) and item >= 0 for item in citations							):
								raise ValueError('''The citations should be a list of non negative integers.'''							)

				citations.sort()
				A__	:						str								=				len(__UpperCamelCase							)

				for i in range(__UpperCamelCase							):
								if citations[len_citations - 1 - i] <= i:
												return i

				return len_citations


if __name__ == "__main__":
					import doctest

					doctest.testmod()