rewritten to make fewer loops