improve algorithm