




class 							__SCREAMING_SNAKE_CASE				:

					def __init__(							self					,			__lowercase   ):







						'''simple docstring'''




						lowerCamelCase_				:						List[str]				  =				val
						# Number of nodes in left subtree
						lowerCamelCase_				:						Tuple				  =				0
						lowerCamelCase_				:						Union[str, Any]				  =				None
						lowerCamelCase_				:						Any				  =				None
						lowerCamelCase_				:						Optional[Any]				  =				None





					def       lowercase_				(							self					,			__lowercase   ):







						'''simple docstring'''




						assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"

						if self.val < other.val:
							lowerCamelCase_				:						List[str]				  =				self.right
							lowerCamelCase_				:						str				  =				None
							if self.right:
								lowerCamelCase_				:						Dict				  =				other
							lowerCamelCase_				:						Tuple				  =				other
							lowerCamelCase_				:						Any				  =				self.left_tree_size * 2 + 1
							return self
						else:
							lowerCamelCase_				:						int				  =				other.right
							lowerCamelCase_				:						Tuple				  =				None
							if other.right:
								lowerCamelCase_				:						Union[str, Any]				  =				self
							lowerCamelCase_				:						Optional[int]				  =				self
							lowerCamelCase_				:						List[str]				  =				other.left_tree_size * 2 + 1
							return other


class 							__SCREAMING_SNAKE_CASE				:

					def __init__(							self					,			__lowercase=None					,			__lowercase=None					,			__lowercase=0   ):







						'''simple docstring'''




						lowerCamelCase_				:						Tuple				  =				heap_size
						lowerCamelCase_				:						Optional[Any]				  =				bottom_root
						lowerCamelCase_				:						List[str]				  =				min_node

					def       lowercase_				(							self					,			__lowercase   ):







						'''simple docstring'''




						if other.size == 0:
							return None
						if self.size == 0:
							lowerCamelCase_				:						int				  =				other.size
							lowerCamelCase_				:						Tuple				  =				other.bottom_root
							lowerCamelCase_				:						List[str]				  =				other.min_node
							return None
						# Update size
						lowerCamelCase_				:						Tuple				  =				self.size + other.size

						# Update min.node
						if self.min_node.val > other.min_node.val:
							lowerCamelCase_				:						str				  =				other.min_node
						# Merge

						# Order roots by left_subtree_size
						lowerCamelCase_				:						Tuple				  =				[]
						lowerCamelCase_  ,     lowerCamelCase_				:						str				  =				self.bottom_root, other.bottom_root
						while i or j:
							if i and ((not j) or i.left_tree_size < j.left_tree_size):
								combined_roots_list.append((i, True)   )
								lowerCamelCase_				:						Tuple				  =				i.parent
							else:
								combined_roots_list.append((j, False)   )
								lowerCamelCase_				:						List[Any]				  =				j.parent
        # Insert links between them
						for i in range(len(__lowercase   ) - 1   ):
							if combined_roots_list[i][1] != combined_roots_list[i + 1][1]:
								lowerCamelCase_				:						Optional[int]				  =				combined_roots_list[i + 1][0]
								lowerCamelCase_				:						str				  =				combined_roots_list[i][0]
        # Consecutively merge roots with same left_tree_size
						lowerCamelCase_				:						Union[str, Any]				  =				combined_roots_list[0][0]
						while i.parent:
							if (
							    (i.left_tree_size == i.parent.left_tree_size) and (not i.parent.parent)
							) or (
							    i.left_tree_size == i.parent.left_tree_size
							    and i.left_tree_size != i.parent.parent.left_tree_size
							):
								# Neighbouring Nodes
								lowerCamelCase_				:						Any				  =				i.left
								lowerCamelCase_				:						Tuple				  =				i.parent.parent

								# Merging trees
								lowerCamelCase_				:						int				  =				i.merge_trees(i.parent   )

								# Updating links
								lowerCamelCase_				:						List[Any]				  =				previous_node
								lowerCamelCase_				:						Union[str, Any]				  =				next_node
								if previous_node:
									lowerCamelCase_				:						List[str]				  =				i
								if next_node:
									lowerCamelCase_				:						Tuple				  =				i
							else:
								lowerCamelCase_				:						Dict				  =				i.parent
        # Updating self.bottom_root
						while i.left:
							lowerCamelCase_				:						List[Any]				  =				i.left
						lowerCamelCase_				:						Optional[Any]				  =				i

						# Update other
						lowerCamelCase_				:						Tuple				  =				self.size
						lowerCamelCase_				:						Dict				  =				self.bottom_root
						lowerCamelCase_				:						Union[str, Any]				  =				self.min_node

						# Return the merged heap
						return self

					def       lowercase_				(							self					,			__lowercase   ):







						'''simple docstring'''




						if self.size == 0:
							lowerCamelCase_				:						Optional[Any]				  =				Node(__lowercase   )
							lowerCamelCase_				:						str				  =				1
							lowerCamelCase_				:						Union[str, Any]				  =				self.bottom_root
						else:
							# Create new node
							lowerCamelCase_				:						Optional[int]				  =				Node(__lowercase   )

							# Update size
							self.size += 1

							# update min_node
							if val < self.min_node.val:
								lowerCamelCase_				:						str				  =				new_node
							# Put new_node as a bottom_root in heap
							lowerCamelCase_				:						Tuple				  =				new_node
							lowerCamelCase_				:						Dict				  =				self.bottom_root
							lowerCamelCase_				:						int				  =				new_node

							# Consecutively merge roots with same left_tree_size
							while (
							    self.bottom_root.parent
							    and self.bottom_root.left_tree_size
							    == self.bottom_root.parent.left_tree_size
							):
								# Next node
								lowerCamelCase_				:						List[Any]				  =				self.bottom_root.parent.parent

								# Merge
								lowerCamelCase_				:						List[Any]				  =				self.bottom_root.merge_trees(self.bottom_root.parent   )

								# Update Links
								lowerCamelCase_				:						List[Any]				  =				next_node
								lowerCamelCase_				:						Union[str, Any]				  =				None
								if next_node:
									lowerCamelCase_				:						List[Any]				  =				self.bottom_root

					def       lowercase_				(							self   ):







						'''simple docstring'''




						return self.min_node.val

					def       lowercase_				(							self   ):







						'''simple docstring'''




						return self.size == 0

					def       lowercase_				(							self   ):







						'''simple docstring'''




						lowerCamelCase_				:						Any				  =				self.min_node.val

						# Last element in heap corner case
						if self.size == 1:
							# Update size
							lowerCamelCase_				:						Union[str, Any]				  =				0

							# Update bottom root
							lowerCamelCase_				:						Any				  =				None

							# Update min_node
							lowerCamelCase_				:						int				  =				None

							return min_value
						# No right subtree corner case
						# The structure of the tree implies that this should be the bottom root
						# and there is at least one other root
						if self.min_node.right is None:
							# Update size
							self.size -= 1

							# Update bottom root
							lowerCamelCase_				:						int				  =				self.bottom_root.parent
							lowerCamelCase_				:						List[str]				  =				None

							# Update min_node
							lowerCamelCase_				:						Any				  =				self.bottom_root
							lowerCamelCase_				:						Optional[Any]				  =				self.bottom_root.parent
							while i:
								if i.val < self.min_node.val:
									lowerCamelCase_				:						Any				  =				i
								lowerCamelCase_				:						Optional[int]				  =				i.parent
							return min_value
						# General case
						# Find the BinomialHeap of the right subtree of min_node
						lowerCamelCase_				:						Dict				  =				self.min_node.right
						lowerCamelCase_				:						List[Any]				  =				None
						lowerCamelCase_				:						int				  =				bottom_of_new
						lowerCamelCase_				:						Any				  =				1

						# Size, min_node and bottom_root
						while bottom_of_new.left:
							lowerCamelCase_				:						Optional[Any]				  =				size_of_new * 2 + 1
							lowerCamelCase_				:						str				  =				bottom_of_new.left
							if bottom_of_new.val < min_of_new.val:
								lowerCamelCase_				:						Tuple				  =				bottom_of_new
        # Corner case of single root on top left path
						if (not self.min_node.left) and (not self.min_node.parent):
							lowerCamelCase_				:						Union[str, Any]				  =				size_of_new
							lowerCamelCase_				:						Any				  =				bottom_of_new
							lowerCamelCase_				:						List[str]				  =				min_of_new
							# print("Single root, multiple nodes case")
							return min_value
						# Remaining cases
						# Construct heap of right subtree
						lowerCamelCase_				:						Any				  =				BinomialHeap(
						    bottom_root=__lowercase					,			min_node=__lowercase					,			heap_size=__lowercase   )

						# Update size
						lowerCamelCase_				:						Tuple				  =				self.size - 1 - size_of_new

						# Neighbour nodes
						lowerCamelCase_				:						Dict				  =				self.min_node.left
						lowerCamelCase_				:						Optional[Any]				  =				self.min_node.parent

						# Initialize new bottom_root and min_node
						lowerCamelCase_				:						int				  =				previous_node or next_node
						lowerCamelCase_				:						int				  =				next_node

						# Update links of previous_node and search below for new min_node and
						# bottom_root
						if previous_node:
							lowerCamelCase_				:						Optional[Any]				  =				next_node

							# Update bottom_root and search for min_node below
							lowerCamelCase_				:						int				  =				previous_node
							lowerCamelCase_				:						Dict				  =				previous_node
							while self.bottom_root.left:
								lowerCamelCase_				:						int				  =				self.bottom_root.left
								if self.bottom_root.val < self.min_node.val:
									lowerCamelCase_				:						Any				  =				self.bottom_root
						if next_node:
							lowerCamelCase_				:						List[str]				  =				previous_node

							# Search for new min_node above min_node
							lowerCamelCase_				:						Union[str, Any]				  =				next_node
							while i:
								if i.val < self.min_node.val:
									lowerCamelCase_				:						Union[str, Any]				  =				i
								lowerCamelCase_				:						Dict				  =				i.parent
        # Merge heaps
						self.merge_heaps(__lowercase   )

						return min_value

					def       lowercase_				(							self   ):







						'''simple docstring'''




						lowerCamelCase_				:						Optional[Any]				  =				self.bottom_root
						while top_root.parent:
							lowerCamelCase_				:						str				  =				top_root.parent
						# preorder
						lowerCamelCase_				:						int				  =				[]
						self.__traversal(__lowercase					,			__lowercase   )
						return heap_pre_order

					def       lowercase_				(							self					,			__lowercase					,			__lowercase					,			__lowercase=0   ):







						'''simple docstring'''




						if curr_node:
							preorder.append((curr_node.val, level)   )
							self.__traversal(curr_node.left					,			__lowercase					,			level + 1   )
							self.__traversal(curr_node.right					,			__lowercase					,			level + 1   )
						else:
							preorder.append(('#', level)   )





					def __str__(							self   ):







						'''simple docstring'''




						if self.is_empty():
							return ""
						lowerCamelCase_				:						int				  =				self.pre_order()

						return "\n".join(('-' * level + str(__lowercase   )) for value, level in preorder_heap   )


# Unit Tests
if __name__ == "__main__":
							import doctest

							doctest.testmod()






'''simple docstring'''
import os
def 							snake_case_    (  ):



    """simple docstring"""




    __lowercase     							=		os.path.dirname(os.path.realpath(a__     )     )
    __lowercase     							=		os.path.join(a__       ,"""triangle.txt"""     )

    with open(a__     ) as f:
        __lowercase     							=		f.readlines()

    __lowercase     							=		[[int(a__     ) for y in x.rstrip("""\r\n"""     ).split(""" """     )] for x in triangle]

    for i in range(1       ,len(a__     )     ):
        for j in range(len(a[i]     )     ):
            __lowercase     							=		a[i - 1][j] if j != len(a[i - 1]     ) else 0
            __lowercase     							=		a[i - 1][j - 1] if j > 0 else 0
            a[i][j] += max(a__       ,a__     )
    return max(a[-1]     )


if __name__ == "__main__":
  print(solution())




