

"""simple docstring"""




from collections import defaultdict





class  lowerCamelCase    :

			def __init__(       self					:    Tuple     ,					__UpperCAmelCase					:    Union[str, Any]     ,					__UpperCAmelCase					:    Dict							) ->     List[str]:
						SCREAMING_SNAKE_CASE__										=   total  # total no of tasks (N)

						# DP table will have a dimension of (2^M)*N
						# initially all values are set to -1
						SCREAMING_SNAKE_CASE__										=   [
						    [-1 for i in range(total + 1							)] for j in range(2 ** len(__UpperCAmelCase							)							)
						]

						SCREAMING_SNAKE_CASE__										=   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
						SCREAMING_SNAKE_CASE__										=   (1 << len(__UpperCAmelCase							)) - 1

			def        SCREAMING_SNAKE_CASE					(       self					:    List[Any]     ,					__UpperCAmelCase					:    List[Any]     ,					__UpperCAmelCase					:    List[str]							) ->     Tuple:
						# if mask == self.finalmask all persons are distributed tasks, return 1
						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
						SCREAMING_SNAKE_CASE__										=   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.
						SCREAMING_SNAKE_CASE__										=   total_ways_util

						return self.dp[mask][task_no]





			def        SCREAMING_SNAKE_CASE					(       self					:    Any     ,					__UpperCAmelCase					:    Tuple							) ->     str:
						# Store the list of persons for each task
						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__":
						A_				:      str           =			5  # total no of tasks (the value of N)

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





"""simple docstring"""




# flake8: noqa
# Lint as: python3
A_				:      List[str]           =			[
    "VerificationMode",
    "Version",
    "disable_progress_bar",
    "enable_progress_bar",
    "is_progress_bar_enabled",
    "experimental",
]

from .info_utils import VerificationMode
from .logging import disable_progress_bar, enable_progress_bar, is_progress_bar_enabled
from .version import Version
from .experimental import experimental


