code: 
  
  
  '''simple docstring'''
  
  
  
  
  from __future__ import annotations
  
  from collections.abc import Callable
  from typing import Generic, TypeVar
  
  __lowercase  :      str      		=				TypeVar("""T""")
  __lowercase  :      Tuple      		=				TypeVar("""U""")
  
  
  
  
  
  class _snake_case   ( Generic[T, U]   ):
  							"""simple docstring"""
  
  
  
  
  
  							def __init__(   self			,				__A			,				__A	)     ->int:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											__lowerCamelCase		:      Any											=					key
  											__lowerCamelCase		:      Dict											=					val
  											__lowerCamelCase		:      int											=					0
  											__lowerCamelCase		:      DoubleLinkedListNode[T, U] | None											=					None
  											__lowerCamelCase		:      DoubleLinkedListNode[T, U] | None											=					None
  
  
  
  
  
  
  
  							def __repr__(   self	)     ->str:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											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 _snake_case   ( Generic[T, U]   ):
  							"""simple docstring"""
  
  
  
  
  
  							def __init__(   self	)     ->None:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											__lowerCamelCase		:      DoubleLinkedListNode[T, U]											=					DoubleLinkedListNode(__A			,				__A	)
  											__lowerCamelCase		:      DoubleLinkedListNode[T, U]											=					DoubleLinkedListNode(__A			,				__A	)
  											__lowerCamelCase						,					__lowerCamelCase		:      Union[str, Any]											=					self.rear, self.head
  
  
  
  
  
  
  
  							def __repr__(   self	)     ->str:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											__lowerCamelCase		:      Dict											=					["DoubleLinkedList"]
  											__lowerCamelCase		:      int											=					self.head
  											while node.next is not None:
  															rep.append(str(__A	)	)
  															__lowerCamelCase		:      List[Any]											=					node.next
  											rep.append(str(self.rear	)	)
  											return ",\n    ".join(__A	)
  
  
  
  
  
  
  
  							def 		__SCREAMING_SNAKE_CASE(   self			,				__A	)     ->None:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											__lowerCamelCase		:      Tuple											=					self.rear.prev
  
  											# All nodes other than self.head are guaranteed to have non-None previous
  											assert previous is not None
  
  											__lowerCamelCase		:      List[Any]											=					node
  											__lowerCamelCase		:      int											=					previous
  											__lowerCamelCase		:      Tuple											=					node
  											__lowerCamelCase		:      Union[str, Any]											=					self.rear
  											node.freq += 1
  											self._position_node(__A	)
  
  
  
  
  
  
  
  							def 		__SCREAMING_SNAKE_CASE(   self			,				__A	)     ->None:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											while node.prev is not None and node.prev.freq > node.freq:
  															# swap node with previous node
  															__lowerCamelCase		:      Dict											=					node.prev
  
  															__lowerCamelCase		:      Tuple											=					previous_node.prev
  															__lowerCamelCase		:      List[str]											=					node.prev
  															__lowerCamelCase		:      Tuple											=					previous_node
  															__lowerCamelCase		:      List[Any]											=					node
  
  
  
  
  
  
  
  							def 		__SCREAMING_SNAKE_CASE(   self			,				__A	)     ->DoubleLinkedListNode[T, U] | None:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											if node.prev is None or node.next is None:
  															return None
  
  											__lowerCamelCase		:      List[Any]											=					node.next
  											__lowerCamelCase		:      Dict											=					node.prev
  											__lowerCamelCase		:      List[str]											=					None
  											__lowerCamelCase		:      Any											=					None
  											return node
  
  
  
  
  
  class _snake_case   ( Generic[T, U]   ):
  							"""simple docstring"""
  
  
  
  
  
  							__a												=     {}
  
  
  
  
  
  
  
  							def __init__(   self			,				__A	)     ->List[Any]:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											__lowerCamelCase		:      DoubleLinkedList[T, U]											=					DoubleLinkedList()
  											__lowerCamelCase		:      Any											=					capacity
  											__lowerCamelCase		:      int											=					0
  											__lowerCamelCase		:      Optional[int]											=					0
  											__lowerCamelCase		:      List[str]											=					0
  											__lowerCamelCase		:      dict[T, DoubleLinkedListNode[T, U]]											=					{}
  
  
  
  
  
  
  
  							def __repr__(   self	)     ->str:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											return (
  											    f'CacheInfo(hits={self.hits}, misses={self.miss}, '
  											    f'capacity={self.capacity}, current_size={self.num_keys})'
  											)
  
  
  
  
  
  
  
  							def __contains__(   self			,				__A	)     ->bool:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											return key in self.cache
  
  
  
  
  
  
  
  							def 		__SCREAMING_SNAKE_CASE(   self			,				__A	)     ->U | None:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											if key in self.cache:
  															self.hits += 1
  															__lowerCamelCase		:      DoubleLinkedListNode[T, U]											=					self.cache[key]
  															__lowerCamelCase		:      Optional[int]											=					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(__A	)
  															return node.val
  											self.miss += 1
  											return None
  
  
  
  
  
  
  
  							def 		__SCREAMING_SNAKE_CASE(   self			,				__A			,				__A	)     ->None:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											if key not in self.cache:
  															if self.num_keys >= self.capacity:
  																			# delete first node when over capacity
  																			__lowerCamelCase		:      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(__A	) is not None
  																			# first_node guaranteed to be in list
  
  																			del self.cache[first_node.key]
  																			self.num_keys -= 1
  															__lowerCamelCase		:      str											=					DoubleLinkedListNode(__A			,				__A	)
  															self.list.add(self.cache[key]	)
  															self.num_keys += 1
  
  											else:
  															__lowerCamelCase		:      List[Any]											=					self.list.remove(self.cache[key]	)
  															assert node is not None  # node guaranteed to be in list
  															__lowerCamelCase		:      Tuple											=					value
  															self.list.add(__A	)
  
  
  
  
  
  
  
  							@classmethod
  							def 		__SCREAMING_SNAKE_CASE(   cls			,				__A = 128	)     ->Callable[[Callable[[T], U]], Callable[..., U]]:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											def cache_decorator_inner(__A	) -> Callable[..., U]:
  															def cache_decorator_wrapper(*__A	) -> U:
  																			if func not in cls.decorator_function_to_instance_map:
  																							__lowerCamelCase		:      int											=					LFUCache(__A	)
  
  																			__lowerCamelCase		:      Optional[int]											=					cls.decorator_function_to_instance_map[func].get(args[0]	)
  																			if result is None:
  																							__lowerCamelCase		:      Union[str, Any]											=					func(*__A	)
  																							cls.decorator_function_to_instance_map[func].put(args[0]			,				__A	)
  																			return result
  
  															def cache_info() -> LFUCache[T, U]:
  																			return cls.decorator_function_to_instance_map[func]
  
  															setattr(__A			,				"cache_info"			,				__A	)  # noqa: B010
  
  															return cache_decorator_wrapper
  
  											return cache_decorator_inner
  
  
  if __name__ == "__main__":
  				import doctest
  
  				doctest.testmod()
  
  
  
  
  
  
style_context: 
  
  
  '''simple docstring'''
  
  
  
  
  from __future__ import annotations
  
  from collections import deque
  from enum import Enum
  from math import atana, degrees
  from sys import maxsize
  
  
  
  
  
  class _snake_case   ( a__   ):
  							"""simple docstring"""
  
  
  
  
  
  							__a												=     1
  							__a												=     2
  							__a												=     3
  
  
  
  
  
  
  
  							def __repr__(   self	)     ->Tuple:
  
  
  
  											"""simple docstring"""
  
  
  
  
  
  
  
  											return f'{self.__class__.__name__}.{self.name}'
  
  
  
  
  
  def 							a_       (						lowercase							,						lowercase							,						lowercase    )			->float:
  
  
  
  
  
  
  				'''simple docstring'''
  
  				__lowerCamelCase						,					__lowerCamelCase		:      str											=					point
  				return degrees(atana(y - miny							,						x - minx    )    )
  
  
  
  
  
  def 							a_       (						lowercase							,						lowercase							,						lowercase    )			->Direction:
  
  
  
  
  
  
  				'''simple docstring'''
  
  				__lowerCamelCase						,					__lowerCamelCase		:      List[str]											=					starting
  				__lowerCamelCase						,					__lowerCamelCase		:      Any											=					via
  				__lowerCamelCase						,					__lowerCamelCase		:      str											=					target
  				__lowerCamelCase		:      str											=					degrees(atana(ya - ya							,						xa - xa    )    )
  				via_angle %= 360
  				__lowerCamelCase		:      List[Any]											=					degrees(atana(ya - ya							,						xa - xa    )    )
  				target_angle %= 360
  				# t-
  				#  \ \
  				#   \ v
  				#    \|
  				#     s
  				# via_angle is always lower than target_angle, if direction is left.
  				# If they are same, it means they are on a same line of convex hull.
  				if target_angle > via_angle:
  								return Direction.left
  				elif target_angle == via_angle:
  								return Direction.straight
  				else:
  								return Direction.right
  
  
  
  
  
  def 							a_       (						lowercase    )			->list[tuple[int, int]]:
  
  
  
  
  
  
  				'''simple docstring'''
  
  				if len(lowercase    ) <= 2:
  								# There is no convex hull
  								raise ValueError("graham_scan: argument must contain more than 3 points."    )
  				if len(lowercase    ) == 3:
  								return points
  				# find the lowest and the most left point
  				__lowerCamelCase		:      Optional[Any]											=					0
  				__lowerCamelCase						,					__lowerCamelCase		:      List[Any]											=					maxsize, maxsize
  				for i, point in enumerate(lowercase    ):
  								__lowerCamelCase		:      Dict											=					point[0]
  								__lowerCamelCase		:      Optional[int]											=					point[1]
  								if y < miny:
  												__lowerCamelCase		:      Dict											=					y
  												__lowerCamelCase		:      int											=					x
  												__lowerCamelCase		:      List[Any]											=					i
  								if y == miny and x < minx:
  												__lowerCamelCase		:      Optional[int]											=					x
  												__lowerCamelCase		:      Any											=					i
  
      # remove the lowest and the most left point from points for preparing for sort
  				points.pop(lowercase    )
  
  				__lowerCamelCase		:      Optional[Any]											=					sorted(lowercase							,						key=lambda lowercase    : angle_comparer(lowercase							,						lowercase							,						lowercase    )    )
  				# This insert actually costs complexity,
  				# and you should instead add (minx, miny) into stack later.
  				# I'm using insert just for easy understanding.
  				sorted_points.insert(0							,						(minx, miny)    )
  
  				__lowerCamelCase		:      deque[tuple[int, int]]											=					deque()
  				stack.append(sorted_points[0]    )
  				stack.append(sorted_points[1]    )
  				stack.append(sorted_points[2]    )
  				# In any ways, the first 3 points line are towards left.
  				# Because we sort them the angle from minx, miny.
  				__lowerCamelCase		:      str											=					Direction.left
  
  				for i in range(3							,						len(lowercase    )    ):
  								while True:
  												__lowerCamelCase		:      List[Any]											=					stack[-2]
  												__lowerCamelCase		:      str											=					stack[-1]
  												__lowerCamelCase		:      int											=					sorted_points[i]
  												__lowerCamelCase		:      List[Any]											=					check_direction(lowercase							,						lowercase							,						lowercase    )
  
  												if next_direction == Direction.left:
  																__lowerCamelCase		:      Optional[int]											=					Direction.left
  																break
  												if next_direction == Direction.straight:
  																if current_direction == Direction.left:
  																				# We keep current_direction as left.
  																				# Because if the straight line keeps as straight,
  																				# we want to know if this straight line is towards left.
  																				break
  																elif current_direction == Direction.right:
  																				# If the straight line is towards right,
  																				# every previous points on those straigh line is not convex hull.
  																				stack.pop()
  												if next_direction == Direction.right:
  																stack.pop()
  								stack.append(sorted_points[i]    )
  				return list(lowercase    )
  
  
  
  
  
  