

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

typedef long long ll;

using namespace std;

const int maxn = 3e3 + 50, INF = 0x3f3f3f3f;

inline int read () {
	register int x = 0, w = 1;
	register char ch = getchar ();
	for (; ch < '0' || ch > '9'; ch = getchar ()) if (ch == '-') w = -1;
	for (; ch >= '0' && ch <= '9'; ch = getchar ()) x = x * 10 + ch - '0';
	return x * w;
}

int n, deg[maxn], que[maxn], lst[maxn];
bool vis[maxn], incir[maxn];
double ans;

struct Edge {
	int to, next;
} e[maxn << 1];

int tot, head[maxn];

inline void Add (register int u, register int v) {
	e[++ tot].to = v;
	e[tot].next = head[u];
	head[u] = tot;
}

inline void Topu (register int front = 0, register int tail = -1) {
	for (register int i = 1; i <= n; i ++)
		if (deg[i] == 1) que[++ tail] = i;
	while (front <= tail) {
		register int u = que[front ++];
		for (register int i = head[u]; i; i = e[i].next) {
			register int v = e[i].to;
			if (-- deg[v] == 1) que[++ tail] = v;
		}
	}
	for (register int i = 1; i <= n; i ++) if (deg[i] == 2) incir[i] = 1;
}

inline void DFS (register int u, register int dis0, register int dis1) {
	if (dis1) {
		ans +=1.0/(dis0 + dis1);
		if (lst[u]) ans -=1.0/(dis0 + dis1 + lst[u] - 2);
		else lst[u] = dis1;
	} else ans +=1.0/dis0;
	for (register int i = head[u]; i; i = e[i].next) {
		register int v = e[i].to;
		if (vis[v]) continue;
		if (incir[v]) vis[v] = 1, DFS (v, dis0, dis1 + 1), vis[v] = 0;
		else vis[v] = 1, DFS (v, dis0 + 1, dis1), vis[v] = 0;
	}
}

int main ()
{
	n = read();
	for (register int i = 1, u, v; i <= n; i ++)
		u = read(), v = read(), deg[u] ++, deg[v] ++, Add (u, v), Add (v, u);
	Topu ();
	for (register int i = 1; i <= n; i ++) {
		memset (lst, 0, sizeof lst);
		if (incir[i]) vis[i] = 1, DFS (i, 0, 1), vis[i] = 0;
		else vis[i] = 1, DFS (i, 1, 0), vis[i] = 0;
	}
	return printf ("%.10lf\n", ans), 0;
}
