






from __future__ import annotations

import math
import random
from typing import Any







class       __lowercase					:

	def __init__(      self   :						List[Any]):
			UpperCamelCase__				:					list[Any]					=					[]
			UpperCamelCase__				:					int					=					0
			UpperCamelCase__				:					int					=					0

	def      __UpperCamelCase							(      self   :						str):
			return self.head == self.tail

	def      __UpperCamelCase							(      self   :						str  ,					UpperCAmelCase_   :						List[str]):
			self.data.append(UpperCamelCase__)
			UpperCamelCase__				:					List[Any]					=					self.tail + 1

	def      __UpperCamelCase							(      self   :						Tuple):
			UpperCamelCase__				:					Tuple					=					self.data[self.head]
			UpperCamelCase__				:					List[str]					=					self.head + 1
			return ret

	def      __UpperCamelCase							(      self   :						Dict):
			return self.tail - self.head





	def      __UpperCamelCase							(      self   :						Union[str, Any]):
			print(self.data)
			print('**************')
			print(self.data[self.head : self.tail])







class       __lowercase					:

	def __init__(      self   :						int  ,					UpperCAmelCase_   :						int):
			UpperCamelCase__				:					Union[str, Any]					=					data
			UpperCamelCase__				:					MyNode | None					=					None
			UpperCamelCase__				:					MyNode | None					=					None
			UpperCamelCase__				:					int					=					1

	def      __UpperCamelCase							(      self   :						Optional[int]):
			return self.data

	def      __UpperCamelCase							(      self   :						Optional[int]):
			return self.left

	def      __UpperCamelCase							(      self   :						Dict):
			return self.right

	def      __UpperCamelCase							(      self   :						List[str]):
			return self.height

	def      __UpperCamelCase							(      self   :						Any  ,					UpperCAmelCase_   :						int):
			UpperCamelCase__				:					int					=					data

	def      __UpperCamelCase							(      self   :						Any  ,					UpperCAmelCase_   :						List[Any]):
			UpperCamelCase__				:					Any					=					node

	def      __UpperCamelCase							(      self   :						Tuple  ,					UpperCAmelCase_   :						Tuple):
			UpperCamelCase__				:					Union[str, Any]					=					node





	def      __UpperCamelCase							(      self   :						int  ,					UpperCAmelCase_   :						Tuple):
			UpperCamelCase__				:					Tuple					=					height







def       __UpperCAmelCase						(  lowerCamelCase_)							->     int:







		if node is None:
				return 0
		return node.get_height()







def       __UpperCAmelCase						(  lowerCamelCase_     ,      lowerCamelCase_)							->     int:







		if a > b:
				return a
		return b







def       __UpperCAmelCase						(  lowerCamelCase_)							->     MyNode:
		print('left rotation node:'     ,      node.get_data())
		UpperCamelCase__				:					Optional[int]					=					node.get_left()
		assert ret is not None
		node.set_left(ret.get_right())
		ret.set_right(__UpperCamelCase)
		UpperCamelCase__				:					int					=					my_max(get_height(node.get_right())     ,      get_height(node.get_left())) + 1
		node.set_height(__UpperCamelCase)
		UpperCamelCase__				:					Optional[Any]					=					my_max(get_height(ret.get_right())     ,      get_height(ret.get_left())) + 1
		ret.set_height(__UpperCamelCase)
		return ret







def       __UpperCAmelCase						(  lowerCamelCase_)							->     MyNode:
		print('right rotation node:'     ,      node.get_data())
		UpperCamelCase__				:					Union[str, Any]					=					node.get_right()
		assert ret is not None
		node.set_right(ret.get_left())
		ret.set_left(__UpperCamelCase)
		UpperCamelCase__				:					Optional[int]					=					my_max(get_height(node.get_right())     ,      get_height(node.get_left())) + 1
		node.set_height(__UpperCamelCase)
		UpperCamelCase__				:					List[str]					=					my_max(get_height(ret.get_right())     ,      get_height(ret.get_left())) + 1
		ret.set_height(__UpperCamelCase)
		return ret







def       __UpperCAmelCase						(  lowerCamelCase_)							->     MyNode:
		UpperCamelCase__				:					Dict					=					node.get_left()
		assert left_child is not None
		node.set_left(left_rotation(__UpperCamelCase))
		return right_rotation(__UpperCamelCase)







def       __UpperCAmelCase						(  lowerCamelCase_)							->     MyNode:
		UpperCamelCase__				:					List[str]					=					node.get_right()
		assert right_child is not None
		node.set_right(right_rotation(__UpperCamelCase))
		return left_rotation(__UpperCamelCase)







def       __UpperCAmelCase						(  lowerCamelCase_     ,      lowerCamelCase_)							->     MyNode | None:







		if node is None:
				return MyNode(__UpperCamelCase)
		if data < node.get_data():
				node.set_left(insert_node(node.get_left()     ,      __UpperCamelCase))
				if (
				    get_height(node.get_left()) - get_height(node.get_right()) == 2
				):  # an unbalance detected
						UpperCamelCase__				:					List[Any]					=					node.get_left()
						assert left_child is not None
						if (
						    data < left_child.get_data()
						):  # new node is the left child of the left child
								UpperCamelCase__				:					int					=					right_rotation(__UpperCamelCase)
						else:
								UpperCamelCase__				:					Dict					=					lr_rotation(__UpperCamelCase)
		else:
				node.set_right(insert_node(node.get_right()     ,      __UpperCamelCase))
				if get_height(node.get_right()) - get_height(node.get_left()) == 2:
						UpperCamelCase__				:					List[Any]					=					node.get_right()
						assert right_child is not None
						if data < right_child.get_data():
								UpperCamelCase__				:					List[Any]					=					rl_rotation(__UpperCamelCase)
						else:
								UpperCamelCase__				:					Optional[Any]					=					left_rotation(__UpperCamelCase)
		UpperCamelCase__				:					Optional[Any]					=					my_max(get_height(node.get_right())     ,      get_height(node.get_left())) + 1
		node.set_height(__UpperCamelCase)
		return node







def       __UpperCAmelCase						(  lowerCamelCase_)							->     Any:







		while True:
				UpperCamelCase__				:					Optional[Any]					=					root.get_right()
				if right_child is None:
						break
				UpperCamelCase__				:					Union[str, Any]					=					right_child
		return root.get_data()







def       __UpperCAmelCase						(  lowerCamelCase_)							->     Any:







		while True:
				UpperCamelCase__				:					str					=					root.get_left()
				if left_child is None:
						break
				UpperCamelCase__				:					List[str]					=					left_child
		return root.get_data()







def       __UpperCAmelCase						(  lowerCamelCase_     ,      lowerCamelCase_)							->     MyNode | None:
		UpperCamelCase__				:					str					=					root.get_left()
		UpperCamelCase__				:					Optional[Any]					=					root.get_right()
		if root.get_data() == data:
				if left_child is not None and right_child is not None:
						UpperCamelCase__				:					str					=					get_left_most(__UpperCamelCase)
						root.set_data(__UpperCamelCase)
						root.set_right(del_node(__UpperCamelCase     ,      __UpperCamelCase))
				elif left_child is not None:
						UpperCamelCase__				:					str					=					left_child
				elif right_child is not None:
						UpperCamelCase__				:					Any					=					right_child
				else:
						return None
		elif root.get_data() > data:
				if left_child is None:
						print('No such data')
						return root
				else:
						root.set_left(del_node(__UpperCamelCase     ,      __UpperCamelCase))
		else:  # root.get_data() < data
				if right_child is None:
						return root
				else:
						root.set_right(del_node(__UpperCamelCase     ,      __UpperCamelCase))

		if get_height(__UpperCamelCase) - get_height(__UpperCamelCase) == 2:
				assert right_child is not None
				if get_height(right_child.get_right()) > get_height(right_child.get_left()):
						UpperCamelCase__				:					int					=					left_rotation(__UpperCamelCase)
				else:
						UpperCamelCase__				:					Any					=					rl_rotation(__UpperCamelCase)
		elif get_height(__UpperCamelCase) - get_height(__UpperCamelCase) == -2:
				assert left_child is not None
				if get_height(left_child.get_left()) > get_height(left_child.get_right()):
						UpperCamelCase__				:					Dict					=					right_rotation(__UpperCamelCase)
				else:
						UpperCamelCase__				:					Optional[Any]					=					lr_rotation(__UpperCamelCase)
		UpperCamelCase__				:					int					=					my_max(get_height(root.get_right())     ,      get_height(root.get_left())) + 1
		root.set_height(__UpperCamelCase)
		return root







class       __lowercase					:

	def __init__(      self   :						Dict):
			UpperCamelCase__				:					MyNode | None					=					None

	def      __UpperCamelCase							(      self   :						Optional[Any]):
			return get_height(self.root)

	def      __UpperCamelCase							(      self   :						str  ,					UpperCAmelCase_   :						int):
			print('insert:' + str(UpperCamelCase__))
			UpperCamelCase__				:					Tuple					=					insert_node(self.root  ,					UpperCamelCase__)

	def      __UpperCamelCase							(      self   :						Any  ,					UpperCAmelCase_   :						Optional[Any]):
			print('delete:' + str(UpperCamelCase__))
			if self.root is None:
					print('Tree is empty!')
					return
			UpperCamelCase__				:					Union[str, Any]					=					del_node(self.root  ,					UpperCamelCase__)





	def __str__(      self   :						Dict  ,					):  # a level traversale, gives a more intuitive look on the tree
			UpperCamelCase__				:					Union[str, Any]					=					''''''
			UpperCamelCase__				:					Union[str, Any]					=					MyQueue()
			q.push(self.root)
			UpperCamelCase__				:					int					=					self.get_height()
			if layer == 0:
					return output
			UpperCamelCase__				:					List[Any]					=					0
			while not q.is_empty():
					UpperCamelCase__				:					Optional[int]					=					q.pop()
					UpperCamelCase__				:					int					=					''' ''' * int(math.pow(2  ,					layer - 1))
					output += space
					if node is None:
							output += "*"
							q.push(UpperCamelCase__)
							q.push(UpperCamelCase__)
					else:
							output += str(node.get_data())
							q.push(node.get_left())
							q.push(node.get_right())
					output += space
					UpperCamelCase__				:					Dict					=					cnt + 1
					for i in range(100):
							if cnt == math.pow(2  ,					UpperCamelCase__) - 1:
									UpperCamelCase__				:					Tuple					=					layer - 1
									if layer == 0:
											output += "\n*************************************"
											return output
									output += "\n"
									break
			output += "\n*************************************"
			return output







def       __UpperCAmelCase						(  )							->     None:
		import doctest

		doctest.testmod()


if __name__ == "__main__":
		_test()
		lowerCAmelCase__          =						AVLtree()
		lowerCAmelCase__          =						list(range(10))
		random.shuffle(lst)
		for i in lst:
				t.insert(i)
				print(str(t))
		random.shuffle(lst)
		for i in lst:
				t.del_node(i)
				print(str(t))












'''simple docstring'''




from __future__ import annotations







class       __lowercase					:

	def __init__(      self   :						Union[str, Any]  ,					UpperCAmelCase_   :						list[list[int]]):
			UpperCamelCase__				:					int					=					TypeError(
			    'Matrices must be formed from a list of zero or more lists containing at '
			    'least one and the same number of values, each of which must be of type '
			    'int or float.')
			if len(UpperCAmelCase_) != 0:
					UpperCamelCase__				:					str					=					len(rows[0])
					if cols == 0:
							raise error
					for row in rows:
							if len(UpperCAmelCase_) != cols:
									raise error
							for value in row:
									if not isinstance(UpperCAmelCase_  ,					(int, float)):
											raise error
					UpperCamelCase__				:					Optional[int]					=					rows
			else:
					UpperCamelCase__				:					Optional[Any]					=					[]

	def      __UpperCamelCase							(      self   :						Union[str, Any]):
			return [[row[i] for row in self.rows] for i in range(len(self.rows[0]))]

	@property
	def      __UpperCamelCase							(      self   :						Dict):
			return len(self.rows)

	@property
	def      __UpperCamelCase							(      self   :						Tuple):
			return len(self.rows[0])

	@property
	def      __UpperCamelCase							(      self   :						List[Any]):
			return (self.num_rows, self.num_columns)

	@property
	def      __UpperCamelCase							(      self   :						Any):
			return self.order[0] == self.order[1]

	def      __UpperCamelCase							(      self   :						Any):
			UpperCamelCase__				:					Optional[int]					=					[
			    [0 if column_num != row_num else 1 for column_num in range(self.num_rows)]
			    for row_num in range(self.num_rows)
			]
			return Matrix(UpperCAmelCase_)

	def      __UpperCamelCase							(      self   :						Dict):
			if not self.is_square:
					return 0
			if self.order == (0, 0):
					return 1
			if self.order == (1, 1):
					return int(self.rows[0][0])
			if self.order == (2, 2):
					return int(
					    (self.rows[0][0] * self.rows[1][1])
					    - (self.rows[0][1] * self.rows[1][0]))
			else:
					return sum(
					    self.rows[0][column] * self.cofactors().rows[0][column]
					    for column in range(self.num_columns))

	def      __UpperCamelCase							(      self   :						str):
			return bool(self.determinant())

	def      __UpperCamelCase							(      self   :						List[str]  ,					UpperCAmelCase_   :						int  ,					UpperCAmelCase_   :						int):
			UpperCamelCase__				:					Optional[Any]					=					[
			    [
			        self.rows[other_row][other_column]
			        for other_column in range(self.num_columns)
			        if other_column != column
			    ]
			    for other_row in range(self.num_rows)
			    if other_row != row
			]
			return Matrix(UpperCAmelCase_).determinant()

	def      __UpperCamelCase							(      self   :						Any  ,					UpperCAmelCase_   :						int  ,					UpperCAmelCase_   :						int):
			if (row + column) % 2 == 0:
					return self.get_minor(UpperCAmelCase_  ,					UpperCAmelCase_)
			return -1 * self.get_minor(UpperCAmelCase_  ,					UpperCAmelCase_)

	def      __UpperCamelCase							(      self   :						List[Any]):
			return Matrix(
			    [
			        [self.get_minor(UpperCAmelCase_  ,					UpperCAmelCase_) for column in range(self.num_columns)]
			        for row in range(self.num_rows)
			    ])

	def      __UpperCamelCase							(      self   :						Optional[int]):
			return Matrix(
			    [
			        [
			            self.minors().rows[row][column]
			            if (row + column) % 2 == 0
			            else self.minors().rows[row][column] * -1
			            for column in range(self.minors().num_columns)
			        ]
			        for row in range(self.minors().num_rows)
			    ])

	def      __UpperCamelCase							(      self   :						Dict):
			UpperCamelCase__				:					Dict					=					[
			    [self.cofactors().rows[column][row] for column in range(self.num_columns)]
			    for row in range(self.num_rows)
			]
			return Matrix(UpperCAmelCase_)

	def      __UpperCamelCase							(      self   :						int):
			UpperCamelCase__				:					List[Any]					=					self.determinant()
			if not determinant:
					raise TypeError('Only matrices with a non-zero determinant have an inverse')
			return self.adjugate() * (1 / determinant)

	def __repr__(      self   :						Any):
			return str(self.rows)

	def __str__(      self   :						List[Any]):
			if self.num_rows == 0:
					return "[]"
			if self.num_rows == 1:
					return "[[" + ". ".join(str(self.rows[0])) + "]]"
			return (
			    "["
			    + "\n ".join(
			        [
			            '[' + '. '.join([str(UpperCAmelCase_) for value in row]) + '.]'
			            for row in self.rows
			        ])
			    + "]"
			)

	def      __UpperCamelCase							(      self   :						Dict  ,					UpperCAmelCase_   :						list[int]  ,					UpperCAmelCase_   :						int | None = None):
			UpperCamelCase__				:					List[str]					=					TypeError('Row must be a list containing all ints and/or floats')
			if not isinstance(UpperCAmelCase_  ,					UpperCAmelCase_):
					raise type_error
			for value in row:
					if not isinstance(UpperCAmelCase_  ,					(int, float)):
							raise type_error
			if len(UpperCAmelCase_) != self.num_columns:
					raise ValueError(
					    'Row must be equal in length to the other rows in the matrix')
			if position is None:
					self.rows.append(UpperCAmelCase_)
			else:
					UpperCamelCase__				:					Tuple					=					self.rows[0:position] + [row] + self.rows[position:]

	def      __UpperCamelCase							(      self   :						Tuple  ,					UpperCAmelCase_   :						list[int]  ,					UpperCAmelCase_   :						int | None = None):
			UpperCamelCase__				:					int					=					TypeError(
			    'Column must be a list containing all ints and/or floats')
			if not isinstance(UpperCAmelCase_  ,					UpperCAmelCase_):
					raise type_error
			for value in column:
					if not isinstance(UpperCAmelCase_  ,					(int, float)):
							raise type_error
			if len(UpperCAmelCase_) != self.num_rows:
					raise ValueError(
					    'Column must be equal in length to the other columns in the matrix')
			if position is None:
					UpperCamelCase__				:					Optional[int]					=					[self.rows[i] + [column[i]] for i in range(self.num_rows)]
			else:
					UpperCamelCase__				:					str					=					[
					    self.rows[i][0:position] + [column[i]] + self.rows[i][position:]
					    for i in range(self.num_rows)
					]

	def __eq__(      self   :						List[Any]  ,					UpperCAmelCase_   :						object):
			if not isinstance(UpperCAmelCase_  ,					UpperCAmelCase_):
					return NotImplemented
			return self.rows == other.rows

	def __ne__(      self   :						Any  ,					UpperCAmelCase_   :						object):
			return not self == other

	def __neg__(      self   :						Union[str, Any]):
			return self * -1

	def __add__(      self   :						Optional[int]  ,					UpperCAmelCase_   :						Matrix):
			if self.order != other.order:
					raise ValueError('Addition requires matrices of the same order')
			return Matrix(
			    [
			        [self.rows[i][j] + other.rows[i][j] for j in range(self.num_columns)]
			        for i in range(self.num_rows)
			    ])

	def __sub__(      self   :						Tuple  ,					UpperCAmelCase_   :						Matrix):
			if self.order != other.order:
					raise ValueError('Subtraction requires matrices of the same order')
			return Matrix(
			    [
			        [self.rows[i][j] - other.rows[i][j] for j in range(self.num_columns)]
			        for i in range(self.num_rows)
			    ])

	def __mul__(      self   :						Any  ,					UpperCAmelCase_   :						Matrix | int | float):
			if isinstance(UpperCAmelCase_  ,					(int, float)):
					return Matrix(
					    [[int(element * other) for element in row] for row in self.rows])
			elif isinstance(UpperCAmelCase_  ,					UpperCAmelCase_):
					if self.num_columns != other.num_rows:
							raise ValueError(
							    'The number of columns in the first matrix must '
							    'be equal to the number of rows in the second')
					return Matrix(
					    [
					        [Matrix.dot_product(UpperCAmelCase_  ,					UpperCAmelCase_) for column in other.columns()]
					        for row in self.rows
					    ])
			else:
					raise TypeError(
					    'A Matrix can only be multiplied by an int, float, or another matrix')

	def __pow__(      self   :						Dict  ,					UpperCAmelCase_   :						int):
			if not isinstance(UpperCAmelCase_  ,					UpperCAmelCase_):
					raise TypeError('A Matrix can only be raised to the power of an int')
			if not self.is_square:
					raise ValueError('Only square matrices can be raised to a power')
			if other == 0:
					return self.identity()
			if other < 0:
					if self.is_invertable():
							return self.inverse() ** (-other)
					raise ValueError(
					    'Only invertable matrices can be raised to a negative power')
			UpperCamelCase__				:					str					=					self
			for _ in range(other - 1):
					result *= self
			return result





	@classmethod
	def      __UpperCamelCase							(      cls   :						Optional[int]  ,					UpperCAmelCase_   :						list[int]  ,					UpperCAmelCase_   :						list[int]):
			return sum(row[i] * column[i] for i in range(len(UpperCAmelCase_)))


if __name__ == "__main__":
		import doctest

		doctest.testmod()




