
"""simple docstring"""





from collections.abc import Sequence
from queue import Queue





class 				a :





       """simple docstring"""







       def __init__(			self							,	snake_case_							,	snake_case_							,	snake_case_							,	snake_case_=None							,	snake_case_=None			)    ->				Tuple:
          _UpperCAmelCase         =      start
          _UpperCAmelCase         =      end
          _UpperCAmelCase         =      val
          _UpperCAmelCase         =      (start + end) // 2
          _UpperCAmelCase         =      left
          _UpperCAmelCase         =      right






       def __repr__(			self			)    ->				Union[str, Any]:
          return F"""SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})"""





class 				a :





       """simple docstring"""







       def __init__(			self							,	snake_case_							,	snake_case_			)    ->				Any:
          _UpperCAmelCase         =      collection
          _UpperCAmelCase         =      function
          if self.collection:
             _UpperCAmelCase         =      self._build_tree(0							,	len(_SCREAMING_SNAKE_CASE			) - 1			)






       def 				__A						(			self							,	snake_case_							,	snake_case_			)    ->				Any:
          self._update_tree(self.root							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)






       def 				__A						(			self							,	snake_case_							,	snake_case_			)    ->				Any:
          return self._query_range(self.root							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)






       def 				__A						(			self							,	snake_case_							,	snake_case_			)    ->				List[Any]:
          if start == end:
             return SegmentTreeNode(_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE							,	self.collection[start]			)
          _UpperCAmelCase         =      (start + end) // 2
          _UpperCAmelCase         =      self._build_tree(_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)
          _UpperCAmelCase         =      self._build_tree(mid + 1							,	_SCREAMING_SNAKE_CASE			)
          return SegmentTreeNode(_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE							,	self.fn(left.val							,	right.val			)							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)






       def 				__A						(			self							,	snake_case_							,	snake_case_							,	snake_case_			)    ->				Dict:
          if node.start == i and node.end == i:
             _UpperCAmelCase         =      val
             return
          if i <= node.mid:
             self._update_tree(node.left							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)
          else:
             self._update_tree(node.right							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)
          _UpperCAmelCase         =      self.fn(node.left.val							,	node.right.val			)






       def 				__A						(			self							,	snake_case_							,	snake_case_							,	snake_case_			)    ->				Tuple:
          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							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)
             else:
                # range in left child tree and right child tree
                return self.fn(
                    self._query_range(node.left							,	_SCREAMING_SNAKE_CASE							,	node.mid			)							,	self._query_range(node.right							,	node.mid + 1							,	_SCREAMING_SNAKE_CASE			)							,	)
          else:
             # range in right child tree
             return self._query_range(node.right							,	_SCREAMING_SNAKE_CASE							,	_SCREAMING_SNAKE_CASE			)






       def 				__A						(			self			)    ->				int:
          if self.root is not None:
             _UpperCAmelCase         =      Queue()
             queue.put(self.root			)
             while not queue.empty():
                _UpperCAmelCase         =      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)
  SCREAMING_SNAKE_CASE_												= 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()







def lowerCamelCase__  (     _lowercase					,		_lowercase ):

     '''simple docstring'''


     while a != 0:
          UpperCAmelCase_,       UpperCAmelCase_     :				Optional[int]  =     b % a, a
     return b







def lowerCamelCase__  (     _lowercase					,		_lowercase ):

     '''simple docstring'''


     if gcd(_lowercase					,		_lowercase ) != 1:
          UpperCAmelCase_     :				int  =     f'''mod inverse of {a!r} and {m!r} does not exist'''
          raise ValueError(_lowercase )
     UpperCAmelCase_,       UpperCAmelCase_,       UpperCAmelCase_     :				Union[str, Any]  =     1, 0, a
     UpperCAmelCase_,       UpperCAmelCase_,       UpperCAmelCase_     :				Dict  =     0, 1, m
     while va != 0:
          UpperCAmelCase_     :				List[Any]  =     ua // va
          UpperCAmelCase_,       UpperCAmelCase_,       UpperCAmelCase_,       UpperCAmelCase_,       UpperCAmelCase_,       UpperCAmelCase_     :				Any  =     (ua - q * va), (ua - q * va), (ua - q * va), va, va, va
     return ua % m