import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class Euler441 {
    static final int N = 10000000;
    static final int HALF = N / 2;

    static int[] spf;
    static int[] phi;
    static double[] harmonic;

    static void buildSieveAndHarmonic() {
        spf = new int[N + 1];
        phi = new int[N + 1];
        harmonic = new double[N + 1];

        phi[1] = 1;
        List<Integer> primes = new ArrayList<>();

        for (int i = 2; i <= N; i++) {
            if (spf[i] == 0) {
                spf[i] = i;
                phi[i] = i - 1;
                primes.add(i);
            }

            for (int p : primes) {
                long v = (long) i * p;
                if (v > N)
                    break;
                spf[(int) v] = p;
                if (p == spf[i]) {
                    phi[(int) v] = phi[i] * p;
                    break;
                }
                phi[(int) v] = phi[i] * (p - 1);
            }
        }

        harmonic[0] = 0.0;
        for (int i = 1; i <= N; i++) {
            harmonic[i] = harmonic[i - 1] + 1.0 / i;
        }
    }

    static class KahanAccumulator {
        double sum = 0.0;
        double compensation = 0.0;

        void add(double value) {
            double y = value - compensation;
            double t = sum + y;
            compensation = (t - sum) - y;
            sum = t;
        }
    }

    static double computeContribution(int q) {
        int[] primeFactors = new int[16];
        int factorCount = 0;

        int x = q;
        while (x > 1) {
            int p = spf[x];
            primeFactors[factorCount++] = p;
            while (x % p == 0) {
                x /= p;
            }
        }

        int[] divisors = new int[1024];
        int[] signs = new int[1024];
        int subsetCount = 1;

        divisors[0] = 1;
        signs[0] = 1;

        for (int i = 0; i < factorCount; i++) {
            int p = primeFactors[i];
            for (int j = 0; j < subsetCount; j++) {
                divisors[subsetCount + j] = divisors[j] * p;
                signs[subsetCount + j] = -signs[j];
            }
            subsetCount <<= 1;
        }

        int qm1 = q - 1;

        if (q <= HALF) {
            double aFull = 0.0;
            for (int i = 0; i < subsetCount; i++) {
                int d = divisors[i];
                double signedInvD = (double) signs[i] / d;
                aFull += signedInvD * harmonic[qm1 / d];
            }
            return (phi[q] + aFull) / q;
        }

        int a = N - q;
        double aA = 0.0;
        double b = 0.0;
        long c = 0;

        for (int i = 0; i < subsetCount; i++) {
            int d = divisors[i];
            int sign = signs[i];
            double signedInvD = (double) sign / d;
            int aOverD = a / d;

            c += (long) sign * aOverD;
            double ha = harmonic[aOverD];
            double hq = harmonic[qm1 / d];

            aA += signedInvD * ha;
            b += signedInvD * (hq - ha);
        }

        double numerator = c + aA + (a + 1) * b;
        return numerator / q;
    }

    public static String solve() {
        buildSieveAndHarmonic();

        int numThreads = Math.max(1, Runtime.getRuntime().availableProcessors());
        int chunkSize = 2048;
        int totalChunks = (N - 1 + chunkSize - 1) / chunkSize;
        double[] partials = new double[totalChunks];

        IntStream.range(0, totalChunks).parallel().forEach(chunkIdx -> {
            int qBegin = 2 + chunkIdx * chunkSize;
            int qEnd = Math.min(N, qBegin + chunkSize - 1);
            KahanAccumulator local = new KahanAccumulator();
            for (int q = qBegin; q <= qEnd; q++) {
                local.add(computeContribution(q));
            }
            partials[chunkIdx] = local.sum;
        });

        KahanAccumulator total = new KahanAccumulator();
        for (double p : partials) {
            total.add(p);
        }

        return String.format(java.util.Locale.US, "%.4f", total.sum);
    }

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