





'''simple docstring'''






from __future__ import annotations

import math
def 							_lowerCamelCase(  UpperCamelCase__    : list    ,       UpperCamelCase__    : list		)		->  list:
    if len(UpperCamelCase__		) != 2 or len(a[0]		) != 2 or len(UpperCamelCase__		) != 2 or len(b[0]		) != 2:
        raise Exception('''Matrices are not 2x2'''		)
    A       :       List[Any]							=						[
        [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
        [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]],
    ]
    return new_matrix
def 							_lowerCamelCase(  UpperCamelCase__    : list    ,       UpperCamelCase__    : list		)		->  str:
    return [
        [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]		)		)]
        for row in range(len(UpperCamelCase__		)		)
    ]
def 							_lowerCamelCase(  UpperCamelCase__    : list    ,       UpperCamelCase__    : list		)		->  Optional[Any]:
    return [
        [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]		)		)]
        for row in range(len(UpperCamelCase__		)		)
    ]
def 							_lowerCamelCase(  UpperCamelCase__    : list		)		->  tuple[list, list, list, list]:
    if len(UpperCamelCase__		) % 2 != 0 or len(a[0]		) % 2 != 0:
        raise Exception('''Odd matrices are not supported!'''		)

    A       :       Any							=						len(UpperCamelCase__		)
    A       :       Optional[Any]							=						matrix_length // 2

    A       :       Dict							=						[[a[i][j] for j in range(UpperCamelCase__    ,       UpperCamelCase__		)] for i in range(UpperCamelCase__		)]
    A       :       Union[str, Any]							=						[
        [a[i][j] for j in range(UpperCamelCase__    ,       UpperCamelCase__		)] for i in range(UpperCamelCase__    ,       UpperCamelCase__		)
    ]

    A       :       Optional[Any]							=						[[a[i][j] for j in range(UpperCamelCase__		)] for i in range(UpperCamelCase__		)]
    A       :       Union[str, Any]							=						[[a[i][j] for j in range(UpperCamelCase__		)] for i in range(UpperCamelCase__    ,       UpperCamelCase__		)]

    return top_left, top_right, bot_left, bot_right
def 							_lowerCamelCase(  UpperCamelCase__    : list		)		->  tuple[int, int]:
    return len(UpperCamelCase__		), len(matrix[0]		)
def 							_lowerCamelCase(  UpperCamelCase__    : list		)		->  None:
    print('''\n'''.join(str(UpperCamelCase__		) for line in matrix		)		)
def 							_lowerCamelCase(  UpperCamelCase__    : list    ,       UpperCamelCase__    : list		)		->  list:
    if matrix_dimensions(UpperCamelCase__		) == (2, 2):
        return default_matrix_multiplication(UpperCamelCase__    ,       UpperCamelCase__		)

    A,	A,	A,	A       :       Optional[Any]							=						split_matrix(UpperCamelCase__		)
    A,	A,	A,	A       :       List[str]							=						split_matrix(UpperCamelCase__		)

    A       :       Union[str, Any]							=						actual_strassen(UpperCamelCase__    ,       matrix_subtraction(UpperCamelCase__    ,       UpperCamelCase__		)		)
    A       :       Dict							=						actual_strassen(matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)    ,       UpperCamelCase__		)
    A       :       int							=						actual_strassen(matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)    ,       UpperCamelCase__		)
    A       :       str							=						actual_strassen(UpperCamelCase__    ,       matrix_subtraction(UpperCamelCase__    ,       UpperCamelCase__		)		)
    A       :       Union[str, Any]							=						actual_strassen(matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)    ,       matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)		)
    A       :       Tuple							=						actual_strassen(matrix_subtraction(UpperCamelCase__    ,       UpperCamelCase__		)    ,       matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)		)
    A       :       Any							=						actual_strassen(matrix_subtraction(UpperCamelCase__    ,       UpperCamelCase__		)    ,       matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)		)

    A       :       int							=						matrix_addition(matrix_subtraction(matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)    ,       UpperCamelCase__		)    ,       UpperCamelCase__		)
    A       :       Optional[int]							=						matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)
    A       :       Optional[Any]							=						matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)
    A       :       Dict							=						matrix_subtraction(matrix_subtraction(matrix_addition(UpperCamelCase__    ,       UpperCamelCase__		)    ,       UpperCamelCase__		)    ,       UpperCamelCase__		)

    # construct the new matrix from our 4 quadrants
    A       :       int							=						[]
    for i in range(len(UpperCamelCase__		)		):
        new_matrix.append(top_left[i] + top_right[i]		)
    for i in range(len(UpperCamelCase__		)		):
        new_matrix.append(bot_left[i] + bot_right[i]		)
    return new_matrix
def 							_lowerCamelCase(  UpperCamelCase__    : list    ,       UpperCamelCase__    : list		)		->  list:
    if matrix_dimensions(UpperCamelCase__		)[1] != matrix_dimensions(UpperCamelCase__		)[0]:
        A       :       Tuple							=						(
            '''Unable to multiply these matrices, please check the dimensions.\n'''
            F'''Matrix A: {matrixa}\n'''
            F'''Matrix B: {matrixa}'''
        )
        raise Exception(UpperCamelCase__		)
    A       :       Optional[Any]							=						matrix_dimensions(UpperCamelCase__		)
    A       :       List[str]							=						matrix_dimensions(UpperCamelCase__		)

    if dimensiona[0] == dimensiona[1] and dimensiona[0] == dimensiona[1]:
        return [matrixa, matrixa]

    A       :       List[Any]							=						max(*UpperCamelCase__    ,       *UpperCamelCase__		)
    A       :       int							=						int(math.pow(2    ,       math.ceil(math.loga(UpperCamelCase__		)		)		)		)
    A       :       int							=						matrixa
    A       :       Any							=						matrixa

    # Adding zeros to the matrices so that the arrays dimensions are the same and also
    # power of 2
    for i in range(0    ,       UpperCamelCase__		):
        if i < dimensiona[0]:
            for _ in range(dimensiona[1]    ,       UpperCamelCase__		):
                new_matrixa[i].append(0		)
        else:
            new_matrixa.append([0] * maxim		)
        if i < dimensiona[0]:
            for _ in range(dimensiona[1]    ,       UpperCamelCase__		):
                new_matrixa[i].append(0		)
        else:
            new_matrixa.append([0] * maxim		)

    A       :       Dict							=						actual_strassen(UpperCamelCase__    ,       UpperCamelCase__		)

    # Removing the additional zeros
    for i in range(0    ,       UpperCamelCase__		):
        if i < dimensiona[0]:
            for _ in range(dimensiona[1]    ,       UpperCamelCase__		):
                final_matrix[i].pop()
        else:
            final_matrix.pop()
    return final_matrix


if __name__ == "__main__":
     snake_case_     =	[
         [2, 3, 4, 5],
         [6, 4, 3, 1],
         [2, 3, 6, 7],
         [3, 1, 2, 4],
         [2, 3, 4, 5],
         [6, 4, 3, 1],
         [2, 3, 6, 7],
         [3, 1, 2, 4],
         [2, 3, 4, 5],
         [6, 2, 3, 1],
     ]
     snake_case_     =	[[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
     print(strassen(matrixa, matrixa))







'''simple docstring'''






from __future__ import annotations


class   _lowercase						:


   def __init__( self    ,   _UpperCAmelCase					):
       A       :       str							=						data
       A       :       Node | None							=						None
       A       :       Node | None							=						None







def 							_lowerCamelCase(  UpperCamelCase__    : Node | None		)		->  None:  # In Order traversal of the tree
    if tree:
        display(tree.left		)
        print(tree.data		)
        display(tree.right		)
def 							_lowerCamelCase(  UpperCamelCase__    : Node | None		)		->  int:
    return 1 + max(depth_of_tree(tree.left		)    ,       depth_of_tree(tree.right		)		) if tree else 0
def 							_lowerCamelCase(  UpperCamelCase__    : Node		)		->  bool:
    if not tree:
        return True
    if tree.left and tree.right:
        return is_full_binary_tree(tree.left		) and is_full_binary_tree(tree.right		)
    else:
        return not tree.left and not tree.right
def 							_lowerCamelCase(  )		->  None:  # Main function for testing.
    A       :       Optional[int]							=						Node(1		)
    A       :       Tuple							=						Node(2		)
    A       :       Dict							=						Node(3		)
    A       :       List[str]							=						Node(4		)
    A       :       Union[str, Any]							=						Node(5		)
    A       :       str							=						Node(6		)
    A       :       Any							=						Node(7		)
    A       :       str							=						Node(8		)
    A       :       Optional[int]							=						Node(9		)

    print(is_full_binary_tree(UpperCamelCase__		)		)
    print(depth_of_tree(UpperCamelCase__		)		)
    print('''Tree is: '''		)
    display(UpperCamelCase__		)


if __name__ == "__main__":
     main()
