


'''simple docstring'''







from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

A   :  Tuple       		=				TypeVar('''T''')
A   :  str       		=				TypeVar('''U''')


class 				__lowerCamelCase				( Generic[T, U] ):
    """simple docstring"""


    def __init__(						self    :							List[Any]   ,							SCREAMING_SNAKE_CASE    :							T | None   ,							SCREAMING_SNAKE_CASE    :							U | None):
           _A  :			List[Any]											=      key
           _A  :			List[str]											=      val
           _A  :			int											=      0
           _A  :			DoubleLinkedListNode[T, U] | None											=      None
           _A  :			DoubleLinkedListNode[T, U] | None											=      None


    def __repr__(						self    :							str):
           return "Node: key: {}, val: {}, freq: {}, has next: {}, has prev: {}".format(
               self.key   ,							self.val   ,							self.freq   ,							self.next is not None   ,							self.prev is not None)




class 				__lowerCamelCase				( Generic[T, U] ):
    """simple docstring"""


    def __init__(						self    :							Optional[int]):
           _A  :			DoubleLinkedListNode[T, U]											=      DoubleLinkedListNode(SCREAMING_SNAKE_CASE   ,							SCREAMING_SNAKE_CASE)
           _A  :			DoubleLinkedListNode[T, U]											=      DoubleLinkedListNode(SCREAMING_SNAKE_CASE   ,							SCREAMING_SNAKE_CASE)
           _A						,				_A  :			List[Any]											=      self.rear, self.head


    def __repr__(						self    :							List[Any]):
           _A  :			Any											=      ['DoubleLinkedList']
           _A  :			List[Any]											=      self.head
           while node.next is not None:
                  rep.append(str(SCREAMING_SNAKE_CASE))
                  _A  :			List[Any]											=      node.next
           rep.append(str(self.rear))
           return ",\n    ".join(SCREAMING_SNAKE_CASE)


    def      A					(						self    :							str   ,							SCREAMING_SNAKE_CASE    :							DoubleLinkedListNode[T, U]):
           _A  :			Optional[Any]											=      self.rear.prev

           # All nodes other than self.head are guaranteed to have non-None previous
           assert previous is not None

           _A  :			Optional[Any]											=      node
           _A  :			Union[str, Any]											=      previous
           _A  :			Optional[Any]											=      node
           _A  :			Optional[Any]											=      self.rear
           node.freq += 1
           self._position_node(SCREAMING_SNAKE_CASE)


    def      A					(						self    :							Tuple   ,							SCREAMING_SNAKE_CASE    :							DoubleLinkedListNode[T, U]):

           while node.prev is not None and node.prev.freq > node.freq:
                  # swap node with previous node
                  _A  :			str											=      node.prev

                  _A  :			List[Any]											=      previous_node.prev
                  _A  :			str											=      node.prev
                  _A  :			Any											=      previous_node
                  _A  :			Any											=      node


    def      A					(						self    :							str   ,							SCREAMING_SNAKE_CASE    :							DoubleLinkedListNode[T, U]):

           if node.prev is None or node.next is None:
                  return None

           _A  :			int											=      node.next
           _A  :			List[str]											=      node.prev
           _A  :			Optional[Any]											=      None
           _A  :			List[str]											=      None
           return node




class 				__lowerCamelCase				( Generic[T, U] ):
    """simple docstring"""
    a									=					{}


    def __init__(						self    :							Dict   ,							SCREAMING_SNAKE_CASE    :							int):
           _A  :			DoubleLinkedList[T, U]											=      DoubleLinkedList()
           _A  :			Tuple											=      capacity
           _A  :			Optional[int]											=      0
           _A  :			Dict											=      0
           _A  :			List[str]											=      0
           _A  :			dict[T, DoubleLinkedListNode[T, U]]											=      {}


    def __repr__(						self    :							int):
           return (
               F'CacheInfo(hits={self.hits}, misses={self.miss}, '
               F'capacity={self.capacity}, current_size={self.num_keys})'
           )


    def __contains__(						self    :							List[str]   ,							SCREAMING_SNAKE_CASE    :							T):
           return key in self.cache


    def      A					(						self    :							Optional[Any]   ,							SCREAMING_SNAKE_CASE    :							T):

           if key in self.cache:
                  self.hits += 1
                  _A  :			DoubleLinkedListNode[T, U]											=      self.cache[key]
                  _A  :			Union[str, Any]											=      self.list.remove(self.cache[key])
                  assert node == value_node

                  # node is guaranteed not None because it is in self.cache
                  assert node is not None
                  self.list.add(SCREAMING_SNAKE_CASE)
                  return node.val
           self.miss += 1
           return None


    def      A					(						self    :							int   ,							SCREAMING_SNAKE_CASE    :							T   ,							SCREAMING_SNAKE_CASE    :							U):

           if key not in self.cache:
                  if self.num_keys >= self.capacity:
                         # delete first node when over capacity
                         _A  :			List[str]											=      self.list.head.next

                         # guaranteed to have a non-None first node when num_keys > 0
                         # explain to type checker via assertions
                         assert first_node is not None
                         assert first_node.key is not None
                         assert self.list.remove(SCREAMING_SNAKE_CASE) is not None
                         # first_node guaranteed to be in list

                         del self.cache[first_node.key]
                         self.num_keys -= 1
                  _A  :			int											=      DoubleLinkedListNode(SCREAMING_SNAKE_CASE   ,							SCREAMING_SNAKE_CASE)
                  self.list.add(self.cache[key])
                  self.num_keys += 1

           else:
                  _A  :			List[str]											=      self.list.remove(self.cache[key])
                  assert node is not None  # node guaranteed to be in list
                  _A  :			str											=      value
                  self.list.add(SCREAMING_SNAKE_CASE)


    @classmethod
    def      A					(						cls    :							type[LFUCache[T, U]]   ,							SCREAMING_SNAKE_CASE    :							int = 128):

           def cache_decorator_inner(SCREAMING_SNAKE_CASE    :							Callable[[T], U]) -> Callable[..., U]:
                  def cache_decorator_wrapper(*SCREAMING_SNAKE_CASE    :							T) -> U:
                         if func not in cls.decorator_function_to_instance_map:
                                _A  :			Optional[Any]											=      LFUCache(SCREAMING_SNAKE_CASE)

                         _A  :			List[Any]											=      cls.decorator_function_to_instance_map[func].get(args[0])
                         if result is None:
                                _A  :			Any											=      func(*SCREAMING_SNAKE_CASE)
                                cls.decorator_function_to_instance_map[func].put(args[0]   ,							SCREAMING_SNAKE_CASE)
                         return result

                  def cache_info() -> LFUCache[T, U]:
                         return cls.decorator_function_to_instance_map[func]

                  setattr(SCREAMING_SNAKE_CASE   ,							'cache_info'   ,							SCREAMING_SNAKE_CASE)  # noqa: B010

                  return cache_decorator_wrapper

           return cache_decorator_inner


if __name__ == "__main__":
   import doctest

   doctest.testmod()










'''simple docstring'''







import itertools






def    lowerCAmelCase__ (       lowerCamelCase  :    int = 1000000     ):
       _A  :			str											=      [1]

       for i in itertools.count(len(lowerCamelCase     )     ):
              _A  :			Optional[Any]											=      0
              for j in itertools.count(1     ):
                     _A  :			int											=      -1 if j % 2 == 0 else +1
                     _A  :			Optional[Any]											=      (j * j * 3 - j) // 2
                     if index > i:
                            break
                     item += partitions[i - index] * sign
                     item %= number
                     index += j
                     if index > i:
                            break
                     item += partitions[i - index] * sign
                     item %= number

              if item == 0:
                     return i
              partitions.append(lowerCamelCase     )

       return 0


if __name__ == "__main__":
   import doctest

   doctest.testmod()

   print(f"""{solution() = }""")






