final algorithm