



from math import factorial



class 				lowerCAmelCase_		:
       def __init__(			self,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )     ->		Optional[Any]:
          UpperCamelCase    :  List[Any]							=	real
          if isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
             UpperCamelCase    :  List[str]							=	[1] * rank
          else:
             UpperCamelCase    :  List[str]							=	rank
       def __repr__(			self       )     ->		Optional[Any]:
          return (
              F"""{self.real}+"""
              F"""{"+".join(str(SCREAMING_SNAKE_CASE_       )+"E"+str(n+1       )for n,dual in enumerate(self.duals       )       )}"""
          )
       def 					snake_case_       (			self       )     ->		List[Any]:
          UpperCamelCase    :  int							=	self.duals.copy()
          while cur[-1] == 0:
             cur.pop(-1       )
          return Dual(self.real,			SCREAMING_SNAKE_CASE_       )
       def __add__(			self,			SCREAMING_SNAKE_CASE_       )     ->		Union[str, Any]:
          if not isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
             return Dual(self.real + other,			self.duals       )
          UpperCamelCase    :  Dict							=	self.duals.copy()
          UpperCamelCase    :  Any							=	other.duals.copy()
          if len(SCREAMING_SNAKE_CASE_       ) > len(SCREAMING_SNAKE_CASE_       ):
             o_dual.extend([1] * (len(SCREAMING_SNAKE_CASE_       ) - len(SCREAMING_SNAKE_CASE_       ))       )
          elif len(SCREAMING_SNAKE_CASE_       ) < len(SCREAMING_SNAKE_CASE_       ):
             s_dual.extend([1] * (len(SCREAMING_SNAKE_CASE_       ) - len(SCREAMING_SNAKE_CASE_       ))       )
          UpperCamelCase    :  List[Any]							=	[]
          for i in range(len(SCREAMING_SNAKE_CASE_       )       ):
             new_duals.append(s_dual[i] + o_dual[i]       )
          return Dual(self.real + other.real,			SCREAMING_SNAKE_CASE_       )

       UpperCAmelCase__				:					str        =  __add__
       def __sub__(			self,			SCREAMING_SNAKE_CASE_       )     ->		Union[str, Any]:
          return self + other * -1
       def __mul__(			self,			SCREAMING_SNAKE_CASE_       )     ->		Any:
          if not isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
             UpperCamelCase    :  Union[str, Any]							=	[]
             for i in self.duals:
                new_duals.append(i * other       )
             return Dual(self.real * other,			SCREAMING_SNAKE_CASE_       )
          UpperCamelCase    :  str							=	[0] * (len(self.duals       ) + len(other.duals       ) + 1)
          for i, item in enumerate(self.duals       ):
             for j, jtem in enumerate(other.duals       ):
                new_duals[i + j + 1] += item * jtem
          for k in range(len(self.duals       )       ):
             new_duals[k] += self.duals[k] * other.real
          for index in range(len(other.duals       )       ):
             new_duals[index] += other.duals[index] * self.real
          return Dual(self.real * other.real,			SCREAMING_SNAKE_CASE_       )

       UpperCAmelCase__				:					List[Any]        =  __mul__
       def __truediv__(			self,			SCREAMING_SNAKE_CASE_       )     ->		List[str]:
          if not isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
             UpperCamelCase    :  Dict							=	[]
             for i in self.duals:
                new_duals.append(i / other       )
             return Dual(self.real / other,			SCREAMING_SNAKE_CASE_       )
          raise ValueError
       def __floordiv__(			self,			SCREAMING_SNAKE_CASE_       )     ->		List[str]:
          if not isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
             UpperCamelCase    :  Union[str, Any]							=	[]
             for i in self.duals:
                new_duals.append(i // other       )
             return Dual(self.real // other,			SCREAMING_SNAKE_CASE_       )
          raise ValueError






       def __pow__(			self,			SCREAMING_SNAKE_CASE_       )     ->		Optional[Any]:
          if n < 0 or isinstance(SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       ):
             raise ValueError('power must be a positive integer'       )
          if n == 0:
             return 1
          if n == 1:
             return self
          UpperCamelCase    :  int							=	self
          for _ in range(n - 1       ):
             x *= self
          return x






def 		UpperCamelCase	(   snake_case__       :    List[str]       ,     snake_case__       :    str       ,     snake_case__       :    str	)	->     List[str]:
   if not callable(snake_case__	):
      raise ValueError('differentiate() requires a function as input for func'	)
   if not isinstance(snake_case__       ,     (float, int)	):
      raise ValueError('differentiate() requires a float as input for position'	)
   if not isinstance(snake_case__       ,     snake_case__	):
      raise ValueError('differentiate() requires an int as input for order'	)
   UpperCamelCase    :  List[Any]							=	Dual(snake_case__       ,     1	)
   UpperCamelCase    :  Optional[int]							=	func(snake_case__	)
   if order == 0:
      return result.real
   return result.duals[order - 1] * factorial(snake_case__	)


if __name__ == "__main__":
    import doctest

    doctest.testmod()
    def 		UpperCamelCase	(   snake_case__       :    Optional[int]	)	->     Optional[int]:
       return y**2 * y**4


    print(differentiate(f, 9, 2))








from __future__ import annotations

__UpperCAmelCase          =       {
    '''A''': ['''B''', '''C''', '''E'''],
    '''B''': ['''A''', '''D''', '''E'''],
    '''C''': ['''A''', '''F''', '''G'''],
    '''D''': ['''B'''],
    '''E''': ['''A''', '''B''', '''D'''],
    '''F''': ['''C'''],
    '''G''': ['''C'''],
}



class 				lowerCAmelCase_		:
       def __init__(			self,			SCREAMING_SNAKE_CASE_,			SCREAMING_SNAKE_CASE_       )     ->		None:
          UpperCamelCase    :  Union[str, Any]							=	graph
          # mapping node to its parent in resulting breadth first tree
          UpperCamelCase    :  dict[str, str | None]							=	{}
          UpperCamelCase    :  Union[str, Any]							=	source_vertex
       def 					snake_case_       (			self       )     ->		None:
          UpperCamelCase    :  str							=	{self.source_vertex}
          UpperCamelCase    :  str							=	None
          UpperCamelCase    :  int							=	[self.source_vertex]  # first in first out queue

          while queue:
             UpperCamelCase    :  Dict							=	queue.pop(0       )
             for adjacent_vertex in self.graph[vertex]:
                if adjacent_vertex not in visited:
                   visited.add(SCREAMING_SNAKE_CASE_       )
                   UpperCamelCase    :  Tuple							=	vertex
                   queue.append(SCREAMING_SNAKE_CASE_       )






       def 					snake_case_       (			self,			SCREAMING_SNAKE_CASE_       )     ->		str:
          if target_vertex == self.source_vertex:
             return self.source_vertex

          UpperCamelCase    :  Optional[Any]							=	self.parent.get(SCREAMING_SNAKE_CASE_       )
          if target_vertex_parent is None:
             UpperCamelCase    :  Union[str, Any]							=	(
                 F"""No path from vertex: {self.source_vertex} to vertex: {target_vertex}"""
             )
             raise ValueError(SCREAMING_SNAKE_CASE_       )

          return self.shortest_path(SCREAMING_SNAKE_CASE_       ) + F"""->{target_vertex}"""


if __name__ == "__main__":
    __UpperCAmelCase          =       Graph(graph, '''G''')
    g.breath_first_search()
    print(g.shortest_path('''D'''))
    print(g.shortest_path('''G'''))
    print(g.shortest_path('''Foo'''))



