load("div.sage")

def construct(points):
    divs = []
    for i in range(0, len(points), 2):
        # Odd last remainder element
        if i + 1 == len(points):
            P = points[i]
            L = div_line(P, -P)
            Q = points[i]
            divs.append((Q, L))
            break

        P1, P2 = points[i], points[i + 1]
        L = div_line(P1, P2)
        Q = P1 + P2
        divs.append((Q, L))

    # Now apply reduction algorithm repeatedly
    while len(divs) != 1:
        divs2 = []

        if len(divs) % 2 == 1:
            divs2.append(divs[0])
            divs = divs[1:]

        for i in range(0, len(divs), 2):
            assert i + 1 < len(divs)
            Q1, L1 = divs[i]
            Q2, L2 = divs[i + 1]
            ℓ = div_line(Q1, Q2)
            L = ℓ + L1 + L2 - div_line(Q1, -Q1) - div_line(Q2, -Q2)
            Q = Q1 + Q2
            divs2.append((Q, L))

        divs = divs2

    assert len(divs) == 1
    return divs[0][1]

