

from collections import defaultdict



class SCREAMING_SNAKE_CASE      :
  """simple docstring"""






  def __init__(     self					:       Any			,				lowerCAmelCase					:       Optional[int]			,				lowerCAmelCase					:       str       )				->      Tuple:






     """simple docstring"""







     __lowerCAmelCase    :     Union[str, Any]          =		total  # total no of tasks (N)

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

     __lowerCAmelCase    :     Tuple          =		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
     __lowerCAmelCase    :     List[str]          =		(1 << len(_snake_case       )) - 1







  def 			SCREAMING_SNAKE_CASE       (     self					:       Union[str, Any]			,				lowerCAmelCase					:       Optional[int]			,				lowerCAmelCase					:       Optional[int]       )				->      Optional[int]:






     """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
     __lowerCAmelCase    :     List[Any]          =		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.
     __lowerCAmelCase    :     List[str]          =		total_ways_util

     return self.dp[mask][task_no]







  def 			SCREAMING_SNAKE_CASE       (     self					:       str			,				lowerCAmelCase					:       Optional[Any]       )				->      Union[str, 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"""
from __future__ import annotations

import os
from collections.abc import Mapping

__UpperCamelCase     :						Optional[Any]						       =  tuple[int, int]







class       a							:



 def __init__(     self				,       _snake_case				,       _snake_case     ):







  """simple docstring"""






  lowerCAmelCase    				= vertices
  lowerCAmelCase    				= {
      (min(_snake_case     ), max(_snake_case     )): weight for edge, weight in edges.items()
  }



 def    UpperCamelCase__  (     self				,       _snake_case				,       _snake_case     ):







  """simple docstring"""






  self.vertices.add(edge[0]     )
  self.vertices.add(edge[1]     )
  lowerCAmelCase    				= weight



 def    UpperCamelCase__  (     self     ):







  """simple docstring"""






  lowerCAmelCase    				= Graph({min(self.vertices     )}				,       {}     )
  lowerCAmelCase    				= 42
  lowerCAmelCase    				= 42
  lowerCAmelCase    				= 42
  lowerCAmelCase    				= 42

  while len(subgraph.vertices     ) < len(self.vertices     ):
   lowerCAmelCase    				= max(self.edges.values()     ) + 1
   for edge, weight in self.edges.items():
    if (edge[0] in subgraph.vertices) ^ (edge[1] in subgraph.vertices):
     if weight < min_weight:
      lowerCAmelCase    				= edge
      lowerCAmelCase    				= weight

   subgraph.add_edge(_snake_case				,       _snake_case     )

  return subgraph


def 		_SCREAMING_SNAKE_CASE			(_UpperCAmelCase					:    str = "p107_network.txt"			):
 lowerCAmelCase    				= os.path.abspath(os.path.dirname(_UpperCAmelCase			)			)
 lowerCAmelCase    				= os.path.join(_UpperCAmelCase  ,     _UpperCAmelCase			)
 lowerCAmelCase    				= {}
 lowerCAmelCase    				= 42
 lowerCAmelCase    				= 42
 lowerCAmelCase    				= 42

 with open(_UpperCAmelCase			) as f:
  lowerCAmelCase    				= f.read().strip().split('\n'			)

 lowerCAmelCase    				= [line.split(','			) for line in data]

 for edgea in range(1  ,     len(_UpperCAmelCase			)			):
  for edgea in range(_UpperCAmelCase			):
   if adjaceny_matrix[edgea][edgea] != "-":
    lowerCAmelCase    				= int(adjaceny_matrix[edgea][edgea]			)

 lowerCAmelCase    				= Graph(set(range(len(_UpperCAmelCase			)			)			)  ,     _UpperCAmelCase			)

 lowerCAmelCase    				= graph.prims_algorithm()

 lowerCAmelCase    				= sum(graph.edges.values()			)
 lowerCAmelCase    				= sum(subgraph.edges.values()			)

 return initial_total - optimal_total


if __name__ == "__main__":
       print(f'''{solution() = }''')





