# Path: py_algorithms/graph/adt/vertex.py
# class Vertex:
#     __slots__ = '_element'
# 
#     def __init__(self, element: Any):
#         self._element = element
# 
#     def element(self) -> Any:
#         return self._element
# 
#     def __hash__(self) -> int:
#         return hash(id(self))
# 
#     def __repr__(self):
#         return "#<{}({})>" \
#             .format(self.__class__.__name__, self.element())


from typing import Any
from typing import Tuple
from typing import Union
from .vertex import Vertex



class Edge:
    __slots__ = '_origin', '_destination', '_element'

    def __init__(self, origin: Vertex, destination: Vertex, element: Any):
        self._element = element
        self._destination = destination
        self._origin = origin

    def endpoints(self) -> Tuple[Any, Any]:
        return self._origin, self._destination


# Path: py_algorithms/graph/adt/vertex.py
# class Vertex:
#     __slots__ = '_element'
# 
#     def __init__(self, element: Any):
#         self._element = element
# 
#     def element(self) -> Any:
#         return self._element
# 
#     def __hash__(self) -> int:
#         return hash(id(self))
# 
#     def __repr__(self):
#         return "#<{}({})>" \
#             .format(self.__class__.__name__, self.element())


# Path: py_algorithms/graph/adt/edge.py
from typing import Any
from typing import Tuple
from typing import Union
from .vertex import Vertex




class Edge:
    __slots__ = '_origin', '_destination', '_element'

    def __init__(self, origin: Vertex, destination: Vertex, element: Any):
        self._element = element
        self._destination = destination
        self._origin = origin

    def endpoints(self) -> Tuple[Any, Any]:
        return self._origin, self._destination


    def opposite(self, v) -> Union[None, Vertex]: