import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.Locale;

public class Euler695 {
    static double median3(double a, double b, double c) {
        return a + b + c - Math.min(a, Math.min(b, c)) - Math.max(a, Math.max(b, c));
    }

    static double meanMedianNormalized(double x, double y) {
        double x0 = 1.0 - x;
        double y0 = 1.0 - y;

        double m1 = median3(x * y, x0 * y0, 1.0);
        double m2 = median3(x * y, x0, y0);
        double m3 = median3(x * y0, x0 * y, 1.0);
        double m4 = median3(x * y0, x0, y);
        double m5 = median3(x, x0 * y, y0);
        double m6 = median3(x, x0 * y0, y);

        return (m1 + m2 + m3 + m4 + m5 + m6) / 6.0;
    }

    static class NodesWeights {
        double[] x;
        double[] w;
    }

    static NodesWeights gaussLegendreUnitInterval(int n) {
        NodesWeights nw = new NodesWeights();
        nw.x = new double[n];
        nw.w = new double[n];

        double pi = Math.PI;
        double eps = 1e-15;
        int half = (n + 1) / 2;

        for (int i = 0; i < half; ++i) {
            double z = Math.cos(pi * (i + 0.75) / (n + 0.5));
            double zPrev = 0.0;
            double p1 = 0.0, p2 = 0.0, pp = 0.0;

            do {
                p1 = 1.0;
                p2 = 0.0;
                for (int j = 1; j <= n; ++j) {
                    double p3 = p2;
                    p2 = p1;
                    p1 = ((2.0 * j - 1.0) * z * p2 - (j - 1.0) * p3) / j;
                }
                pp = n * (z * p1 - p2) / (z * z - 1.0);
                zPrev = z;
                z = zPrev - p1 / pp;
            } while (Math.abs(z - zPrev) > eps);

            double weight = 2.0 / ((1.0 - z * z) * pp * pp);
            int iLeft = i;
            int iRight = n - 1 - i;

            nw.x[iLeft] = 0.5 * (-z + 1.0);
            nw.x[iRight] = 0.5 * (z + 1.0);
            nw.w[iLeft] = 0.5 * weight;
            nw.w[iRight] = 0.5 * weight;
        }

        return nw;
    }

    static double integrateJ(int n) {
        NodesWeights nw = gaussLegendreUnitInterval(n);

        int threads = Runtime.getRuntime().availableProcessors();
        if (threads < 1)
            threads = 1;

        ExecutorService pool = Executors.newFixedThreadPool(threads);
        List<Future<Double>> futures = new ArrayList<>();

        for (int t = 0; t < threads; ++t) {
            int start = (n * t) / threads;
            int end = (n * (t + 1)) / threads;

            futures.add(pool.submit(() -> {
                double localSum = 0.0;
                for (int i = start; i < end; ++i) {
                    double xi = nw.x[i];
                    double wi = nw.w[i];
                    double row = wi * wi * meanMedianNormalized(xi, xi);
                    for (int j = i + 1; j < n; ++j) {
                        row += 2.0 * wi * nw.w[j] * meanMedianNormalized(xi, nw.x[j]);
                    }
                    localSum += row;
                }
                return localSum;
            }));
        }

        double total = 0.0;
        for (Future<Double> f : futures) {
            try {
                total += f.get();
            } catch (Exception e) {
            }
        }
        pool.shutdown();

        return total;
    }

    public static String solve() {
        int baseN = 8192;
        int fineN = baseN * 2;

        double eBase = integrateJ(baseN) / 4.0;
        double eFine = integrateJ(fineN) / 4.0;

        double eRichardson = eFine + (eFine - eBase) / 3.0;

        return String.format(Locale.US, "%.10f", eRichardson);
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
