First, full version of the algorithm