public static void Part2(FighterStats boss, List <Spell> spells)
    {
        var player = new FighterStats(50, 0, 0, 500);
        var data   = new Data {
            Spells      = spells,
            MinManaUsed = Int32.MaxValue,
            HardMode    = true
        };
        var state = new StateNode {
            Player        = player,
            Boss          = boss,
            ActiveEffects = new List <Effect>(),
        };

        Func <Data, StateNode, bool> reject = (Data data, StateNode state) => {
            if (state.Player.Hp <= 0 || state.Player.Mana <= 0 || state.ManaSpent > data.MinManaUsed)
            {
                return(true);
            }
            return(false);
        };
        Func <Data, StateNode, bool> accept = (Data data, StateNode state) => {
            if (state.Boss.Hp <= 0)
            {
                data.MinManaUsed = Math.Min(data.MinManaUsed, state.ManaSpent);
                return(true);
            }
            return(false);
        };

        Console.WriteLine(AOC.Backtrack(data, state, reject, accept, TrySpells).Select(s => s.ManaSpent).Min());
    }