#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 7;
int n;
vector<int> G[3005];
vector<int> cyc;
int grp[3005];
bool vis[3005];
int find_cyc(int v, int par) {
  vis[v] = true;
  cyc.push_back(v);
  for (int i = 0; i < (int)(G[v].size()); i++) {
    int u = G[v][i];
    if (u == par) continue;
    if (vis[u]) return u;
    int cans = find_cyc(u, v);
    if (cans != -1) return cans;
  }
  cyc.pop_back();
  return -1;
}
int dep[3005];
vector<int> subt[3005];
int dist[3005][3005];
void gen_info(int v, int gid) {
  grp[v] = gid;
  subt[v].push_back(v);
  for (int i = 0; i < (int)(G[v].size()); i++) {
    int u = G[v][i];
    if (grp[u] != -1) continue;
    dep[u] = dep[v] + 1;
    gen_info(u, gid);
    for (int j = 0; j < (int)(subt[u].size()); j++)
      for (int k = 0; k < (int)(subt[v].size()); k++) {
        int cu = subt[u][j], cv = subt[v][k];
        dist[cu][cv] = dist[cv][cu] = dep[cu] + dep[cv] - dep[v];
      }
    for (int j = 0; j < (int)(subt[u].size()); j++)
      subt[v].push_back(subt[u][j]);
  }
}
void gen_info() {
  int v = find_cyc(0, -1);
  reverse(cyc.begin(), cyc.end());
  while (cyc.back() != v) cyc.pop_back();
  for (int i = 0; i < (int)(n); i++) grp[i] = -1;
  for (int i = 0; i < (int)(cyc.size()); i++) {
    grp[cyc[i]] = i;
    dep[cyc[i]] = 0;
  }
  for (int i = 0; i < (int)(cyc.size()); i++) gen_info(cyc[i], i);
}
double get_cost(int u, int v) {
  if (grp[u] == grp[v]) return 1.0 / (dist[u][v] + 1);
  int gu = grp[u], gv = grp[v];
  if (gu > gv) swap(gu, gv);
  return 1.0 / (gv - gu + dep[u] + dep[v] + 1) +
         1.0 / (cyc.size() + gu - gv + dep[u] + dep[v] + 1) +
         1.0 / (cyc.size() + dep[u] + dep[v] + 1);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < (int)(n); i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  gen_info();
  double ans;
  for (int i = 0; i < (int)(n); i++)
    for (int j = 0; j < (int)(i + 1); j++) ans += get_cost(i, j);
  printf("%.8lf\n", ans);
  return 0;
}
