public static BigInteger OreRequiredToProduceFuel(BigInteger amount, ChemicalProductionGraph graph)
        {
            var amountRequired  = graph.Nodes().ToDictionary(x => x, x => x == "FUEL" ? amount : 0);
            var unfinishedNodes = graph.Nodes().ToHashSet();

            while (unfinishedNodes.Any())
            {
                var nextUnfinishedNodes = new HashSet <string>(unfinishedNodes);
                foreach (var node in unfinishedNodes)
                {
                    var parents = graph.InNeighbours(node).Select(x => x.nb);
                    if (!unfinishedNodes.Intersect(parents).Any())
                    {
                        var        children        = graph.OutNeighbours(node);
                        BigInteger amountOfBatches = (amountRequired[node] - 1) / graph.BatchSize(node) + 1; //find smallest x s.t. x*batchsize > amountrequired
                        foreach ((string child, int perbatch) in children)
                        {
                            amountRequired[child] += perbatch * amountOfBatches;
                        }
                        nextUnfinishedNodes.Remove(node);
                    }
                }
                unfinishedNodes = nextUnfinishedNodes;
            }
            return(amountRequired["ORE"]);
        }
 protected override void PrepareSolution()
 {
     cpgraph = new ChemicalProductionGraph(recipes);
 }