from typing import List


def max_triangle_path(triangle: List[List[int]]) -> int:
    """Alters triangle and returns the maximum path sum from top to bottom.

    A path is valid iff it consists of a number from each row of the triangle
    such that each number is adjacent to those in the rows above and below it.
    """

    num_rows = len(triangle)

    # add maximum adjacent values from row above to each row
    for i in range(1, num_rows):
        for j in range(i + 1):
            if j != 0 and j != i:
                # two adjacent elements above; add maximal
                triangle[i][j] += max(triangle[i-1][j-1], triangle[i-1][j])
            elif j == 0:
                # no adjacent element to left above; add right
                triangle[i][j] += triangle[i - 1][j]
            else:
                # no adjacent element to right above; add left
                triangle[i][j] += triangle[i - 1][j - 1]

    # return maximal sum accumulated in last row of triangle
    return max(triangle[-1])