






from __future__ import annotations

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



@dataclass
class 							_UpperCamelCase			:
      snake_case_  =							42
      snake_case_  =							42



class 							_UpperCamelCase			:


      def __init__(	self					,						__UpperCamelCase	)->	Optional[int]:
           __lowerCAmelCase								=					[[] for _ in range(__UpperCamelCase	)]
           __lowerCAmelCase								=					size


      def __getitem__(	self					,						__UpperCamelCase	)->	Iterator[Edge]:
           return iter(self._graph[vertex]	)


      @property
      def  __UpperCAmelCase		(	self	)->	Optional[Any]:
           return self._size


      def  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase					,						__UpperCamelCase	)->	List[Any]:
           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  __UpperCAmelCase		(	self					,						__UpperCamelCase					,						__UpperCamelCase	)->	int | None:
           __lowerCAmelCase								=					deque([start_vertex]	)
           __lowerCAmelCase								=					[None] * self.size
           __lowerCAmelCase								=					0

           while queue:
                __lowerCAmelCase								=					queue.popleft()
                __lowerCAmelCase								=					distances[current_vertex]
                if current_distance is None:
                     continue

                for edge in self[current_vertex]:
                     __lowerCAmelCase								=					current_distance + edge.weight
                     __lowerCAmelCase								=					distances[edge.destination_vertex]
                     if (
                         isinstance(__UpperCamelCase					,						__UpperCamelCase	)
                         and new_distance >= dest_vertex_distance
                     ):
                          continue
                     __lowerCAmelCase								=					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()














import random



class 							_UpperCamelCase			:


      @staticmethod
      def  __UpperCAmelCase		(	__UpperCamelCase	)->	tuple[list[int], list[int]]:
           __lowerCAmelCase								=					[ord(__UpperCamelCase	) for i in text]
           __lowerCAmelCase								=					[]
           __lowerCAmelCase								=					[]
           for i in plain:
                __lowerCAmelCase								=					random.randint(1					,						3_0_0	)
                __lowerCAmelCase								=					(i + k) * k
                cipher.append(__UpperCamelCase	)
                key.append(__UpperCamelCase	)
           return cipher, key


      @staticmethod
      def  __UpperCAmelCase		(	__UpperCamelCase					,						__UpperCamelCase	)->	str:
           __lowerCAmelCase								=					[]
           for i in range(len(__UpperCamelCase	)	):
                __lowerCAmelCase								=					int((cipher[i] - (key[i]) ** 2) / key[i]	)
                plain.append(chr(__UpperCamelCase	)	)
           return "".join(__UpperCamelCase	)


if __name__ == "__main__":
 lowerCamelCase      ,					lowerCamelCase			:					List[Any]         =	Onepad().encrypt('''Hello''')
 print(c, k)
 print(Onepad().decrypt(c, k))






