





from __future__ import annotations

from collections import deque
from collections.abc import Iterator
from dataclasses import dataclass

@dataclass
class      lowerCAmelCase							:
 UpperCAmelCase__									=	42
 UpperCAmelCase__									=	42



class      lowerCAmelCase							:
 def __init__(   self						:   Any    ,  UpperCAmelCase						:   int			)    ->			Tuple:
     lowerCamelCase__					:   list[list[Edge]]      				=	[[] for _ in range(UpperCAmelCase			)]
     lowerCamelCase__					:   Tuple      				=	size
 def __getitem__(   self						:   Optional[Any]    ,  UpperCAmelCase						:   int			)    ->			Iterator[Edge]:
     return iter(self._graph[vertex]			)
 @property
 def   A_			(   self						:   int			)    ->			str:
     return self._size
 def   A_			(   self						:   Optional[Any]    ,  UpperCAmelCase						:   int    ,  UpperCAmelCase						:   int    ,  UpperCAmelCase						:   int			)    ->			Optional[int]:
     if weight not in (0, 1):
         raise ValueError('Edge weight must be either 0 or 1.'			)

     if to_vertex < 0 or to_vertex >= self.size:
         raise ValueError('Vertex indexes must be in [0; size).'			)

     self._graph[from_vertex].append(Edge(UpperCAmelCase    ,  UpperCAmelCase			)			)







 def   A_			(   self						:   str    ,  UpperCAmelCase						:   int    ,  UpperCAmelCase						:   int			)    ->			int | None:
     lowerCamelCase__					:   int      				=	deque([start_vertex]			)
     lowerCamelCase__					:   list[int | None]      				=	[None] * self.size
     lowerCamelCase__					:   Tuple      				=	0

     while queue:
         lowerCamelCase__					:   str      				=	queue.popleft()
         lowerCamelCase__					:   List[Any]      				=	distances[current_vertex]
         if current_distance is None:
             continue

         for edge in self[current_vertex]:
             lowerCamelCase__					:   Union[str, Any]      				=	current_distance + edge.weight
             lowerCamelCase__					:   int      				=	distances[edge.destination_vertex]
             if (
                 isinstance(UpperCAmelCase    ,  UpperCAmelCase			)
                 and new_distance >= dest_vertex_distance
             ):
                 continue
             lowerCamelCase__					:   Optional[int]      				=	new_distance
             if edge.weight == 0:
                 queue.appendleft(edge.destination_vertex			)
             else:
                 queue.append(edge.destination_vertex			)

     if distances[finish_vertex] is None:
         raise ValueError('No path from start_vertex to finish_vertex.'			)

     return distances[finish_vertex]


if __name__ == "__main__":
    import doctest

    doctest.testmod()












class      lowerCAmelCase							:
 def __init__(   self						:   Union[str, Any]    ,  UpperCAmelCase						:   list			)    ->			None:
     lowerCamelCase__					:   int      				=	set_counts
     lowerCamelCase__					:   List[str]      				=	max(UpperCAmelCase			)
     lowerCamelCase__					:   Dict      				=	len(UpperCAmelCase			)
     lowerCamelCase__					:   List[str]      				=	[1] * num_sets
     lowerCamelCase__					:   List[str]      				=	list(range(UpperCAmelCase			)			)
 def   A_			(   self						:   Dict    ,  UpperCAmelCase						:   int    ,  UpperCAmelCase						:   int			)    ->			bool:
     lowerCamelCase__					:   List[str]      				=	self.get_parent(UpperCAmelCase			)
     lowerCamelCase__					:   List[str]      				=	self.get_parent(UpperCAmelCase			)

     if src_parent == dst_parent:
         return False

     if self.ranks[dst_parent] >= self.ranks[src_parent]:
         self.set_counts[dst_parent] += self.set_counts[src_parent]
         lowerCamelCase__					:   Union[str, Any]      				=	0
         lowerCamelCase__					:   str      				=	dst_parent
         if self.ranks[dst_parent] == self.ranks[src_parent]:
             self.ranks[dst_parent] += 1
         lowerCamelCase__					:   int      				=	self.set_counts[dst_parent]
     else:
         self.set_counts[src_parent] += self.set_counts[dst_parent]
         lowerCamelCase__					:   List[str]      				=	0
         lowerCamelCase__					:   Tuple      				=	src_parent
         lowerCamelCase__					:   List[str]      				=	self.set_counts[src_parent]

     lowerCamelCase__					:   Optional[int]      				=	max(self.max_set    ,  UpperCAmelCase			)
     return True







 def   A_			(   self						:   str    ,  UpperCAmelCase						:   int			)    ->			int:
     if self.parents[disj_set] == disj_set:
         return disj_set
     lowerCamelCase__					:   Dict      				=	self.get_parent(self.parents[disj_set]			)
     return self.parents[disj_set]





