from collections import defaultdict







class 	__snake_case      :
 def __init__(     self						,      snake_case__						,      snake_case__  )		->							Union[str, Any]:
       '''simple docstring'''





       UpperCAmelCase			:       Optional[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			:       Optional[int]			     =[
           [-1 for i in range(total + 1  )] for j in range(2 ** len(__lowerCAmelCase  )  )
       ]

       UpperCAmelCase			:       Any			     =defaultdict(__lowerCAmelCase  )  # 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[Any]			     =(1 << len(__lowerCAmelCase  )) - 1
 def 		UpperCAmelCase__				(     self						,      snake_case__						,      snake_case__  )		->							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
       UpperCAmelCase			:       int			     =self.count_ways_until(__lowerCAmelCase						,      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			:       Union[str, Any]			     =total_ways_util

       return self.dp[mask][task_no]






 def 		UpperCAmelCase__				(     self						,      snake_case__  )		->							List[str]:
       '''simple docstring'''





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

        # 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
         )
     )

'''simple docstring'''




def 				snake_case__							(			_A:					str )    ->	list[int]:

		'''simple docstring'''


		lowerCAmelCase   					=  [0 for i in range(len(_A ) )]

		# initialize interval's left pointer and right pointer
		lowerCAmelCase					,     lowerCAmelCase   					=  0, 0

		for i in range(1      ,   len(_A ) ):
				# case when current index is inside the interval
				if i <= right_pointer:
						lowerCAmelCase   					=  min(right_pointer - i + 1      ,   z_result[i - left_pointer] )
						lowerCAmelCase   					=  min_edge

				while go_next(_A      ,   _A      ,   _A ):
						z_result[i] += 1

				# if new index's result gives us more right interval,
				# we've to update left_pointer and right_pointer
				if i + z_result[i] - 1 > right_pointer:
						lowerCAmelCase					,     lowerCAmelCase   					=  i, i + z_result[i] - 1

		return z_result






def 				snake_case__							(			_A:					int      ,   _A:					list[int]      ,   _A:					str )    ->	bool:

		'''simple docstring'''


		return i + z_result[i] < len(_A ) and s[z_result[i]] == s[i + z_result[i]]






def 				snake_case__							(			_A:					str      ,   _A:					str )    ->	int:

		'''simple docstring'''


		lowerCAmelCase   					=  0
		# concatenate 'pattern' and 'input_str' and call z_function
		# with concatenated string
		lowerCAmelCase   					=  z_function(pattern + input_str )

		for val in z_result:
				# if value is greater then length of the pattern string
				# that means this index is starting position of substring
				# which is equal to pattern string
				if val >= len(_A ):
						answer += 1

		return answer


if __name__ == "__main__":
						import doctest

						doctest.testmod()




