import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

public class Euler794 {

    static long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    static long lcm(long a, long b) {
        return (a / gcd(a, b)) * b;
    }

    static int lcmUpto(int n) {
        long d = 1;
        for (int i = 1; i <= n; ++i) {
            d = lcm(d, i);
        }
        return (int) d;
    }

    static class Interval implements Comparable<Interval> {
        int l, u;

        Interval(int l, int u) {
            this.l = l;
            this.u = u;
        }

        @Override
        public int compareTo(Interval other) {
            if (this.l != other.l) {
                return Integer.compare(this.l, other.l);
            }
            return Integer.compare(this.u, other.u);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;
            Interval interval = (Interval) o;
            return l == interval.l && u == interval.u;
        }

        @Override
        public int hashCode() {
            return 31 * l + u;
        }
    }

    static class Option {
        int bin, l, u;

        Option(int bin, int l, int u) {
            this.bin = bin;
            this.l = l;
            this.u = u;
        }
    }

    static class Solver {
        int target;
        int d;
        HashMap<ArrayList<Interval>, Long> memoMin;
        HashMap<ArrayList<Interval>, Boolean> memoFeasible;

        Solver(int target) {
            this.target = target;
            this.d = lcmUpto(target);
            this.memoMin = new HashMap<>();
            this.memoFeasible = new HashMap<>();
        }

        long solveMin() {
            ArrayList<Interval> init = new ArrayList<>();
            init.add(new Interval(0, d));
            return solveMinState(init);
        }

        boolean canChooseAll() {
            ArrayList<Interval> init = new ArrayList<>();
            init.add(new Interval(0, d));
            return feasibleState(init);
        }

        long solveMinState(ArrayList<Interval> intervals) {
            if (memoMin.containsKey(intervals)) {
                return memoMin.get(intervals);
            }

            int n = intervals.size();
            if (n == target) {
                long sum = 0;
                for (Interval in : intervals) {
                    sum += in.l;
                }
                memoMin.put(new ArrayList<>(intervals), sum);
                return sum;
            }

            int m = n + 1;
            int[][] bins = new int[m][2];
            for (int k = 0; k < m; ++k) {
                bins[k][0] = k * d / m;
                bins[k][1] = (k + 1) * d / m;
            }

            ArrayList<ArrayList<Option>> options = new ArrayList<>(n);
            for (int i = 0; i < n; ++i) {
                ArrayList<Option> ops = new ArrayList<>();
                for (int k = 0; k < m; ++k) {
                    int nl = Math.max(intervals.get(i).l, bins[k][0]);
                    int nu = Math.min(intervals.get(i).u, bins[k][1]);
                    if (nl < nu) {
                        ops.add(new Option(k, nl, nu));
                    }
                }
                if (ops.isEmpty()) {
                    long INF = 1L << 60;
                    memoMin.put(new ArrayList<>(intervals), INF);
                    return INF;
                }
                options.add(ops);
            }

            Integer[] order = new Integer[n];
            for (int i = 0; i < n; i++)
                order[i] = i;

            Arrays.sort(order, Comparator.comparingInt(a -> options.get(a).size()));

            boolean[] used = new boolean[m];
            Interval[] assigned = new Interval[n];
            long[] best = { 1L << 60 };

            dfsMin(0, n, m, order, options, used, assigned, bins, best);

            memoMin.put(new ArrayList<>(intervals), best[0]);
            return best[0];
        }

        void dfsMin(int pos, int n, int m, Integer[] order, ArrayList<ArrayList<Option>> options,
                boolean[] used, Interval[] assigned, int[][] bins, long[] best) {
            if (pos == n) {
                int hole = -1;
                for (int k = 0; k < m; ++k) {
                    if (!used[k]) {
                        hole = k;
                        break;
                    }
                }
                if (hole < 0)
                    return;

                ArrayList<Interval> child = new ArrayList<>(Arrays.asList(assigned));
                child.add(new Interval(bins[hole][0], bins[hole][1]));
                Collections.sort(child);

                long cand = solveMinState(child);
                if (cand < best[0]) {
                    best[0] = cand;
                }
                return;
            }

            int i = order[pos];
            for (Option op : options.get(i)) {
                if (used[op.bin])
                    continue;
                used[op.bin] = true;
                assigned[i] = new Interval(op.l, op.u);
                dfsMin(pos + 1, n, m, order, options, used, assigned, bins, best);
                used[op.bin] = false;
            }
        }

        boolean feasibleState(ArrayList<Interval> intervals) {
            if (memoFeasible.containsKey(intervals)) {
                return memoFeasible.get(intervals);
            }

            int n = intervals.size();
            if (n == target) {
                memoFeasible.put(new ArrayList<>(intervals), true);
                return true;
            }

            int m = n + 1;
            int[][] bins = new int[m][2];
            for (int k = 0; k < m; ++k) {
                bins[k][0] = k * d / m;
                bins[k][1] = (k + 1) * d / m;
            }

            ArrayList<ArrayList<Option>> options = new ArrayList<>(n);
            for (int i = 0; i < n; ++i) {
                ArrayList<Option> ops = new ArrayList<>();
                for (int k = 0; k < m; ++k) {
                    int nl = Math.max(intervals.get(i).l, bins[k][0]);
                    int nu = Math.min(intervals.get(i).u, bins[k][1]);
                    if (nl < nu) {
                        ops.add(new Option(k, nl, nu));
                    }
                }
                if (ops.isEmpty()) {
                    memoFeasible.put(new ArrayList<>(intervals), false);
                    return false;
                }
                options.add(ops);
            }

            Integer[] order = new Integer[n];
            for (int i = 0; i < n; i++)
                order[i] = i;

            Arrays.sort(order, Comparator.comparingInt(a -> options.get(a).size()));

            boolean[] used = new boolean[m];
            Interval[] assigned = new Interval[n];
            boolean[] ok = { false };

            dfsFeasible(0, n, m, order, options, used, assigned, bins, ok);

            memoFeasible.put(new ArrayList<>(intervals), ok[0]);
            return ok[0];
        }

        void dfsFeasible(int pos, int n, int m, Integer[] order, ArrayList<ArrayList<Option>> options,
                boolean[] used, Interval[] assigned, int[][] bins, boolean[] ok) {
            if (ok[0])
                return;
            if (pos == n) {
                int hole = -1;
                for (int k = 0; k < m; ++k) {
                    if (!used[k]) {
                        hole = k;
                        break;
                    }
                }
                if (hole < 0)
                    return;

                ArrayList<Interval> child = new ArrayList<>(Arrays.asList(assigned));
                child.add(new Interval(bins[hole][0], bins[hole][1]));
                Collections.sort(child);

                if (feasibleState(child)) {
                    ok[0] = true;
                }
                return;
            }

            int i = order[pos];
            for (Option op : options.get(i)) {
                if (used[op.bin])
                    continue;
                used[op.bin] = true;
                assigned[i] = new Interval(op.l, op.u);
                dfsFeasible(pos + 1, n, m, order, options, used, assigned, bins, ok);
                used[op.bin] = false;
                if (ok[0])
                    return;
            }
        }
    }

    static String formatRounded12(long numerator, int denominator) {
        BigInteger SCALE = BigInteger.valueOf(1000000000000L);
        BigInteger num = BigInteger.valueOf(numerator);
        BigInteger den = BigInteger.valueOf(denominator);

        BigInteger rounded = num.multiply(SCALE).multiply(BigInteger.TWO).add(den)
                .divide(den.multiply(BigInteger.TWO));

        BigInteger integerPart = rounded.divide(SCALE);
        BigInteger fracPart = rounded.remainder(SCALE);

        String frac = fracPart.toString();
        while (frac.length() < 12) {
            frac = "0" + frac;
        }

        return integerPart.toString() + "." + frac;
    }

    public static String solve() {
        Solver solver17 = new Solver(17);
        long num = solver17.solveMin();
        return formatRounded12(num, solver17.d);
    }

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