





'''simple docstring'''




class 					SCREAMING_SNAKE_CASE       :


     def __init__(		self):

          '''simple docstring'''






          __A		:					Union[str, Any]						=			{}


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          print(self.vertex)
          for i in self.vertex:
               print(_UpperCAmelCase		,      ' -> '		,      ' -> '.join([str(_UpperCAmelCase) for j in self.vertex[i]]))


     def 				SCREAMING_SNAKE_CASE    (		self		,      _UpperCAmelCase		,      _UpperCAmelCase):

          '''simple docstring'''






          if from_vertex in self.vertex:
               self.vertex[from_vertex].append(_UpperCAmelCase)
          else:
               # else make a new vertex
               __A		:					Tuple						=			[to_vertex]


     def 				SCREAMING_SNAKE_CASE    (		self):

          '''simple docstring'''






          __A		:					str						=			[False] * len(self.vertex)

          # call the recursive helper function
          for i in range(len(self.vertex)):
               if not visited[i]:
                    self.dfs_recursive(_UpperCAmelCase		,      _UpperCAmelCase)


     def 				SCREAMING_SNAKE_CASE    (		self		,      _UpperCAmelCase		,      _UpperCAmelCase):

          '''simple docstring'''






          __A		:					Dict						=			True

          print(_UpperCAmelCase		,      end=' ')

          # Recur for all the vertices that are adjacent to this node
          for i in self.vertex:
               if not visited[i]:
                    self.dfs_recursive(_UpperCAmelCase		,      _UpperCAmelCase)


if __name__ == "__main__":
  lowercase__       : Any         =       Graph()
  g.add_edge(0, 1)
  g.add_edge(0, 2)
  g.add_edge(1, 2)
  g.add_edge(2, 0)
  g.add_edge(2, 3)
  g.add_edge(3, 3)

  g.print_graph()
  print('''DFS:''')
  g.dfs()

  # OUTPUT:
  # 0  ->  1 -> 2
  # 1  ->  2
  # 2  ->  0 -> 3
  # 3  ->  3
  # DFS:
  #  0 1 2 3






'''simple docstring'''




def 			_lowerCAmelCase     (    __snake_case    :					Optional[Any]     )	->	Optional[Any]:  # noqa: E741
     __A		:					Tuple						=			len(__snake_case     )
     __A		:					Optional[int]						=			0
     __A		:					str						=			[0] * n
     __A		:					int						=			[False] * n
     __A		:					Tuple						=			[False] * n

     def dfs(__snake_case    :					List[str]					,				__snake_case    :					List[Any]					,				__snake_case    :					Optional[Any]					,				__snake_case    :					int     ):
          if parent == root:
               out_edge_count += 1
          __A		:					str						=			True
          __A		:					Tuple						=			at

          for to in l[at]:
               if to == parent:
                    pass
               elif not visited[to]:
                    __A		:					Optional[int]						=			dfs(__snake_case					,				__snake_case					,				__snake_case					,				__snake_case     )
                    __A		:					int						=			min(low[at]					,				low[to]     )

                    # AP found via bridge
                    if at < low[to]:
                         __A		:					Tuple						=			True
                    # AP found via cycle
                    if at == low[to]:
                         __A		:					Optional[Any]						=			True
               else:
                    __A		:					Any						=			min(low[at]					,				__snake_case     )
          return out_edge_count

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

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


# Adjacency list of graph
lowercase__       : Tuple         =       {
    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)