






from __future__ import annotations

import sys

def 					UpperCamelCase		( _A				):






						"""simple docstring"""







						if n < 0:
												raise ValueError("""Negative arguments are not supported"""				)
						return _fib(_A				)[0]

def 					UpperCamelCase		( _A				):






						"""simple docstring"""







						if n == 0:  # (F(0), F(1))
												return (0, 1)

						# F(2n) = F(n)[2F(n+1) − F(n)]
						# F(2n+1) = F(n+1)^2+F(n)^2
						__magic_name__    :     str     		=      _fib(n // 2				)
						__magic_name__    :     Dict     		=      a * (b * 2 - a)
						__magic_name__    :     List[Any]     		=      a * a + b * b
						return (d, c + d) if n % 2 else (c, d)


if __name__ == "__main__":
		__magic_name__:  Optional[Any]  	=			int(sys.argv[1])
		print(F"""fibonacci({n}) is {fibonacci(n)}""")








class  snake_case__      :
	def __init__(       self				)							->   None:
							# numbermap keys are the number and its values are lists of indexes sorted
							# in ascending order
							__magic_name__    :     dict[int, list[int]]     		=      {}
							# indexmap keys are an index and it's values are the number at that index
							__magic_name__    :     dict[int, int]     		=      {}
	def     __magic_name__       (       self    ,     lowerCAmelCase__    ,     lowerCAmelCase__				)							->   list[int]:
							if isinstance(lowerCAmelCase__    ,     (range, str)				):
													__magic_name__    :     int     		=      list(lowerCAmelCase__				)
							elif not isinstance(lowerCAmelCase__    ,     lowerCAmelCase__				):
													raise TypeError(
													    """binary_search_delete() only accepts either a list, range or str"""				)

							__magic_name__    :     str     		=      0
							__magic_name__    :     int     		=      len(lowerCAmelCase__				) - 1

							while low <= high:
													__magic_name__    :     List[str]     		=      (low + high) // 2
													if array[mid] == item:
																			array.pop(lowerCAmelCase__				)
																			return array
													elif array[mid] < item:
																			__magic_name__    :     Tuple     		=      mid + 1
													else:
																			__magic_name__    :     Dict     		=      mid - 1
							raise ValueError(
							    """Either the item is not in the array or the array was unsorted"""				)
	def     __magic_name__       (       self    ,     lowerCAmelCase__    ,     lowerCAmelCase__				)							->   list[int]:
							if isinstance(lowerCAmelCase__    ,     (range, str)				):
													__magic_name__    :     Tuple     		=      list(lowerCAmelCase__				)
							elif not isinstance(lowerCAmelCase__    ,     lowerCAmelCase__				):
													raise TypeError(
													    """binary_search_insert() only accepts either a list, range or str"""				)

							__magic_name__    :     List[str]     		=      0
							__magic_name__    :     Tuple     		=      len(lowerCAmelCase__				) - 1

							while low <= high:
													__magic_name__    :     Dict     		=      (low + high) // 2
													if array[mid] == index:
																			# If the item already exists in the array,
																			# insert it after the existing item
																			array.insert(mid + 1    ,     lowerCAmelCase__				)
																			return array
													elif array[mid] < index:
																			__magic_name__    :     int     		=      mid + 1
													else:
																			__magic_name__    :     Tuple     		=      mid - 1

        # If the item doesn't exist in the array, insert it at the appropriate position
							array.insert(lowerCAmelCase__    ,     lowerCAmelCase__				)
							return array
	def     __magic_name__       (       self    ,     lowerCAmelCase__    ,     lowerCAmelCase__				)							->   None:
							# Remove previous index
							if index in self.indexmap:
													__magic_name__    :     int     		=      self.indexmap[index]
													if len(self.numbermap[n]				) == 1:
																			del self.numbermap[n]
													else:
																			__magic_name__    :     Union[str, Any]     		=      self.binary_search_delete(self.numbermap[n]    ,     lowerCAmelCase__				)

        # Set new index
							__magic_name__    :     List[Any]     		=      number

							# Number not seen before or empty so insert number value
							if number not in self.numbermap:
													__magic_name__    :     Any     		=      [index]

							# Here we need to perform a binary search insertion in order to insert
							# The item in the correct place
							else:
													__magic_name__    :     Optional[Any]     		=      self.binary_search_insert(
													    self.numbermap[number]    ,     lowerCAmelCase__				)







	def     __magic_name__       (       self    ,     lowerCAmelCase__				)							->   int:
							return self.numbermap.get(lowerCAmelCase__    ,     [-1]				)[0]


if __name__ == "__main__":
		import doctest

		doctest.testmod()
