def fls(val: int, v6: bool) -> int:
    """Find last set - returns the index, counting from 0 (from the right) of the
    most significant set bit in `val`."""
    # if b is zero, there is no first set bit
    if val == 0:
        return 0

    # gradually set all bits right of MSB
    # this technique is called 'bit smearing'
    # if ipv6, max bit index we want to smear is 2^7=64, 
    # otherwise it's 2^4=16
    max_power_of_2 = 7 if v6 else 5
    n = val | val >> 1
    for i in range(1, max_power_of_2+1):
        n |= n >> 2**i

    # increment diff by one so that there's only
    # one set bit which is just before original MSB
    n += 1

    # shift it so it's in the original position
    n >>= 1

    # figure out the ordinal of the bit from LSB
    pos = 0
    while (n & 1) == 0:
        n >>= 1
        pos += 1
    return pos