implement the algorithm