'''simple docstring'''


def    _lowerCamelCase       ( lowerCamelCase_   :				list  ):



     """simple docstring"""





     UpperCAmelCase_				:  Optional[int]  = len(lowerCamelCase_  )

     # Set the gap value to be decreased by a factor of 1.3
     # after each iteration
     UpperCAmelCase_				:  Optional[Any]  = 1.3

     # Continue sorting until the gap is 1
     while gap > 1:
          # Decrease the gap value
          UpperCAmelCase_				:  Optional[Any]  = int(gap / shrink  )

          # Sort the elements using insertion sort
          for i in range(lowerCamelCase_      ,	len(lowerCamelCase_  )  ):
               UpperCAmelCase_				:  Optional[int]  = collection[i]
               UpperCAmelCase_				:  Tuple  = i
               while j >= gap and collection[j - gap] > temp:
                    UpperCAmelCase_				:  Tuple  = collection[j - gap]
                    j -= gap
               UpperCAmelCase_				:  Optional[int]  = temp

     return collection


if __name__ == "__main__":
 import doctest

 doctest.testmod()









import timeit





class    __UpperCAmelCase	:



   def __init__(				self				:	Dict,						__A				:	Union[str, Any]		):
     if isinstance(__A,						__A		):  # Initializes a matrix identical to the one provided.
       UpperCAmelCase			:				str										=					arg
       UpperCAmelCase			:				Optional[Any]										=					len(__A		)
     else:  # Initializes a square matrix of the given size and set values to zero.
       UpperCAmelCase			:				List[str]										=					arg
       UpperCAmelCase			:				List[Any]										=					[[0 for _ in range(self.n		)] for _ in range(self.n		)]





   def __mul__(				self				:	Dict,						__A				:	List[Any]		):
     UpperCAmelCase			:				Dict										=					Matrix(self.n		)
     for i in range(self.n		):
       for j in range(self.n		):
         for k in range(self.n		):
           matrix.t[i][j] += self.t[i][k] * b.t[k][j]
     return matrix






def      a__	(						UpperCAmelCase				:     List[str]							,					UpperCAmelCase				:     List[Any]     )    ->		str:
  UpperCAmelCase			:				Tuple										=					Matrix([[1, 0], [0, 1]]     )
  while b > 0:
    if b & 1:
      matrix *= a
    a *= a
    b >>= 1
  return matrix

def      a__	(						UpperCAmelCase				:     Any							,					UpperCAmelCase				:     Dict							,					UpperCAmelCase				:     Dict     )    ->		str:
  # Trivial Cases
  if n == 1:
    return fa
  elif n == 2:
    return fa
  UpperCAmelCase			:				List[str]										=					Matrix([[1, 1], [1, 0]]     )
  UpperCAmelCase			:				Union[str, Any]										=					modular_exponentiation(UpperCAmelCase							,					n - 2     )
  return fa * matrix.t[0][0] + fa * matrix.t[0][1]

def      a__	(						UpperCAmelCase				:     Any							,					UpperCAmelCase				:     int							,					UpperCAmelCase				:     List[Any]     )    ->		Optional[Any]:
  # Trivial Cases
  if n == 1:
    return fa
  elif n == 2:
    return fa

  UpperCAmelCase			:				str										=					fa
  UpperCAmelCase			:				List[str]										=					fa
  n -= 2

  while n > 0:
    UpperCAmelCase					,		UpperCAmelCase			:				str										=					fn_a + fn_a, fn_a
    n -= 1

  return fn_a

def      a__	(						)    ->		Any:
  UpperCAmelCase			:				int										=					'''
from random import randint
from __main__ import fibonacci_with_matrix_exponentiation
'''
  UpperCAmelCase			:				Dict										=					'''fibonacci_with_matrix_exponentiation(randint(1,70000), 1, 1)'''
  UpperCAmelCase			:				Tuple										=					timeit.timeit(setup=UpperCAmelCase							,					stmt=UpperCAmelCase							,					number=100     )
  print('''With matrix exponentiation the average execution time is '''							,					exec_time / 100     )
  return exec_time

def      a__	(						)    ->		int:
  UpperCAmelCase			:				str										=					'''
from random import randint
from __main__ import simple_fibonacci
'''
  UpperCAmelCase			:				List[str]										=					'''simple_fibonacci(randint(1,70000), 1, 1)'''
  UpperCAmelCase			:				List[str]										=					timeit.timeit(setup=UpperCAmelCase							,					stmt=UpperCAmelCase							,					number=100     )
  print(
      '''Without matrix exponentiation the average execution time is '''							,					exec_time / 100     )
  return exec_time

def      a__	(						)    ->		List[str]:
  matrix_exponentiation_time()
  simple_fibonacci_time()


if __name__ == "__main__":
     main()





