def is_even(n):
    return n % 2 == 0
def fib(n):
    return fib_iter(1, 0, 0, 1, n)

def fib_iter(a, b, p, q, count):
    return (b
            if count == 0
            else fib_iter(a,
                          b,
                          p * p + q * q,
                          2 * p * q + q * q,
                          count // 2)
            if is_even(count)
            else fib_iter(b * q + a * q + a * p,
                          b * p + a * q,
                          p,
                          q,
                          count - 1))
print(fib(5))

# expected: 5
