
from collections import Counter
from functools import total_ordering

from data_structures.heap.heap import Heap





@total_ordering
class 						__lowercase:


       """simple docstring"""







       def __init__(     self					:			List[Any]  ,      _lowerCAmelCase					:			List[Any]  ,      _lowerCAmelCase					:			Tuple       )					->   Any:
         _lowerCAmelCase						=		word
         _lowerCAmelCase						=		count



       def __eq__(     self					:			List[Any]  ,      _lowerCAmelCase					:			Union[str, Any]       )					->   Any:
         if not isinstance(UpperCAmelCase__  ,      UpperCAmelCase__       ):
           return NotImplemented
         return self.count == other.count






       def __lt__(     self					:			List[str]  ,      _lowerCAmelCase					:			List[Any]       )					->   Optional[int]:
         if not isinstance(UpperCAmelCase__  ,      UpperCAmelCase__       ):
           return NotImplemented
         return self.count < other.count



def 	_a  (					__SCREAMING_SNAKE_CASE					:  list[str]		,				__SCREAMING_SNAKE_CASE					:  int    ):






  """simple docstring"""




  _lowerCAmelCase						=		Heap()
  _lowerCAmelCase						=		Counter(lowerCamelCase_    )
  heap.build_max_heap(
      [WordCount(lowerCamelCase_		,				lowerCamelCase_    ) for word, count in count_by_word.items()]    )
  return [heap.extract_max().word for _ in range(min(lowerCamelCase_		,				len(lowerCamelCase_    )    )    )]


if __name__ == "__main__":
       import doctest

       doctest.testmod()




"""simple docstring"""






class       lowerCamelCase_		:





				"""simple docstring"""







				class       lowerCamelCase_		:





								"""simple docstring"""







								_lowerCAmelCase   :   Dict   				=       "_prev", "_data", "_next"



								def __init__(    self							,		UpperCAmelCase__							,		UpperCAmelCase__							,		UpperCAmelCase__  ):
												SCREAMING_SNAKE_CASE__  				=					link_p
												SCREAMING_SNAKE_CASE__  				=					element
												SCREAMING_SNAKE_CASE__  				=					link_n






								def 	lowerCAmelCase__		(    self  ):
												return (
												    f''' Prev -> {self._prev is not None}, Next -> {self._next is not None}'''
												)



				def __init__(    self  ):
								SCREAMING_SNAKE_CASE__  				=					self._Node(UpperCAmelCase__							,		UpperCAmelCase__							,		UpperCAmelCase__  )
								SCREAMING_SNAKE_CASE__  				=					self._Node(UpperCAmelCase__							,		UpperCAmelCase__							,		UpperCAmelCase__  )
								SCREAMING_SNAKE_CASE__  				=					self._trailer
								SCREAMING_SNAKE_CASE__  				=					self._header
								SCREAMING_SNAKE_CASE__  				=					0



				def __len__(    self  ):
								return self._size



				def 	lowerCAmelCase__		(    self  ):
								return self.__len__() == 0



				def 	lowerCAmelCase__		(    self							,		UpperCAmelCase__							,		UpperCAmelCase__							,		UpperCAmelCase__  ):
								# Create new_node by setting it's prev.link -> header
								# setting it's next.link -> trailer
								SCREAMING_SNAKE_CASE__  				=					self._Node(UpperCAmelCase__							,		UpperCAmelCase__							,		UpperCAmelCase__  )
								SCREAMING_SNAKE_CASE__  				=					new_node
								SCREAMING_SNAKE_CASE__  				=					new_node
								self._size += 1
								return self






				def 	lowerCAmelCase__		(    self							,		UpperCAmelCase__  ):
								SCREAMING_SNAKE_CASE__  				=					node._prev
								SCREAMING_SNAKE_CASE__  				=					node._next

								SCREAMING_SNAKE_CASE__  				=					successor
								SCREAMING_SNAKE_CASE__  				=					predecessor
								self._size -= 1
								SCREAMING_SNAKE_CASE__  				=					node._data
								SCREAMING_SNAKE_CASE__  				=					SCREAMING_SNAKE_CASE__  				=					SCREAMING_SNAKE_CASE__  				=					None
								del node
								return temp


class       lowerCamelCase_		(      _DoublyLinkedBase ):





				"""simple docstring"""







				def 	lowerCAmelCase__		(    self  ):
								if self.is_empty():
												raise Exception("List is empty"  )
								return self._header._next._data



				def 	lowerCAmelCase__		(    self  ):
								if self.is_empty():
												raise Exception("List is empty"  )
								return self._trailer._prev._data



				def 	lowerCAmelCase__		(    self							,		UpperCAmelCase__  ):
								return self._insert(self._header							,		UpperCAmelCase__							,		self._header._next  )



				def 	lowerCAmelCase__		(    self							,		UpperCAmelCase__  ):
								return self._insert(self._trailer._prev							,		UpperCAmelCase__							,		self._trailer  )



				def 	lowerCAmelCase__		(    self  ):
								if self.is_empty():
												raise IndexError("remove_first from empty list"  )
								return self._delete(self._header._next  )






				def 	lowerCAmelCase__		(    self  ):
								if self.is_empty():
												raise IndexError("remove_first from empty list"  )
								return self._delete(self._trailer._prev  )
