main algo