The main algorithm