



from collections import defaultdict



class 				lowerCAmelCase_		:
       def __init__(			self,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )     ->		Optional[int]:
          UpperCamelCase    :  int							=	total  # total no of tasks (N)

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

          UpperCamelCase    :  str							=	defaultdict(SCREAMING_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
          UpperCamelCase    :  Union[str, Any]							=	(1 << len(SCREAMING_SNAKE_CASE_       )) - 1
       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )     ->		Optional[int]:
          # 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
          UpperCamelCase    :  Optional[Any]							=	self.count_ways_until(SCREAMING_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.
          UpperCamelCase    :  List[str]							=	total_ways_util

          return self.dp[mask][task_no]






       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_       )     ->		List[str]:
          # Store the list of persons for each task
          for i in range(len(SCREAMING_SNAKE_CASE_       )       ):
             for j in task_performed[i]:
                self.task[j].append(SCREAMING_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
        )
    )








from __future__ import annotations

from typing import Any



class 				lowerCAmelCase_		:
       def __init__(			self,			SCREAMING_SNAKE_CASE_       )     ->		None:
          UpperCamelCase    :  Any							=	num_of_nodes
          UpperCamelCase    :  list[list[int]]							=	[]
          UpperCamelCase    :  dict[int, int]							=	{}
       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )     ->		None:
          self.m_edges.append([u_node, v_node, weight]       )
       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_       )     ->		int:

          if self.m_component[u_node] == u_node:
             return u_node
          return self.find_component(self.m_component[u_node]       )
       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_       )     ->		None:

          if self.m_component[u_node] != u_node:
             for k in self.m_component:
                UpperCamelCase    :  Dict							=	self.find_component(SCREAMING_SNAKE_CASE_       )
       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )     ->		None:

          if component_size[u_node] <= component_size[v_node]:
             UpperCamelCase    :  Tuple							=	v_node
             component_size[v_node] += component_size[u_node]
             self.set_component(SCREAMING_SNAKE_CASE_       )

          elif component_size[u_node] >= component_size[v_node]:
             UpperCamelCase    :  Union[str, Any]							=	self.find_component(SCREAMING_SNAKE_CASE_       )
             component_size[u_node] += component_size[v_node]
             self.set_component(SCREAMING_SNAKE_CASE_       )






       def 					snake_case_       (			self       )     ->		None:
          UpperCamelCase    :  int							=	[]
          UpperCamelCase    :  int							=	0

          UpperCamelCase    :  list[Any]							=	[-1] * self.m_num_of_nodes

          # A list of components (initialized to all of the nodes)
          for node in range(self.m_num_of_nodes       ):
             self.m_component.update({node: node}       )
             component_size.append(1       )

          UpperCamelCase    :  List[str]							=	self.m_num_of_nodes

          while num_of_components > 1:
             for edge in self.m_edges:
                UpperCamelCase	,     UpperCamelCase	,     UpperCamelCase    :  List[Any]							=	edge

                UpperCamelCase    :  str							=	self.m_component[u]
                UpperCamelCase    :  Any							=	self.m_component[v]

                if u_component != v_component:

                   for component in (u_component, v_component):
                      if (
                          minimum_weight_edge[component] == -1
                          or minimum_weight_edge[component][2] > w
                      ):
                         UpperCamelCase    :  Any							=	[u, v, w]

             for edge in minimum_weight_edge:
                if isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
                   UpperCamelCase	,     UpperCamelCase	,     UpperCamelCase    :  int							=	edge

                   UpperCamelCase    :  List[Any]							=	self.m_component[u]
                   UpperCamelCase    :  Tuple							=	self.m_component[v]

                   if u_component != v_component:
                      mst_weight += w
                      self.union(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )
                      print(F"""Added edge [{u} - {v}]\nAdded weight: {w}\n"""       )
                      num_of_components -= 1

             UpperCamelCase    :  Optional[Any]							=	[-1] * self.m_num_of_nodes
          print(F"""The total weight of the minimal spanning tree is: {mst_weight}"""       )






def 		UpperCamelCase	(   )	->     None:
   pass


if __name__ == "__main__":
    import doctest

    doctest.testmod()



