private ulong EvaluateInternal(ulong n, ulong x0, ulong xmax)
        {
            this.n = n;
            x0     = T1(x0 + 1);
            xmax   = T1(xmax);
            if (x0 > xmax)
            {
                return(0);
            }
            var ymin = YFloor(xmax);
            var xmin = Math.Max(x0, Math.Min(T1(C1 * IntegerMath.CeilingRoot(2 * n, 3)), xmax));

#if DIAG
            Console.WriteLine("n = {0}, xmin = {1}, xmax = {2}", n, xmin, xmax);
#endif
            var s  = (ulong)0;
            var a2 = (ulong)1;
            var x2 = xmax;
            var y2 = ymin;
            var c2 = a2 * x2 + y2;
            while (true)
            {
                var a1 = a2 + 1;
                var x4 = YTan(a1);
                var y4 = YFloor(x4);
                var c4 = a1 * x4 + y4;
                var x5 = x4 + 1;
                var y5 = YFloor(x5);
                var c5 = a1 * x5 + y5;
                if (x4 <= xmin)
                {
                    break;
                }
                s += Triangle(c4 - c2 - x0) - Triangle(c4 - c2 - x5) + Triangle(c5 - c2 - x5);
                if (threads == 0)
                {
                    s += ProcessRegion(0, (ulong)(a1 * x2 + y2 - c5), (ulong)(a2 * x5 + y5 - c2), a1, 1, c5, a2, 1, c2);
                    while (stack.Count > 0)
                    {
                        var r = stack.Pop();
                        s += ProcessRegion(0, r.w, r.h, r.a1, r.b1, r.c1, r.a2, r.b2, r.c2);
                    }
                }
                else
                {
                    Enqueue(new Region((ulong)(a1 * x2 + y2 - c5), (ulong)(a2 * x5 + y5 - c2), a1, 1, c5, a2, 1, c2));
                }
                a2 = a1;
                x2 = x4;
                y2 = y4;
                c2 = c4;
            }
            s += (xmax - x0 + 1) * ymin + Triangle(xmax - x0);
            var rest = x2 - x0;
            s      -= y2 * rest + a2 * Triangle(rest);
            xmanual = x2;
            return(s);
        }