






'''simple docstring'''
from collections import defaultdict


class 							_UpperCAmelCase    :




    def __init__(      self	:							Optional[Any]	,  a	:							Dict	,  a	:							List[str]      ):






       '''simple docstring'''






       lowercase_						:     Tuple							     =  total  # total no of tasks (N)

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

       lowercase_						:     Optional[int]							     =  defaultdict(snake_case_      )  # 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
       lowercase_						:     Optional[int]							     =  (1 << len(snake_case_      )) - 1




    def 					lowerCAmelCase__					(      self	:							Union[str, Any]	,  a	:							Optional[int]	,  a	:							List[Any]      ):






       '''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
       lowercase_						:     Optional[int]							     =  self.count_ways_until(snake_case_	,  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.
       lowercase_						:     List[str]							     =  total_ways_util

       return self.dp[mask][task_no]





    def 					lowerCAmelCase__					(      self	:							str	,  a	:							List[Any]      ):






       '''simple docstring'''






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

        # 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__":
 UpperCamelCase__			=      5  # total no of tasks (the value of N)

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





"""simple docstring"""



def  _A(		lowerCAmelCase			,  lowerCAmelCase							):
							A__       :     List[Any]								=			[1]
							for i in range(2			,  lowerCAmelCase							):
														factorials.append(factorials[-1] * i							)
							assert 0 <= k < factorials[-1] * n, "k out of bounds"

							A__       :     Union[str, Any]								=			[]
							A__       :     int								=			list(range(lowerCAmelCase							)							)

							# Find permutation
							while factorials:
														A__       :     Optional[int]								=			factorials.pop()
														A__				,							A__       :     Union[str, Any]								=			divmod(lowerCAmelCase			,  lowerCAmelCase							)
														permutation.append(elements[number]							)
														elements.remove(elements[number]							)
							permutation.append(elements[0]							)

							return permutation


if __name__ == "__main__":
				import doctest

				doctest.testmod()





