import java.util.ArrayList;
import java.util.List;

public class Euler514 {

    static class Direction {
        int dx, dy;

        Direction(int dx, int dy) {
            this.dx = dx;
            this.dy = dy;
        }
    }

    static class Point {
        int x, y;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    static int gcd(int a, int b) {
        while (b != 0) {
            int temp = a % b;
            a = b;
            b = temp;
        }
        return Math.abs(a);
    }

    static List<Direction> buildDirections(int N) {
        List<Direction> dirs = new ArrayList<>();
        for (int dx = -N; dx <= N; dx++) {
            for (int dy = -N; dy <= N; dy++) {
                if (dx == 0 && dy == 0)
                    continue;
                if (gcd(Math.abs(dx), Math.abs(dy)) != 1)
                    continue;
                dirs.add(new Direction(dx, dy));
            }
        }
        return dirs;
    }

    static double processDirection(int N, Direction dir, double[] powQ, double p, int totalPoints) {
        int n1 = dir.dy;
        int n2 = -dir.dx;

        int s00 = 0;
        int sN0 = n1 * N;
        int s0N = n2 * N;
        int sNN = n1 * N + n2 * N;

        int minS = Math.min(Math.min(s00, sN0), Math.min(s0N, sNN));
        int maxS = Math.max(Math.max(s00, sN0), Math.max(s0N, sNN));
        int range = maxS - minS + 1;

        int[] counts = new int[range];
        List<Point> starts = new ArrayList<>();

        for (int x = 0; x <= N; x++) {
            for (int y = 0; y <= N; y++) {
                int s = n1 * x + n2 * y;
                counts[s - minS]++;
                int px = x - dir.dx;
                int py = y - dir.dy;
                if (px < 0 || px > N || py < 0 || py > N) {
                    starts.add(new Point(x, y));
                }
            }
        }

        int[] prefix = new int[range + 1];
        for (int i = 0; i < range; i++) {
            prefix[i + 1] = prefix[i] + counts[i];
        }

        double p2 = p * p;
        double sumDir = 0.0;
        List<Point> line = new ArrayList<>();

        for (Point start : starts) {
            line.clear();
            int x = start.x;
            int y = start.y;
            while (x >= 0 && x <= N && y >= 0 && y <= N) {
                line.add(new Point(x, y));
                x += dir.dx;
                y += dir.dy;
            }

            int k = line.size();
            if (k < 2)
                continue;

            int s0 = n1 * start.x + n2 * start.y;
            int idx = s0 - minS;
            int L = prefix[idx];
            if (L == 0)
                continue;
            int kOn = counts[idx];
            int R = totalPoints - prefix[idx] - kOn;

            double factor = p2 * powQ[R] * (1.0 - powQ[L]);
            if (factor == 0.0)
                continue;

            double sumLine = 0.0;
            for (int i = 0; i < k - 1; i++) {
                double wi = powQ[i];
                int xi = line.get(i).x;
                int yi = line.get(i).y;
                for (int j = i + 1; j < k; j++) {
                    double wj = powQ[k - 1 - j];
                    double cross = (double) xi * line.get(j).y - (double) line.get(j).x * yi;
                    sumLine += cross * wi * wj;
                }
            }
            sumDir += factor * sumLine;
        }
        return sumDir;
    }

    static double computeExpectedArea(int N) {
        int totalPoints = (N + 1) * (N + 1);
        double p = 1.0 / (double) (N + 1);
        double q = 1.0 - p;

        double[] powQ = new double[totalPoints + 1];
        powQ[0] = 1.0;
        for (int i = 1; i <= totalPoints; i++)
            powQ[i] = powQ[i - 1] * q;

        List<Direction> dirs = buildDirections(N);

        // Multithreaded evaluation for speed
        double sumTotal = dirs.parallelStream()
                .mapToDouble(d -> processDirection(N, d, powQ, p, totalPoints))
                .sum();

        return 0.5 * sumTotal;
    }

    public static void main(String[] args) {
        double ans = computeExpectedArea(100);
        System.out.printf(java.util.Locale.US, "%.5f\n", ans);
    }
}
