from __future__ import annotations

__snake_case						=			list[tuple[int, int]]

__snake_case						=			[
    [0, 0, 0, 0, 0, 0, 0],
    [0, 1, 0, 0, 0, 0, 0],  # 0 are free path whereas 1's are obstacles
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 1, 0, 0, 0, 0],
    [1, 0, 1, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0],
]

__snake_case						=			([-1, 0], [0, -1], [1, 0], [0, 1])  # up, left, down, right







class 	__snake_case      :
 def __init__(     self						,      snake_case__						,      snake_case__						,      snake_case__						,      snake_case__						,      snake_case__						,      snake_case__						,      )		->							Optional[Any]:
       '''simple docstring'''





       UpperCAmelCase			:       str			     =pos_x
       UpperCAmelCase			:       Any			     =pos_y
       UpperCAmelCase			:       str			     =(pos_y, pos_x)
       UpperCAmelCase			:       Tuple			     =goal_x
       UpperCAmelCase			:       Any			     =goal_y
       UpperCAmelCase			:       str			     =g_cost
       UpperCAmelCase			:       str			     =parent
       UpperCAmelCase			:       Dict			     =self.calculate_heuristic()
 def 		UpperCAmelCase__				(     self  )		->							Optional[int]:
       '''simple docstring'''





       UpperCAmelCase			:       Any			     =abs(self.pos_x - self.goal_x  )
       UpperCAmelCase			:       Optional[Any]			     =abs(self.pos_y - self.goal_y  )
       return dx + dy






 def __lt__(     self						,      snake_case__  )		->							Optional[int]:
       '''simple docstring'''





       return self.f_cost < other.f_cost







class 	__snake_case      :
 def __init__(     self						,      snake_case__						,      snake_case__  )		->							List[str]:
       '''simple docstring'''





       UpperCAmelCase			:       List[str]			     =Node(start[1]						,      start[0]						,      goal[1]						,      goal[0]						,      0						,      _A  )
       UpperCAmelCase			:       List[str]			     =Node(goal[1]						,      goal[0]						,      goal[1]						,      goal[0]						,      9_9999						,      _A  )

       UpperCAmelCase			:       Optional[int]			     =[self.start]
       UpperCAmelCase			:       list[Node]			     =[]

       UpperCAmelCase			:       Dict			     =False
 def 		UpperCAmelCase__				(     self  )		->							int:
       '''simple docstring'''





       while self.open_nodes:
             # Open Nodes are sorted using __lt__
             self.open_nodes.sort()
             UpperCAmelCase			:       List[str]			     =self.open_nodes.pop(0  )

             if current_node.pos == self.target.pos:
                   UpperCAmelCase			:       Optional[int]			     =True
                   return self.retrace_path(_A  )

             self.closed_nodes.append(_A  )
             UpperCAmelCase			:       List[str]			     =self.get_successors(_A  )

             for child_node in successors:
                   if child_node in self.closed_nodes:
                         continue

                   if child_node not in self.open_nodes:
                         self.open_nodes.append(_A  )
                   else:
                         # retrieve the best current path
                         UpperCAmelCase			:       Tuple			     =self.open_nodes.pop(self.open_nodes.index(_A  )  )

                         if child_node.g_cost < better_node.g_cost:
                               self.open_nodes.append(_A  )
                         else:
                               self.open_nodes.append(_A  )

       if not self.reached:
             return [self.start.pos]
       return None
 def 		UpperCAmelCase__				(     self						,      snake_case__  )		->							str:
       '''simple docstring'''





       UpperCAmelCase			:       List[str]			     =[]
       for action in delta:
             UpperCAmelCase			:       Dict			     =parent.pos_x + action[1]
             UpperCAmelCase			:       Dict			     =parent.pos_y + action[0]

             if not (0 <= pos_x <= len(grid[0]  ) - 1 and 0 <= pos_y <= len(_A  ) - 1):
                   continue

             if grid[pos_y][pos_x] != 0:
                   continue

             successors.append(
                 Node(
                     _A						,      _A						,      self.target.pos_y						,      self.target.pos_x						,      parent.g_cost + 1						,      _A						,      )  )
       return successors






 def 		UpperCAmelCase__				(     self						,      snake_case__  )		->							List[Any]:
       '''simple docstring'''





       UpperCAmelCase			:       Union[str, Any]			     =node
       UpperCAmelCase			:       Optional[int]			     =[]
       while current_node is not None:
             path.append((current_node.pos_y, current_node.pos_x)  )
             UpperCAmelCase			:       Optional[Any]			     =current_node.parent
       path.reverse()
       return path


if __name__ == "__main__":
     __snake_case						=			(0, 0)
     __snake_case						=			(len(grid) - 1, len(grid[0]) - 1)
     for elem in grid:
          print(elem)

     print('''------''')

     __snake_case						=			GreedyBestFirst(init, goal)
     __snake_case						=			greedy_bf.search()
     if path:
          for pos_x, pos_y in path:
               __snake_case						=			2

          for elem in grid:
               print(elem)

from collections.abc import Sequence
from queue import Queue






class 		a__						:

					def __init__(    self      :       int,_A      :       List[Any],_A      :       Optional[Any],_A      :       Optional[int],_A      :       int=None,_A      :       List[str]=None    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    start
							SCREAMING_SNAKE_CASE_  :		List[str]				      =    end
							SCREAMING_SNAKE_CASE_  :		Tuple				      =    val
							SCREAMING_SNAKE_CASE_  :		List[str]				      =    (start + end) // 2
							SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    left
							SCREAMING_SNAKE_CASE_  :		str				      =    right






					def __repr__(    self      :       Tuple    ):







							"""simple docstring"""






							return F'SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})'







class 		a__						:

					def __init__(    self      :       Any,_A      :       Sequence,_A      :       str    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    collection
							SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    function
							if self.collection:
									SCREAMING_SNAKE_CASE_  :		List[str]				      =    self._build_tree(0,len(_A    ) - 1    )

					def 				__UpperCamelCase   (    self      :       int,_A      :       Any,_A      :       List[Any]    ):







							"""simple docstring"""






							self._update_tree(self.root,_A,_A    )

					def 				__UpperCamelCase   (    self      :       str,_A      :       Any,_A      :       List[Any]    ):







							"""simple docstring"""






							return self._query_range(self.root,_A,_A    )

					def 				__UpperCamelCase   (    self      :       Any,_A      :       Optional[int],_A      :       int    ):







							"""simple docstring"""






							if start == end:
									return SegmentTreeNode(_A,_A,self.collection[start]    )
							SCREAMING_SNAKE_CASE_  :		List[Any]				      =    (start + end) // 2
							SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    self._build_tree(_A,_A    )
							SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    self._build_tree(mid + 1,_A    )
							return SegmentTreeNode(_A,_A,self.fn(left.val,right.val    ),_A,_A    )

					def 				__UpperCamelCase   (    self      :       int,_A      :       int,_A      :       Tuple,_A      :       Dict    ):







							"""simple docstring"""






							if node.start == i and node.end == i:
									SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    val
									return
							if i <= node.mid:
									self._update_tree(node.left,_A,_A    )
							else:
									self._update_tree(node.right,_A,_A    )
							SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    self.fn(node.left.val,node.right.val    )

					def 				__UpperCamelCase   (    self      :       str,_A      :       List[str],_A      :       Optional[int],_A      :       Optional[Any]    ):







							"""simple docstring"""






							if node.start == i and node.end == j:
									return node.val

							if i <= node.mid:
									if j <= node.mid:
											# range in left child tree
											return self._query_range(node.left,_A,_A    )
									else:
											# range in left child tree and right child tree
											return self.fn(
											    self._query_range(node.left,_A,node.mid    ),self._query_range(node.right,node.mid + 1,_A    ),)
							else:
									# range in right child tree
									return self._query_range(node.right,_A,_A    )






					def 				__UpperCamelCase   (    self      :       Optional[Any]    ):







							"""simple docstring"""






							if self.root is not None:
									SCREAMING_SNAKE_CASE_  :		int				      =    Queue()
									queue.put(self.root    )
									while not queue.empty():
											SCREAMING_SNAKE_CASE_  :		Tuple				      =    queue.get()
											yield node

											if node.left is not None:
													queue.put(node.left    )

											if node.right is not None:
													queue.put(node.right    )


if __name__ == "__main__":
		import operator

		for fn in [operator.add, max, min]:
				print('''*''' * 50)
				__lowerCamelCase					:	int       =  SegmentTree([2, 1, 5, 3, 4], fn)
				for node in arr.traverse():
						print(node)
				print()

				arr.update(1, 5)
				for node in arr.traverse():
						print(node)
				print()

				print(arr.query_range(3, 4))  # 7
				print(arr.query_range(2, 2))  # 5
				print(arr.query_range(1, 3))  # 13
				print()
