


import os
from pickle import UnpicklingError
from typing import Dict, Tuple

import jax
import jax.numpy as jnp
import numpy as np
from flax.serialization import from_bytes
from flax.traverse_util import flatten_dict, unflatten_dict

import transformers

from .utils import logging


__lowerCAmelCase			=							logging.get_logger(__name__)




def        snake_case_					(  snake_case      ,							snake_case      ,							snake_case      ,							snake_case=False					)  ->    List[Any]:






       try:
              import torch  # noqa: F401
       except ImportError:
              logger.error(
                  'Loading a PyTorch model in Flax, requires both PyTorch and Flax to be installed. Please see'
                  ' https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation'
                  ' instructions.'					)
              raise

       if not is_sharded:
              lowercase__:       Optional[Any]        =       os.path.abspath(SCREAMING_SNAKE_CASE_					)
              logger.info(f'Loading PyTorch weights from {pt_path}'					)

              lowercase__:       Optional[Any]        =       torch.load(SCREAMING_SNAKE_CASE_      ,							map_location='cpu'					)
              logger.info(f'PyTorch checkpoint contains {sum(t.numel() for t in pt_state_dict.values()					):,} parameters.'					)

              lowercase__:       Optional[int]        =       convert_pytorch_state_dict_to_flax(SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)
       else:
              # model is sharded and pytorch_checkpoint_path already contains the list of .pt shard files
              lowercase__:       int        =       convert_pytorch_sharded_state_dict_to_flax(SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)
       return flax_state_dict




def        snake_case_					(  snake_case      ,							snake_case      ,							snake_case      ,							snake_case      ,							)  ->    (Tuple[str], np.ndarray):






       def is_key_or_prefix_key_in_dict(snake_case					) -> bool:
              return len(set(SCREAMING_SNAKE_CASE_					) & {key, (model_prefix,) + key}					) > 0

       # layer norm
       lowercase__:       str        =       pt_tuple_key[:-1] + ('scale',)
       if pt_tuple_key[-1] in ["weight", "gamma"] and is_key_or_prefix_key_in_dict(SCREAMING_SNAKE_CASE_					):
              return renamed_pt_tuple_key, pt_tensor

       # batch norm layer mean
       lowercase__:       str        =       pt_tuple_key[:-1] + ('mean',)
       if pt_tuple_key[-1] == "running_mean" and not is_key_or_prefix_key_in_dict(SCREAMING_SNAKE_CASE_					):
              return renamed_pt_tuple_key, pt_tensor

       # batch norm layer var
       lowercase__:       int        =       pt_tuple_key[:-1] + ('var',)
       if pt_tuple_key[-1] == "running_var" and not is_key_or_prefix_key_in_dict(SCREAMING_SNAKE_CASE_					):
              return renamed_pt_tuple_key, pt_tensor

       # embedding
       lowercase__:       Optional[int]        =       pt_tuple_key[:-1] + ('embedding',)
       if pt_tuple_key[-1] == "weight" and is_key_or_prefix_key_in_dict(SCREAMING_SNAKE_CASE_					):
              return renamed_pt_tuple_key, pt_tensor

       # conv layer
       lowercase__:       int        =       pt_tuple_key[:-1] + ('kernel',)
       if pt_tuple_key[-1] == "weight" and pt_tensor.ndim == 4 and not is_key_or_prefix_key_in_dict(SCREAMING_SNAKE_CASE_					):
              lowercase__:       Optional[int]        =       pt_tensor.transpose(2      ,							3      ,							1      ,							0					)
              return renamed_pt_tuple_key, pt_tensor

       # linear layer
       lowercase__:       Union[str, Any]        =       pt_tuple_key[:-1] + ('kernel',)
       if pt_tuple_key[-1] == "weight" and not is_key_or_prefix_key_in_dict(SCREAMING_SNAKE_CASE_					):
              lowercase__:       Any        =       pt_tensor.T
              return renamed_pt_tuple_key, pt_tensor

       # old PyTorch layer norm weight
       lowercase__:       List[str]        =       pt_tuple_key[:-1] + ('weight',)
       if pt_tuple_key[-1] == "gamma":
              return renamed_pt_tuple_key, pt_tensor

       # old PyTorch layer norm bias
       lowercase__:       List[str]        =       pt_tuple_key[:-1] + ('bias',)
       if pt_tuple_key[-1] == "beta":
              return renamed_pt_tuple_key, pt_tensor

       # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030
       lowercase__:       Optional[Any]        =       None
       if pt_tuple_key[-3::2] == ("parametrizations", "original0"):
              lowercase__:       str        =       pt_tuple_key[-2] + '_g'
       elif pt_tuple_key[-3::2] == ("parametrizations", "original1"):
              lowercase__:       Tuple        =       pt_tuple_key[-2] + '_v'
       if name is not None:
              lowercase__:       int        =       pt_tuple_key[:-3] + (name,)
              return renamed_pt_tuple_key, pt_tensor

       return pt_tuple_key, pt_tensor




def        snake_case_					(  snake_case      ,							snake_case					)  ->    int:
       lowercase__:       int        =       {k: v.numpy() for k, v in pt_state_dict.items()}

       lowercase__:       List[Any]        =       flax_model.base_model_prefix

       # use params dict if the model contains batch norm layers
       if "params" in flax_model.params:
              lowercase__:       Optional[Any]        =       flax_model.params['params']
       else:
              lowercase__:       List[str]        =       flax_model.params
       lowercase__:       Optional[Any]        =       flatten_dict(SCREAMING_SNAKE_CASE_					)

       # add batch_stats keys,values to dict
       if "batch_stats" in flax_model.params:
              lowercase__:       Tuple        =       flatten_dict(flax_model.params['batch_stats']					)
              random_flax_state_dict.update(SCREAMING_SNAKE_CASE_					)

       lowercase__:       Dict        =       {}

       lowercase__:       int        =       (model_prefix not in flax_model_params) and (
           model_prefix in {k.split('.'					)[0] for k in pt_state_dict.keys()}
       )
       lowercase__:       Tuple        =       (model_prefix in flax_model_params) and (
           model_prefix not in {k.split('.'					)[0] for k in pt_state_dict.keys()}
       )

       # Need to change some parameters name to match Flax names
       for pt_key, pt_tensor in pt_state_dict.items():
              lowercase__:       Tuple        =       tuple(pt_key.split('.'					)					)

              # remove base model prefix if necessary
              lowercase__:       Dict        =       pt_tuple_key[0] == model_prefix
              if load_model_with_head_into_base_model and has_base_model_prefix:
                     lowercase__:       Union[str, Any]        =       pt_tuple_key[1:]

              # Correctly rename weight parameters
              lowercase__      ,						lowercase__:       List[str]        =       rename_key_and_reshape_tensor(
                  SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)

              # add model prefix if necessary
              lowercase__:       List[Any]        =       (model_prefix,) + flax_key in random_flax_state_dict
              if load_base_model_into_model_with_head and require_base_model_prefix:
                     lowercase__:       Union[str, Any]        =       (model_prefix,) + flax_key

              if flax_key in random_flax_state_dict:
                     if flax_tensor.shape != random_flax_state_dict[flax_key].shape:
                            raise ValueError(
                                f'PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape '
                                f'{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}.'					)

        # add batch stats if the model contains batchnorm layers
              if "batch_stats" in flax_model.params:
                     if "mean" in flax_key[-1] or "var" in flax_key[-1]:
                            lowercase__:       Optional[Any]        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)
                            continue
                     # remove num_batches_tracked key
                     if "num_batches_tracked" in flax_key[-1]:
                            flax_state_dict.pop(SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)
                            continue

                     # also add unexpected weight so that warning is thrown
                     lowercase__:       Optional[Any]        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)

              else:
                     # also add unexpected weight so that warning is thrown
                     lowercase__:       Any        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)

       return unflatten_dict(SCREAMING_SNAKE_CASE_					)




def        snake_case_					(  snake_case      ,							snake_case					)  ->    Any:
       import torch

       # Load the index
       lowercase__:       List[str]        =       {}
       for shard_file in shard_filenames:
              # load using msgpack utils
              lowercase__:       List[str]        =       torch.load(SCREAMING_SNAKE_CASE_					)
              lowercase__:       Union[str, Any]        =       {k: v.numpy() for k, v in pt_state_dict.items()}

              lowercase__:       Dict        =       flax_model.base_model_prefix

              # use params dict if the model contains batch norm layers and then add batch_stats keys,values to dict
              if "batch_stats" in flax_model.params:
                     lowercase__:       int        =       flax_model.params['params']

                     lowercase__:       Tuple        =       flatten_dict(SCREAMING_SNAKE_CASE_					)
                     random_flax_state_dict.update(flatten_dict(flax_model.params['batch_stats']					)					)
              else:
                     lowercase__:       List[str]        =       flax_model.params
                     lowercase__:       List[Any]        =       flatten_dict(SCREAMING_SNAKE_CASE_					)

              lowercase__:       Optional[int]        =       (model_prefix not in flax_model_params) and (
                  model_prefix in {k.split('.'					)[0] for k in pt_state_dict.keys()}
              )
              lowercase__:       str        =       (model_prefix in flax_model_params) and (
                  model_prefix not in {k.split('.'					)[0] for k in pt_state_dict.keys()}
              )
              # Need to change some parameters name to match Flax names
              for pt_key, pt_tensor in pt_state_dict.items():
                     lowercase__:       List[str]        =       tuple(pt_key.split('.'					)					)

                     # remove base model prefix if necessary
                     lowercase__:       Optional[Any]        =       pt_tuple_key[0] == model_prefix
                     if load_model_with_head_into_base_model and has_base_model_prefix:
                            lowercase__:       List[str]        =       pt_tuple_key[1:]

                     # Correctly rename weight parameters
                     lowercase__      ,						lowercase__:       Any        =       rename_key_and_reshape_tensor(
                         SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)
                     # add model prefix if necessary
                     lowercase__:       Optional[Any]        =       (model_prefix,) + flax_key in random_flax_state_dict
                     if load_base_model_into_model_with_head and require_base_model_prefix:
                            lowercase__:       List[Any]        =       (model_prefix,) + flax_key

                     if flax_key in random_flax_state_dict:
                            if flax_tensor.shape != random_flax_state_dict[flax_key].shape:
                                   raise ValueError(
                                       f'PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape '
                                       f'{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}.'					)

            # add batch stats if the model contains batchnorm layers
                     if "batch_stats" in flax_model.params:
                            if "mean" in flax_key[-1]:
                                   lowercase__:       List[Any]        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)
                                   continue
                            if "var" in flax_key[-1]:
                                   lowercase__:       str        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)
                                   continue
                            # remove num_batches_tracked key
                            if "num_batches_tracked" in flax_key[-1]:
                                   flax_state_dict.pop(SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)
                                   continue

                            # also add unexpected weight so that warning is thrown
                            lowercase__:       Any        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)

                     else:
                            # also add unexpected weight so that warning is thrown
                            lowercase__:       Dict        =       jnp.asarray(SCREAMING_SNAKE_CASE_					)
       return unflatten_dict(SCREAMING_SNAKE_CASE_					)




def        snake_case_					(  snake_case      ,							snake_case					)  ->    Any:
       lowercase__:       Optional[Any]        =       os.path.abspath(SCREAMING_SNAKE_CASE_					)
       logger.info(f'Loading Flax weights from {flax_checkpoint_path}'					)

       # import correct flax class
       lowercase__:       Optional[Any]        =       getattr(SCREAMING_SNAKE_CASE_      ,							'Flax' + model.__class__.__name__					)

       # load flax weight dict
       with open(SCREAMING_SNAKE_CASE_      ,							'rb'					) as state_f:
              try:
                     lowercase__:       List[str]        =       from_bytes(SCREAMING_SNAKE_CASE_      ,							state_f.read()					)
              except UnpicklingError:
                     raise EnvironmentError(f'Unable to convert {flax_checkpoint_path} to Flax deserializable object. '					)

       return load_flax_weights_in_pytorch_model(SCREAMING_SNAKE_CASE_      ,							SCREAMING_SNAKE_CASE_					)




def        snake_case_					(  snake_case      ,							snake_case					)  ->    Dict:






       try:
              import torch  # noqa: F401
       except ImportError:
              logger.error(
                  'Loading a Flax weights in PyTorch, requires both PyTorch and Flax to be installed. Please see'
                  ' https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation'
                  ' instructions.'					)
              raise

       # check if we have bf16 weights
       lowercase__:       Union[str, Any]        =       flatten_dict(jax.tree_util.tree_map(lambda snake_case					: x.dtype == jnp.bfloataa      ,							SCREAMING_SNAKE_CASE_					)					).values()
       if any(SCREAMING_SNAKE_CASE_					):
              # convert all weights to fp32 if the are bf16 since torch.from_numpy can-not handle bf16
              # and bf16 is not fully supported in PT yet.
              logger.warning(
                  'Found ``bfloat16`` weights in Flax model. Casting all ``bfloat16`` weights to ``float32`` '
                  'before loading those in PyTorch model.'					)
              lowercase__:       List[Any]        =       jax.tree_util.tree_map(
                  lambda snake_case					: params.astype(np.floataa					) if params.dtype == jnp.bfloataa else params      ,							SCREAMING_SNAKE_CASE_					)

       lowercase__:       Optional[Any]        =       flatten_dict(SCREAMING_SNAKE_CASE_					)
       lowercase__:       Tuple        =       pt_model.state_dict()

       lowercase__:       Dict        =       (pt_model.base_model_prefix in flax_state) and (
           pt_model.base_model_prefix not in {k.split('.'					)[0] for k in pt_model_dict.keys()}
       )
       lowercase__:       Dict        =       (pt_model.base_model_prefix not in flax_state) and (
           pt_model.base_model_prefix in {k.split('.'					)[0] for k in pt_model_dict.keys()}
       )

       # keep track of unexpected & missing keys
       lowercase__:       Union[str, Any]        =       []
       lowercase__:       Optional[int]        =       set(pt_model_dict.keys()					)

       for flax_key_tuple, flax_tensor in flax_state_dict.items():
              lowercase__:       List[Any]        =       flax_key_tuple[0] == pt_model.base_model_prefix
              lowercase__:       List[Any]        =       '.'.join((pt_model.base_model_prefix,) + flax_key_tuple					) in pt_model_dict

              # adapt flax_key to prepare for loading from/to base model only
              if load_model_with_head_into_base_model and has_base_model_prefix:
                     lowercase__:       Optional[Any]        =       flax_key_tuple[1:]
              elif load_base_model_into_model_with_head and require_base_model_prefix:
                     lowercase__:       Optional[Any]        =       (pt_model.base_model_prefix,) + flax_key_tuple

              # rename flax weights to PyTorch format
              if flax_key_tuple[-1] == "kernel" and flax_tensor.ndim == 4 and ".".join(SCREAMING_SNAKE_CASE_					) not in pt_model_dict:
                     # conv layer
                     lowercase__:       int        =       flax_key_tuple[:-1] + ('weight',)
                     lowercase__:       Dict        =       jnp.transpose(SCREAMING_SNAKE_CASE_      ,							(3, 2, 0, 1)					)
              elif flax_key_tuple[-1] == "kernel" and ".".join(SCREAMING_SNAKE_CASE_					) not in pt_model_dict:
                     # linear layer
                     lowercase__:       List[str]        =       flax_key_tuple[:-1] + ('weight',)
                     lowercase__:       int        =       flax_tensor.T
              elif flax_key_tuple[-1] in ["scale", "embedding"]:
                     lowercase__:       Tuple        =       flax_key_tuple[:-1] + ('weight',)

              # adding batch stats from flax batch norm to pt
              elif "mean" in flax_key_tuple[-1]:
                     lowercase__:       Any        =       flax_key_tuple[:-1] + ('running_mean',)
              elif "var" in flax_key_tuple[-1]:
                     lowercase__:       Dict        =       flax_key_tuple[:-1] + ('running_var',)

              if "batch_stats" in flax_state:
                     lowercase__:       Union[str, Any]        =       '.'.join(flax_key_tuple[1:]					)  # Remove the params/batch_stats header
              else:
                     lowercase__:       Any        =       '.'.join(SCREAMING_SNAKE_CASE_					)

              # We also need to look at `pt_model_dict` and see if there are keys requiring further transformation.
              lowercase__:       List[str]        =       {}
              # New `weight_norm` from https://github.com/huggingface/transformers/pull/24030
              for key in pt_model_dict:
                     lowercase__:       Any        =       key.split('.'					)
                     lowercase__:       Dict        =       None
                     if key_components[-3::2] == ["parametrizations", "original0"]:
                            lowercase__:       Optional[int]        =       key_components[-2] + '_g'
                     elif key_components[-3::2] == ["parametrizations", "original1"]:
                            lowercase__:       Optional[Any]        =       key_components[-2] + '_v'
                     if name is not None:
                            lowercase__:       List[str]        =       key_components[:-3] + [name]
                            lowercase__:       Optional[int]        =       '.'.join(SCREAMING_SNAKE_CASE_					)
                            lowercase__:       List[Any]        =       key

              if flax_key in special_pt_names:
                     lowercase__:       List[Any]        =       special_pt_names[flax_key]

              if flax_key in pt_model_dict:
                     if flax_tensor.shape != pt_model_dict[flax_key].shape:
                            raise ValueError(
                                f'Flax checkpoint seems to be incorrect. Weight {flax_key_tuple} was expected '
                                f'to be of shape {pt_model_dict[flax_key].shape}, but is {flax_tensor.shape}.'					)
                     else:
                            # add weight to pytorch dict
                            lowercase__:       Any        =       np.asarray(SCREAMING_SNAKE_CASE_					) if not isinstance(SCREAMING_SNAKE_CASE_      ,							np.ndarray					) else flax_tensor
                            lowercase__:       List[Any]        =       torch.from_numpy(SCREAMING_SNAKE_CASE_					)
                            # remove from missing keys
                            missing_keys.remove(SCREAMING_SNAKE_CASE_					)
              else:
                     # weight is not expected by PyTorch model
                     unexpected_keys.append(SCREAMING_SNAKE_CASE_					)

       pt_model.load_state_dict(SCREAMING_SNAKE_CASE_					)

       # re-transform missing_keys to list
       lowercase__:       Any        =       list(SCREAMING_SNAKE_CASE_					)

       if len(SCREAMING_SNAKE_CASE_					) > 0:
              logger.warning(
                  'Some weights of the Flax model were not used when initializing the PyTorch model'
                  f' {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing'
                  f' {pt_model.__class__.__name__} from a Flax model trained on another task or with another architecture'
                  ' (e.g. initializing a BertForSequenceClassification model from a FlaxBertForPreTraining model).\n- This'
                  f' IS NOT expected if you are initializing {pt_model.__class__.__name__} from a Flax model that you expect'
                  ' to be exactly identical (e.g. initializing a BertForSequenceClassification model from a'
                  ' FlaxBertForSequenceClassification model).'					)
       else:
              logger.warning(f'All Flax model weights were used when initializing {pt_model.__class__.__name__}.\n'					)
       if len(SCREAMING_SNAKE_CASE_					) > 0:
              logger.warning(
                  f'Some weights of {pt_model.__class__.__name__} were not initialized from the Flax model and are newly'
                  f' initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to'
                  ' use it for predictions and inference.'					)
       else:
              logger.warning(
                  f'All the weights of {pt_model.__class__.__name__} were initialized from the Flax model.\n'
                  'If your task is similar to the task the model of the checkpoint was trained on, '
                  f'you can already use {pt_model.__class__.__name__} for predictions without further training.'					)

       return pt_model




from collections import deque
from math import floor
from random import random
from time import time





class   __a      :
 def __init__(       self			) ->    Dict:




        '''simple docstring'''
        lowercase__:       Dict        =       {}
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__    ,			lowerCAmelCase__    ,			lowerCAmelCase__=1			) ->    Optional[int]:




        '''simple docstring'''
        if self.graph.get(lowerCAmelCase__			):
               if self.graph[u].count([w, v]			) == 0:
                      self.graph[u].append([w, v]			)
        else:
               lowercase__:       int        =       [[w, v]]
        if not self.graph.get(lowerCAmelCase__			):
               lowercase__:       Union[str, Any]        =       []
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Any:




        '''simple docstring'''
        return list(self.graph			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__    ,			lowerCAmelCase__			) ->    Optional[int]:




        '''simple docstring'''
        if self.graph.get(lowerCAmelCase__			):
               for _ in self.graph[u]:
                      if _[1] == v:
                             self.graph[u].remove(lowerCAmelCase__			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2    ,			lowerCAmelCase__=-1			) ->    Union[str, Any]:




        '''simple docstring'''
        if s == d:
               return []
        lowercase__:       Tuple        =       []
        lowercase__:       Tuple        =       []
        if s == -2:
               lowercase__:       Any        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       Dict        =       s

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       Dict        =       s
                      for node in self.graph[s]:
                             if visited.count(node[1]			) < 1:
                                    if node[1] == d:
                                           visited.append(lowerCAmelCase__			)
                                           return visited
                                    else:
                                           stack.append(node[1]			)
                                           visited.append(node[1]			)
                                           lowercase__:       Union[str, Any]        =       node[1]
                                           break

            # check if all the children are visited
               if s == ss:
                      stack.pop()
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       Optional[int]        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       Dict        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return visited
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-1			) ->    List[str]:




        '''simple docstring'''
        if c == -1:
               lowercase__:       int        =       floor(random() * 10_000			) + 10
        for i in range(lowerCAmelCase__			):
               # every vertex has max 100 edges
               for _ in range(floor(random() * 102			) + 1			):
                      lowercase__:       str        =       floor(random() * c			) + 1
                      if n != i:
                             self.add_pair(lowerCAmelCase__    ,			lowerCAmelCase__    ,			1			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2			) ->    Dict:




        '''simple docstring'''
        lowercase__:       int        =       deque()
        lowercase__:       Dict        =       []
        if s == -2:
               lowercase__:       Optional[int]        =       list(self.graph			)[0]
        d.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        while d:
               lowercase__:       str        =       d.popleft()
               if len(self.graph[s]			) != 0:
                      for node in self.graph[s]:
                             if visited.count(node[1]			) < 1:
                                    d.append(node[1]			)
                                    visited.append(node[1]			)
        return visited
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    Dict:




        '''simple docstring'''
        lowercase__:       Tuple        =       0
        for x in self.graph:
               for y in self.graph[x]:
                      if y[1] == u:
                             count += 1
        return count
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    Union[str, Any]:




        '''simple docstring'''
        return len(self.graph[u]			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2			) ->    Optional[Any]:




        '''simple docstring'''
        lowercase__:       Tuple        =       []
        lowercase__:       str        =       []
        if s == -2:
               lowercase__:       Dict        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       List[Any]        =       s
        lowercase__:       Any        =       []

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       List[str]        =       s
                      for node in self.graph[s]:
                             if visited.count(node[1]			) < 1:
                                    stack.append(node[1]			)
                                    visited.append(node[1]			)
                                    lowercase__:       Dict        =       node[1]
                                    break

            # check if all the children are visited
               if s == ss:
                      sorted_nodes.append(stack.pop()			)
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       int        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       Optional[int]        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return sorted_nodes
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Any:




        '''simple docstring'''
        lowercase__:       List[Any]        =       []
        lowercase__:       int        =       []
        lowercase__:       List[str]        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       Dict        =       -2
        lowercase__:       Union[str, Any]        =       []
        lowercase__:       List[str]        =       s
        lowercase__:       Dict        =       False
        lowercase__:       Union[str, Any]        =       set()

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       Any        =       s
                      for node in self.graph[s]:
                             if (
                                 visited.count(node[1]			) > 0
                                 and node[1] != parent
                                 and indirect_parents.count(node[1]			) > 0
                                 and not on_the_way_back
                             ):
                                    lowercase__:       List[Any]        =       len(lowerCAmelCase__			) - 1
                                    while len_stack >= 0:
                                           if stack[len_stack] == node[1]:
                                                  anticipating_nodes.add(node[1]			)
                                                  break
                                           else:
                                                  anticipating_nodes.add(stack[len_stack]			)
                                                  len_stack -= 1
                             if visited.count(node[1]			) < 1:
                                    stack.append(node[1]			)
                                    visited.append(node[1]			)
                                    lowercase__:       Union[str, Any]        =       node[1]
                                    break

            # check if all the children are visited
               if s == ss:
                      stack.pop()
                      lowercase__:       Any        =       True
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       Optional[Any]        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       Union[str, Any]        =       False
                      indirect_parents.append(lowerCAmelCase__			)
                      lowercase__:       int        =       s
                      lowercase__:       str        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return list(lowerCAmelCase__			)
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Optional[Any]:




        '''simple docstring'''
        lowercase__:       Any        =       []
        lowercase__:       int        =       []
        lowercase__:       Dict        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       Optional[int]        =       -2
        lowercase__:       List[Any]        =       []
        lowercase__:       List[str]        =       s
        lowercase__:       List[Any]        =       False
        lowercase__:       str        =       set()

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       Dict        =       s
                      for node in self.graph[s]:
                             if (
                                 visited.count(node[1]			) > 0
                                 and node[1] != parent
                                 and indirect_parents.count(node[1]			) > 0
                                 and not on_the_way_back
                             ):
                                    lowercase__:       Any        =       len(lowerCAmelCase__			) - 1
                                    while len_stack_minus_one >= 0:
                                           if stack[len_stack_minus_one] == node[1]:
                                                  anticipating_nodes.add(node[1]			)
                                                  break
                                           else:
                                                  return True
                             if visited.count(node[1]			) < 1:
                                    stack.append(node[1]			)
                                    visited.append(node[1]			)
                                    lowercase__:       List[Any]        =       node[1]
                                    break

            # check if all the children are visited
               if s == ss:
                      stack.pop()
                      lowercase__:       Optional[Any]        =       True
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       Any        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       Optional[Any]        =       False
                      indirect_parents.append(lowerCAmelCase__			)
                      lowercase__:       Dict        =       s
                      lowercase__:       Dict        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return False
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2    ,			lowerCAmelCase__=-1			) ->    Dict:




        '''simple docstring'''
        lowercase__:       Union[str, Any]        =       time()
        self.dfs(lowerCAmelCase__    ,			lowerCAmelCase__			)
        lowercase__:       Optional[Any]        =       time()
        return end - begin
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2			) ->    List[str]:




        '''simple docstring'''
        lowercase__:       str        =       time()
        self.bfs(lowerCAmelCase__			)
        lowercase__:       List[str]        =       time()
        return end - begin





class   __a      :
 def __init__(       self			) ->    Tuple:




        '''simple docstring'''
        lowercase__:       Dict        =       {}
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__    ,			lowerCAmelCase__    ,			lowerCAmelCase__=1			) ->    List[Any]:




        '''simple docstring'''
        # check if the u exists
        if self.graph.get(lowerCAmelCase__			):
               # if there already is a edge
               if self.graph[u].count([w, v]			) == 0:
                      self.graph[u].append([w, v]			)
        else:
               # if u does not exist
               lowercase__:       str        =       [[w, v]]
        # add the other way
        if self.graph.get(lowerCAmelCase__			):
               # if there already is a edge
               if self.graph[v].count([w, u]			) == 0:
                      self.graph[v].append([w, u]			)
        else:
               # if u does not exist
               lowercase__:       Union[str, Any]        =       [[w, u]]
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__    ,			lowerCAmelCase__			) ->    str:




        '''simple docstring'''
        if self.graph.get(lowerCAmelCase__			):
               for _ in self.graph[u]:
                      if _[1] == v:
                             self.graph[u].remove(lowerCAmelCase__			)
        # the other way round
        if self.graph.get(lowerCAmelCase__			):
               for _ in self.graph[v]:
                      if _[1] == u:
                             self.graph[v].remove(lowerCAmelCase__			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2    ,			lowerCAmelCase__=-1			) ->    List[str]:




        '''simple docstring'''
        if s == d:
               return []
        lowercase__:       str        =       []
        lowercase__:       int        =       []
        if s == -2:
               lowercase__:       Tuple        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       int        =       s

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       int        =       s
                      for node in self.graph[s]:
                             if visited.count(node[1]			) < 1:
                                    if node[1] == d:
                                           visited.append(lowerCAmelCase__			)
                                           return visited
                                    else:
                                           stack.append(node[1]			)
                                           visited.append(node[1]			)
                                           lowercase__:       List[Any]        =       node[1]
                                           break

            # check if all the children are visited
               if s == ss:
                      stack.pop()
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       Union[str, Any]        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       Optional[Any]        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return visited
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-1			) ->    Optional[Any]:




        '''simple docstring'''
        if c == -1:
               lowercase__:       Any        =       floor(random() * 10_000			) + 10
        for i in range(lowerCAmelCase__			):
               # every vertex has max 100 edges
               for _ in range(floor(random() * 102			) + 1			):
                      lowercase__:       Optional[Any]        =       floor(random() * c			) + 1
                      if n != i:
                             self.add_pair(lowerCAmelCase__    ,			lowerCAmelCase__    ,			1			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2			) ->    List[Any]:




        '''simple docstring'''
        lowercase__:       str        =       deque()
        lowercase__:       List[Any]        =       []
        if s == -2:
               lowercase__:       str        =       list(self.graph			)[0]
        d.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        while d:
               lowercase__:       Union[str, Any]        =       d.popleft()
               if len(self.graph[s]			) != 0:
                      for node in self.graph[s]:
                             if visited.count(node[1]			) < 1:
                                    d.append(node[1]			)
                                    visited.append(node[1]			)
        return visited
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__			) ->    List[Any]:




        '''simple docstring'''
        return len(self.graph[u]			)
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    str:




        '''simple docstring'''
        lowercase__:       str        =       []
        lowercase__:       Dict        =       []
        lowercase__:       Optional[int]        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       Dict        =       -2
        lowercase__:       Dict        =       []
        lowercase__:       List[Any]        =       s
        lowercase__:       Union[str, Any]        =       False
        lowercase__:       List[str]        =       set()

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       Optional[int]        =       s
                      for node in self.graph[s]:
                             if (
                                 visited.count(node[1]			) > 0
                                 and node[1] != parent
                                 and indirect_parents.count(node[1]			) > 0
                                 and not on_the_way_back
                             ):
                                    lowercase__:       Any        =       len(lowerCAmelCase__			) - 1
                                    while len_stack >= 0:
                                           if stack[len_stack] == node[1]:
                                                  anticipating_nodes.add(node[1]			)
                                                  break
                                           else:
                                                  anticipating_nodes.add(stack[len_stack]			)
                                                  len_stack -= 1
                             if visited.count(node[1]			) < 1:
                                    stack.append(node[1]			)
                                    visited.append(node[1]			)
                                    lowercase__:       List[str]        =       node[1]
                                    break

            # check if all the children are visited
               if s == ss:
                      stack.pop()
                      lowercase__:       str        =       True
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       Dict        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       int        =       False
                      indirect_parents.append(lowerCAmelCase__			)
                      lowercase__:       Tuple        =       s
                      lowercase__:       List[Any]        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return list(lowerCAmelCase__			)
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    Any:




        '''simple docstring'''
        lowercase__:       Tuple        =       []
        lowercase__:       Optional[int]        =       []
        lowercase__:       Optional[Any]        =       list(self.graph			)[0]
        stack.append(lowerCAmelCase__			)
        visited.append(lowerCAmelCase__			)
        lowercase__:       Tuple        =       -2
        lowercase__:       Any        =       []
        lowercase__:       int        =       s
        lowercase__:       Optional[int]        =       False
        lowercase__:       List[Any]        =       set()

        while True:
               # check if there is any non isolated nodes
               if len(self.graph[s]			) != 0:
                      lowercase__:       Optional[int]        =       s
                      for node in self.graph[s]:
                             if (
                                 visited.count(node[1]			) > 0
                                 and node[1] != parent
                                 and indirect_parents.count(node[1]			) > 0
                                 and not on_the_way_back
                             ):
                                    lowercase__:       Union[str, Any]        =       len(lowerCAmelCase__			) - 1
                                    while len_stack_minus_one >= 0:
                                           if stack[len_stack_minus_one] == node[1]:
                                                  anticipating_nodes.add(node[1]			)
                                                  break
                                           else:
                                                  return True
                             if visited.count(node[1]			) < 1:
                                    stack.append(node[1]			)
                                    visited.append(node[1]			)
                                    lowercase__:       Any        =       node[1]
                                    break

            # check if all the children are visited
               if s == ss:
                      stack.pop()
                      lowercase__:       List[str]        =       True
                      if len(lowerCAmelCase__			) != 0:
                             lowercase__:       List[str]        =       stack[len(lowerCAmelCase__			) - 1]
               else:
                      lowercase__:       Dict        =       False
                      indirect_parents.append(lowerCAmelCase__			)
                      lowercase__:       Optional[Any]        =       s
                      lowercase__:       Optional[int]        =       ss

               # check if se have reached the starting point
               if len(lowerCAmelCase__			) == 0:
                      return False
 def 		SCREAMING_SNAKE_CASE__       (       self			) ->    List[Any]:




        '''simple docstring'''
        return list(self.graph			)
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2    ,			lowerCAmelCase__=-1			) ->    Union[str, Any]:




        '''simple docstring'''
        lowercase__:       Dict        =       time()
        self.dfs(lowerCAmelCase__    ,			lowerCAmelCase__			)
        lowercase__:       List[Any]        =       time()
        return end - begin
 def 		SCREAMING_SNAKE_CASE__       (       self    ,			lowerCAmelCase__=-2			) ->    List[Any]:




        '''simple docstring'''
        lowercase__:       str        =       time()
        self.bfs(lowerCAmelCase__			)
        lowercase__:       List[str]        =       time()
        return end - begin


