
from __future__ import annotations

from typing import Any




class 			UpperCAmelCase_     :


  '''simple docstring'''







  def __init__(					self     :					Any     ,				UpperCamelCase__     :					Any       )     ->      List[Any]:







    """simple docstring"""






    __magic_name__								=			num_of_nodes
    __magic_name__								=			[]
    __magic_name__								=			{}
  def 				_lowercase				(					self     :					List[str]     ,				UpperCamelCase__     :					List[Any]     ,				UpperCamelCase__     :					Tuple     ,				UpperCamelCase__     :					str       )     ->      Union[str, Any]:







    """simple docstring"""






    self.m_edges.append([u_node, v_node, weight]       )
  def 				_lowercase				(					self     :					Tuple     ,				UpperCamelCase__     :					List[str]       )     ->      Optional[int]:







    """simple docstring"""






    if self.m_component[u_node] == u_node:
      return u_node
    return self.find_component(self.m_component[u_node]       )
  def 				_lowercase				(					self     :					str     ,				UpperCamelCase__     :					Dict       )     ->      Dict:







    """simple docstring"""






    if self.m_component[u_node] != u_node:
      for k in self.m_component:
        __magic_name__								=			self.find_component(lowerCamelCase__       )
  def 				_lowercase				(					self     :					List[str]     ,				UpperCamelCase__     :					Any     ,				UpperCamelCase__     :					List[Any]     ,				UpperCamelCase__     :					List[Any]       )     ->      List[str]:







    """simple docstring"""






    if component_size[u_node] <= component_size[v_node]:
      __magic_name__								=			v_node
      component_size[v_node] += component_size[u_node]
      self.set_component(lowerCamelCase__       )

    elif component_size[u_node] >= component_size[v_node]:
      __magic_name__								=			self.find_component(lowerCamelCase__       )
      component_size[u_node] += component_size[v_node]
      self.set_component(lowerCamelCase__       )





  def 				_lowercase				(					self     :					Union[str, Any]       )     ->      int:







    """simple docstring"""






    __magic_name__								=			[]
    __magic_name__								=			0

    __magic_name__								=			[-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       )

    __magic_name__								=			self.m_num_of_nodes

    while num_of_components > 1:
      for edge in self.m_edges:
        __magic_name__								=			edge

        __magic_name__								=			self.m_component[u]
        __magic_name__								=			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
            ):
              __magic_name__								=			[u, v, w]

      for edge in minimum_weight_edge:
        if isinstance(lowerCamelCase__     ,				lowerCamelCase__       ):
          __magic_name__								=			edge

          __magic_name__								=			self.m_component[u]
          __magic_name__								=			self.m_component[v]

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

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







def a__       (			):






  '''simple docstring'''





  pass


if __name__ == "__main__":
    import doctest

    doctest.testmod()




def 			_A	(      SCREAMING_SNAKE_CASE      ):  # noqa: E741
	UpperCAmelCase__:	int									= len(SCREAMING_SNAKE_CASE      )
	UpperCAmelCase__:	Dict									= 0
	UpperCAmelCase__:	Optional[int]									= [0] * n
	UpperCAmelCase__:	List[str]									= [False] * n
	UpperCAmelCase__:	List[str]									= [False] * n

	def dfs(SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE      ):
		if parent == root:
			out_edge_count += 1
		UpperCAmelCase__:	List[str]									= True
		UpperCAmelCase__:	List[Any]									= at

		for to in l[at]:
			if to == parent:
				pass
			elif not visited[to]:
				UpperCAmelCase__:	str									= dfs(SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE      )
				UpperCAmelCase__:	Optional[Any]									= min(low[at]	,low[to]      )

				# AP found via bridge
				if at < low[to]:
					UpperCAmelCase__:	List[Any]									= True
				# AP found via cycle
				if at == low[to]:
					UpperCAmelCase__:	str									= True
			else:
				UpperCAmelCase__:	Union[str, Any]									= min(low[at]	,SCREAMING_SNAKE_CASE      )
		return out_edge_count

	for i in range(SCREAMING_SNAKE_CASE      ):
		if not visited[i]:
			UpperCAmelCase__:	Optional[Any]									= 0
			UpperCAmelCase__:	Union[str, Any]									= dfs(SCREAMING_SNAKE_CASE	,SCREAMING_SNAKE_CASE	,-1	,SCREAMING_SNAKE_CASE      )
			UpperCAmelCase__:	Tuple									= out_edge_count > 1

	for x in range(len(SCREAMING_SNAKE_CASE      )      ):
		if is_art[x] is True:
			print(SCREAMING_SNAKE_CASE      )


# Adjacency list of graph
_lowerCAmelCase  :      Any			 ={
    0: [1, 2],
    1: [0, 2],
    2: [0, 1, 3, 5],
    3: [2, 4],
    4: [3],
    5: [2, 6, 8],
    6: [5, 7],
    7: [6, 8],
    8: [5, 7],
}
compute_ap(data)