Nit: but it might be nicer if this function didn't expose the `ancestors` to the outside world, since there is no real reason to have that in the public contract of the function. Could you instead write an inner function and recurse using that, instead of recursing down the top level function? If you did that you could probably avoid passing `ancestors` around at all, and instead just define the ancestors set in the outer function and the inner function will have a direct reference.