





"""simple docstring"""




from collections.abc import Iterable
from typing import Any


class        __UpperCamelCase				:






							def __init__(   self      ,					lowerCAmelCase__ = None      )	-> List[str]:
								a      :		Optional[Any]	=				value
								a      :		Node | None	=				None  # Added in order to delete a node easier
								a      :		Node | None	=				None
								a      :		Node | None	=				None






							def __repr__(   self      )	-> str:
								from pprint import pformat

								if self.left is None and self.right is None:
									return str(self.value      )
								return pformat({f"""{self.value}""": (self.left, self.right)}      ,					indent=1      )


class        __UpperCamelCase				:






							def __init__(   self      ,					lowerCAmelCase__ = None      )	-> Tuple:
								a      :		Dict	=				root






							def __str__(   self      )	-> str:
								return str(self.root      )






							def     __a   (   self      ,					lowerCAmelCase__      ,					lowerCAmelCase__      )	-> None:
								if new_children is not None:  # reset its kids
									a      :		Dict	=				node.parent
								if node.parent is not None:  # reset its parent
									if self.is_right(lowerCAmelCase__      ):  # If it is the right children
										a      :		Any	=				new_children
									else:
										a      :		Dict	=				new_children
								else:
									a      :		Any	=				new_children






							def     __a   (   self      ,					lowerCAmelCase__      )	-> bool:
								if node.parent and node.parent.right:
									return node == node.parent.right
								return False






							def     __a   (   self      )	-> bool:
								return self.root is None






							def     __a   (   self      ,					lowerCAmelCase__      )	-> None:
								a      :		int	=				Node(lowerCAmelCase__      )  # create a new Node
								if self.empty():  # if Tree is empty
									a      :		Union[str, Any]	=				new_node  # set its root
								else:  # Tree is not empty
									a      :		Any	=				self.root  # from root
									if parent_node is None:
										return
									while True:  # While we don't get to a leaf
										if value < parent_node.value:  # We go left
											if parent_node.left is None:
												a      :		Dict	=				new_node  # We insert the new node in a leaf
												break
											else:
												a      :		Optional[int]	=				parent_node.left
										else:
											if parent_node.right is None:
												a      :		List[str]	=				new_node
												break
											else:
												a      :		Tuple	=				parent_node.right
									a      :		Union[str, Any]	=				parent_node






							def     __a   (   self      ,					*lowerCAmelCase__      )	-> None:
								for value in values:
									self.__insert(lowerCAmelCase__      )






							def     __a   (   self      ,					lowerCAmelCase__      )	-> Node | None:
								if self.empty():
									raise IndexError("Warning: Tree is empty! please use another."      )
								else:
									a      :		Any	=				self.root
									# use lazy evaluation here to avoid NoneType Attribute error
									while node is not None and node.value is not value:
										a      :		Tuple	=				node.left if value < node.value else node.right
									return node






							def     __a   (   self      ,					lowerCAmelCase__ = None      )	-> Node | None:
								if node is None:
									if self.root is None:
										return None
									a      :		List[str]	=				self.root

								if not self.empty():
									while node.right is not None:
										a      :		Any	=				node.right
								return node






							def     __a   (   self      ,					lowerCAmelCase__ = None      )	-> Node | None:
								if node is None:
									a      :		str	=				self.root
								if self.root is None:
									return None
								if not self.empty():
									a      :		Any	=				self.root
									while node.left is not None:
										a      :		Dict	=				node.left
								return node






							def     __a   (   self      ,					lowerCAmelCase__      )	-> None:
								a      :		List[str]	=				self.search(lowerCAmelCase__      )  # Look for the node with that label
								if node is not None:
									if node.left is None and node.right is None:  # If it has no children
										self.__reassign_nodes(lowerCAmelCase__      ,					lowerCAmelCase__      )
									elif node.left is None:  # Has only right children
										self.__reassign_nodes(lowerCAmelCase__      ,					node.right      )
									elif node.right is None:  # Has only left children
										self.__reassign_nodes(lowerCAmelCase__      ,					node.left      )
									else:
										a      :		Union[str, Any]	=				self.get_max(
										    node.left      )  # Gets the max value of the left branch
										self.remove(tmp_node.value      )  # type: ignore
										a      :		List[str]	=				(
										    tmp_node.value  # type: ignore
										)  # Assigns the value to the node to delete and keep tree structure






							def     __a   (   self      ,					lowerCAmelCase__      )	-> Iterable:
								if node is not None:
									yield node  # Preorder Traversal
									yield from self.preorder_traverse(node.left      )
									yield from self.preorder_traverse(node.right      )






							def     __a   (   self      ,					lowerCAmelCase__=None      )	-> Any:
								if traversal_function is None:
									return self.preorder_traverse(self.root      )
								else:
									return traversal_function(self.root      )






							def     __a   (   self      ,					lowerCAmelCase__      ,					lowerCAmelCase__      )	-> None:
								if node:
									self.inorder(lowerCAmelCase__      ,					node.left      )
									arr.append(node.value      )
									self.inorder(lowerCAmelCase__      ,					node.right      )






							def     __a   (   self      ,					lowerCAmelCase__      ,					lowerCAmelCase__      )	-> int:
								a      :		list[int]	=				[]
								self.inorder(lowerCAmelCase__      ,					lowerCAmelCase__      )  # append all values to list using inorder traversal
								return arr[k - 1]






def       _SCREAMING_SNAKE_CASE		(	_lowercase						:    Node | None					) ->list[Node]:






	'''simple docstring'''






	a      :		List[str]	=				[]
	if curr_node is not None:
		a      :		Dict	=				postorder(curr_node.left					) + postorder(curr_node.right					) + [curr_node]
	return node_list






def       _SCREAMING_SNAKE_CASE		(	) ->None:






	'''simple docstring'''






	a      :		Dict	=				(8, 3, 6, 1, 10, 14, 13, 4, 7)
	a      :		Union[str, Any]	=				BinarySearchTree()
	for i in testlist:
		t.insert(_lowercase					)

	# Prints all the elements of the list in order traversal
	print(_lowercase					)

	if t.search(6					) is not None:
		print("The value 6 exists"					)
	else:
		print("The value 6 doesn't exist"					)

	if t.search(-1					) is not None:
		print("The value -1 exists"					)
	else:
		print("The value -1 doesn't exist"					)

	if not t.empty():
		print("Max Value: "    ,       t.get_max().value					)  # type: ignore
		print("Min Value: "    ,       t.get_min().value					)  # type: ignore

	for i in testlist:
		t.remove(_lowercase					)
		print(_lowercase					)


if __name__ == "__main__":
		import doctest

		doctest.testmod(verbose=True)









"""simple docstring"""




from decimal import Decimal, getcontext
from math import ceil, factorial






def       _SCREAMING_SNAKE_CASE		(	_lowercase						:    int					) ->str:






	'''simple docstring'''






	if not isinstance(_lowercase    ,       _lowercase					):
		raise TypeError("Undefined for non-integers"					)
	elif precision < 1:
		raise ValueError("Undefined for non-natural numbers"					)

	a      :		Tuple	=				precision
	a      :		str	=				ceil(precision / 14					)
	a      :		List[Any]	=				42_6880 * Decimal(1_0005					).sqrt()
	a      :		Union[str, Any]	=				1
	a      :		Dict	=				1359_1409
	a      :		Optional[int]	=				Decimal(_lowercase					)
	for k in range(1    ,       _lowercase					):
		a      :		int	=				factorial(6 * k					) // (factorial(3 * k					) * factorial(_lowercase					) ** 3)
		linear_term += 5_4514_0134
		exponential_term *= -26_2537_4126_4076_8000
		partial_sum += Decimal(multinomial_term * linear_term					) / exponential_term
	return str(constant_term / partial_sum					)[:-1]


if __name__ == "__main__":
		a						: Optional[Any]     	=			50
		print(F'''The first {n} digits of pi is: {pi(n)}''')


