






from importlib import import_module

from .logging import get_logger


lowerCamelCase	:							str				=get_logger(__name__)





class 			__a  :







 def __init__(		self					:   Union[str, Any]							,   SCREAMING_SNAKE_CASE					:   List[str]							,   SCREAMING_SNAKE_CASE					:   Dict=None						):


      '''simple docstring'''






      UpperCamelCase__			:   Union[str, Any]       				=  attrs or []
      if module is not None:
           for key in module.__dict__:
                if key in attrs or not key.startswith("__"						):
                     setattr(self							,   UpperCamelCase_							,   getattr(UpperCamelCase_							,   UpperCamelCase_						)						)
      UpperCamelCase__			:   str       				=  module._original_module if isinstance(UpperCamelCase_							,   _PatchedModuleObj						) else module







class 			__a  :
 _lowerCAmelCase       :       List[str]        = []







 def __init__(		self					:   Any							,   SCREAMING_SNAKE_CASE					:   int							,   SCREAMING_SNAKE_CASE					:   List[Any]							,   SCREAMING_SNAKE_CASE					:   List[Any]							,   SCREAMING_SNAKE_CASE					:   List[Any]=None						):


      '''simple docstring'''






      UpperCamelCase__			:   Optional[int]       				=  obj
      UpperCamelCase__			:   Tuple       				=  target
      UpperCamelCase__			:   int       				=  new
      UpperCamelCase__			:   Union[str, Any]       				=  target.split("."						)[0]
      UpperCamelCase__			:   Union[str, Any]       				=  {}
      UpperCamelCase__			:   Any       				=  attrs or []







 def __enter__(		self					:   str						):


      '''simple docstring'''






      UpperCamelCase__			:   Union[str, Any]       				=  self.target.split("."						)

      # Patch modules:
      # it's used to patch attributes of submodules like "os.path.join";
      # in this case we need to patch "os" and "os.path"

      for i in range(len(UpperCamelCase_						)						):
           try:
                UpperCamelCase__			:   List[Any]       				=  import_module(".".join(submodules[: i + 1]						)						)
           except ModuleNotFoundError:
                continue
           # We iterate over all the globals in self.obj in case we find "os" or "os.path"
           for attr in self.obj.__dir__():
                UpperCamelCase__			:   int       				=  getattr(self.obj							,   UpperCamelCase_						)
                # We don't check for the name of the global, but rather if its value *is* "os" or "os.path".
                # This allows to patch renamed modules like "from os import path as ospath".
                if obj_attr is submodule or (
                    (isinstance(UpperCamelCase_							,   _PatchedModuleObj						) and obj_attr._original_module is submodule)
                ):
                     UpperCamelCase__			:   Tuple       				=  obj_attr
                     # patch at top level
                     setattr(self.obj							,   UpperCamelCase_							,   _PatchedModuleObj(UpperCamelCase_							,   attrs=self.attrs						)						)
                     UpperCamelCase__			:   List[Any]       				=  getattr(self.obj							,   UpperCamelCase_						)
                     # construct lower levels patches
                     for key in submodules[i + 1 :]:
                          setattr(UpperCamelCase_							,   UpperCamelCase_							,   _PatchedModuleObj(getattr(UpperCamelCase_							,   UpperCamelCase_							,   UpperCamelCase_						)							,   attrs=self.attrs						)						)
                          UpperCamelCase__			:   Tuple       				=  getattr(UpperCamelCase_							,   UpperCamelCase_						)
                     # finally set the target attribute
                     setattr(UpperCamelCase_							,   UpperCamelCase_							,   self.new						)

        # Patch attribute itself:
        # it's used for builtins like "open",
        # and also to patch "os.path.join" we may also need to patch "join"
        # itself if it was imported as "from os.path import join".

      if submodules:  # if it's an attribute of a submodule like "os.path.join"
           try:
                UpperCamelCase__			:   Dict       				=  getattr(import_module(".".join(UpperCamelCase_						)						)							,   UpperCamelCase_						)
           except (AttributeError, ModuleNotFoundError):
                return
           # We iterate over all the globals in self.obj in case we find "os.path.join"
           for attr in self.obj.__dir__():
                # We don't check for the name of the global, but rather if its value *is* "os.path.join".
                # This allows to patch renamed attributes like "from os.path import join as pjoin".
                if getattr(self.obj							,   UpperCamelCase_						) is attr_value:
                     UpperCamelCase__			:   Optional[int]       				=  getattr(self.obj							,   UpperCamelCase_						)
                     setattr(self.obj							,   UpperCamelCase_							,   self.new						)
      elif target_attr in globals()["__builtins__"]:  # if it'a s builtin like "open"
           UpperCamelCase__			:   Optional[Any]       				=  globals()['''__builtins__'''][target_attr]
           setattr(self.obj							,   UpperCamelCase_							,   self.new						)
      else:
           raise RuntimeError(F'Tried to patch attribute {target_attr} instead of a submodule.'						)







 def __exit__(		self					:   Tuple							,   *SCREAMING_SNAKE_CASE					:   Union[str, Any]						):


      '''simple docstring'''






      for attr in list(self.original						):
           setattr(self.obj							,   UpperCamelCase_							,   self.original.pop(UpperCamelCase_						)						)







 def 					__lowercase					(		self					:   str						):


      '''simple docstring'''






      self.__enter__()
      self._active_patches.append(self						)







 def 					__lowercase					(		self					:   str						):


      '''simple docstring'''






      try:
           self._active_patches.remove(self						)
      except ValueError:
           # If the patch hasn't been started this will fail
           return None

      return self.__exit__()



'''simple docstring'''
from collections import defaultdict
class    lowercase	:

		"""simple docstring"""

		def __init__(		self    ,   UpperCamelCase_    ,   UpperCamelCase_							):

							'''simple docstring'''


							UpperCamelCase__   :List[Any]												= total  # total no of tasks (N)

							# DP table will have a dimension of (2^M)*N
							# initially all values are set to -1
							UpperCamelCase__   :Union[str, Any]												= [
							    [-1 for i in range(total + 1							)] for j in range(2 ** len(UpperCamelCase_							)							)
							]

							UpperCamelCase__   :str												= defaultdict(UpperCamelCase_							)  # stores the list of persons for each task

							# final_mask is used to check if all persons are included by setting all bits
							# to 1
							UpperCamelCase__   :Optional[int]												= (1 << len(UpperCamelCase_							)) - 1




		def     lowerCAmelCase__				(		self    ,   UpperCamelCase_    ,   UpperCamelCase_							):

							'''simple docstring'''


							if mask == self.final_mask:
												return 1

							# if not everyone gets the task and no more tasks are available, return 0
							if task_no > self.total_tasks:
												return 0

							# if case already considered
							if self.dp[mask][task_no] != -1:
												return self.dp[mask][task_no]

							# Number of ways when we don't this task in the arrangement
							UpperCamelCase__   :str												= self.count_ways_until(UpperCamelCase_    ,   task_no + 1							)

							# now assign the tasks one by one to all possible persons and recursively
							# assign for the remaining tasks.
							if task_no in self.task:
												for p in self.task[task_no]:
																	# if p is already given a task
																	if mask & (1 << p):
																						continue

																	# assign this task to p and change the mask value. And recursively
																	# assign tasks with the new mask value.
																	total_ways_util += self.count_ways_until(mask | (1 << p)    ,   task_no + 1							)

        # save the value.
							UpperCamelCase__   :Optional[int]												= total_ways_util

							return self.dp[mask][task_no]




		def     lowerCAmelCase__				(		self    ,   UpperCamelCase_							):

							'''simple docstring'''


							for i in range(len(UpperCamelCase_							)							):
												for j in task_performed[i]:
																	self.task[j].append(UpperCamelCase_							)

        # call the function to fill the DP table, final answer is stored in dp[0][1]
							return self.count_ways_until(0    ,   1							)


if __name__ == "__main__":
		__snake_case							      =     5  # total no of tasks (the value of N)

		# the list of tasks that can be done by M persons.
		__snake_case							      =     [[1, 3, 4], [1, 2, 5], [3, 4]]
		print(
		    AssignmentUsingBitmask(task_performed, total_tasks).count_no_of_ways(
		        task_performed
		    )
		)