reimplment using topological sort