#include<bits/stdc++.h>
using namespace std;
#define FZ(n) memset((n),0,sizeof(n))
#define FMO(n) memset((n),-1,sizeof(n))
#define MC(n,m) memcpy((n),(m),sizeof(n))
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define ALL(x) begin(x),end(x)
#define IOS do { ios_base::sync_with_stdio(0);cin.tie(0); } while (0)
#define SZ(x) ((int)(x).size())
#ifndef OFFLINE
    #define ONLINE_JUDGE
#endif
#ifdef ONLINE_JUDGE
#define FILEIO(name) \
    do { \
        freopen(name".in", "r", stdin); \
        freopen(name".out", "w", stdout); \
    } while (0)
#else
    #define FILEIO(name) do { } while(0)
#endif

#define _TOKEN_CAT2(x, y) x ## y
#define _TOKEN_CAT(x, y) _TOKEN_CAT2(x, y)
#define _MACRO_OVERL3(_1, _2, _3, _N, ...) _N
#define _RANGE1(a) int _TOKEN_CAT(_t, __LINE__)=0; _TOKEN_CAT(_t, __LINE__)<(a); (_TOKEN_CAT(_t, __LINE__))++
#define _RANGE2(i, a) int (i)=0; (i)<(a); (i)++
#define _RANGE3(i, a, b) int (i)=(a); (i)!=(b); (i)+=((b)>(a)?1:-1)
#define loop(...) for (_MACRO_OVERL3(__VA_ARGS__, _RANGE3, _RANGE2, _RANGE1)(__VA_ARGS__))

#ifdef OFFLINE
template<typename T>
void _dump(const char* s, T&& head) {
    cerr << s << " = " << head << " <<" << endl;
}

template<typename T, typename... Args>
void _dump(const char* s, T&& head, Args&&... tail) {
    int c = 0;
    while (*s!=',' || c!=0) {
        if (*s=='(' || *s=='[' || *s=='{' || *s=='<') c++;
        if (*s==')' || *s==']' || *s=='}' || *s=='>') c--;
        cerr << *s++;
    }
    cerr << " = " << head << ", ";
    _dump(s+1, tail...);
}

#define dump(...) do { \
    cerr << "\033[32m>> " << __LINE__ << ": " << __PRETTY_FUNCTION__ << endl; \
    cout << "   "; \
    _dump(#__VA_ARGS__, __VA_ARGS__); \
    cout << "\033[0m"; \
} while (0)
#else
#define dump(...)
#endif

#define au auto
template<class T>
using vec = vector<T>;

template<typename Iter>
ostream& _IterOutput_(ostream &o, Iter b, Iter e, const string ss="", const string se="") {
    o << ss;
    for (auto it=b; it!=e; it++) o << (it==b ? "" : ", ") << *it;
    return o << se;
}

template<typename T1, typename T2>
ostream& operator << (ostream &o, const pair<T1, T2> &pair) {
    return o << "(" << pair.F << ", " << pair.S << ")";
}

template<typename T>
ostream& operator << (ostream &o, const vector<T> &vec) {
    return _IterOutput_(o, ALL(vec), "[", "]");
}

template<typename T>
ostream& operator << (ostream &o, const set<T> &st) {
    return _IterOutput_(o, ALL(st), "{", "}");
}

template<typename T, size_t N>
ostream& operator << (ostream &o, const array<T, N> &arr) {
    return _IterOutput_(o, ALL(arr), "|", "|");
}

template<typename T1, typename T2>
ostream& operator << (ostream &o, const map<T1, T2> &mp) {
    o << "{";
    for (auto it=mp.begin(); it!=mp.end(); it++) {
        o << (it==mp.begin()?"":", ") << it->F << ":" << it->S;
    }
    o << "}";
    return o;
}

const int MX = 5555;
int N;
vector<int> el[MX];

bool ins[MX];
stack<int> st;
vector<int> lop;
bool dfs(int u, int fa) {
    ins[u] = 1;
    st.push(u);
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (ins[v]) {
            int w;
            do {
                w = st.top(); st.pop();
                lop.PB(w);
            } while (w != v);
            return 1;
        }
        if (dfs(v, u)) return 1;
    }
    return 0;
}

bool islop[MX];
int lopId[MX];
int fath[MX];
vector<int> lopCh[MX];

double ans;

void dfs2(int u, int fa, int d, int id) {
    lopCh[id].PB(d);
    fath[u] = id;
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (islop[v]) continue;
        dfs2(v, u, d+1, id);
    }
}

void dfs3(int u, int fa, int d) {
    ans += 1.0 / d;
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (islop[v]) {
            if (v == fath[u]) ans += 1.0 / (d+1);
            continue;
        }
        dfs3(v, u, d+1);
    }
}

int32_t main() {
    IOS;
    cin >> N;
    for (int i=0; i<N; i++) {
        int u, v; cin >> u >> v;
        el[u].PB(v);
        el[v].PB(u);
    }

    dfs(0, -1);

    assert(SZ(lop));
    int lll = 0;
    for (auto v: lop) {
        islop[v] = 1;
        lopId[v] = ++lll;
    }

    for (auto v: lop) {
        dfs2(v, -1, 1, v);
    }

    for (int i=0; i<N; i++){
        dfs3(i, -1, 1);
    }

    for (auto u: lop) {
        for (auto v: lop) {
            if (u == v) continue;
            int d1 = abs(lopId[u] - lopId[v]), d2 = lll - d1;
            d1--;
            d2--;

            for (auto x: lopCh[u]) {
                for (auto y: lopCh[v]) {
                    ans += 1.0 / (x+y+d1);
                    ans += 1.0 / (x+y+d2);
                    ans -= 1.0 / (x+y+d1+d2);
                }
            }
        }
    }

    cout << fixed << setprecision(10) << ans << endl;

    return 0;
}

// ntuj - 6t6y23n5rp3u8wdk46nzm


#include<bits/stdc++.h>
using namespace std;
#define FZ(n) memset((n),0,sizeof(n))
#define FMO(n) memset((n),-1,sizeof(n))
#define MC(n,m) memcpy((n),(m),sizeof(n))
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define ALL(x) begin(x),end(x)
#define IOS do { ios_base::sync_with_stdio(0);cin.tie(0); } while (0)
#define SZ(x) ((int)(x).size())
#ifndef OFFLINE
    #define ONLINE_JUDGE
#endif
#ifdef ONLINE_JUDGE
#define FILEIO(name) \
    do { \
        freopen(name".in", "r", stdin); \
        freopen(name".out", "w", stdout); \
    } while (0)
#else
    #define FILEIO(name) do { } while(0)
#endif

#define _TOKEN_CAT2(x, y) x ## y
#define _TOKEN_CAT(x, y) _TOKEN_CAT2(x, y)
#define _MACRO_OVERL3(_1, _2, _3, _N, ...) _N
#define _RANGE1(a) int _TOKEN_CAT(_t, __LINE__)=0; _TOKEN_CAT(_t, __LINE__)<(a); (_TOKEN_CAT(_t, __LINE__))++
#define _RANGE2(i, a) int (i)=0; (i)<(a); (i)++
#define _RANGE3(i, a, b) int (i)=(a); (i)!=(b); (i)+=((b)>(a)?1:-1)
#define loop(...) for (_MACRO_OVERL3(__VA_ARGS__, _RANGE3, _RANGE2, _RANGE1)(__VA_ARGS__))

#ifdef OFFLINE
template<typename T>
void _dump(const char* s, T&& head) {
    cerr << s << " = " << head << " <<" << endl;
}

template<typename T, typename... Args>
void _dump(const char* s, T&& head, Args&&... tail) {
    int c = 0;
    while (*s!=',' || c!=0) {
        if (*s=='(' || *s=='[' || *s=='{' || *s=='<') c++;
        if (*s==')' || *s==']' || *s=='}' || *s=='>') c--;
        cerr << *s++;
    }
    cerr << " = " << head << ", ";
    _dump(s+1, tail...);
}

#define dump(...) do { \
    cerr << "\033[32m>> " << __LINE__ << ": " << __PRETTY_FUNCTION__ << endl; \
    cout << "   "; \
    _dump(#__VA_ARGS__, __VA_ARGS__); \
    cout << "\033[0m"; \
} while (0)
#else
#define dump(...)
#endif

#define au auto
template<class T>
using vec = vector<T>;

template<typename Iter>
ostream& _IterOutput_(ostream &o, Iter b, Iter e, const string ss="", const string se="") {
    o << ss;
    for (auto it=b; it!=e; it++) o << (it==b ? "" : ", ") << *it;
    return o << se;
}

template<typename T1, typename T2>
ostream& operator << (ostream &o, const pair<T1, T2> &pair) {
    return o << "(" << pair.F << ", " << pair.S << ")";
}

template<typename T>
ostream& operator << (ostream &o, const vector<T> &vec) {
    return _IterOutput_(o, ALL(vec), "[", "]");
}

template<typename T>
ostream& operator << (ostream &o, const set<T> &st) {
    return _IterOutput_(o, ALL(st), "{", "}");
}

template<typename T, size_t N>
ostream& operator << (ostream &o, const array<T, N> &arr) {
    return _IterOutput_(o, ALL(arr), "|", "|");
}

template<typename T1, typename T2>
ostream& operator << (ostream &o, const map<T1, T2> &mp) {
    o << "{";
    for (auto it=mp.begin(); it!=mp.end(); it++) {
        o << (it==mp.begin()?"":", ") << it->F << ":" << it->S;
    }
    o << "}";
    return o;
}

const int MX = 5555;
int N;
vector<int> el[MX];

bool ins[MX];
stack<int> st;
vector<int> lop;
bool dfs(int u, int fa) {
    ins[u] = 1;
    st.push(u);
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (ins[v]) {
            int w;
            do {
                w = st.top(); st.pop();
                lop.PB(w);
            } while (w != v);
            return 1;
        }
        if (dfs(v, u)) return 1;
    }
    return 0;
}

bool islop[MX];
int lopId[MX];
int fath[MX];
vector<int> lopCh[MX];

double ans;

void dfs2(int u, int fa, int d, int id) {
    lopCh[id].PB(d);
    fath[u] = id;
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (islop[v]) continue;
        dfs2(v, u, d+1, id);
    }
}

void dfs3(int u, int fa, int d) {
    ans += 1.0 / d;
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (islop[v] && v != fath[u]) {
            continue;
        }
        dfs3(v, u, d+1);
    }
}

int32_t main() {
    IOS;
    cin >> N;
    for (int i=0; i<N; i++) {
        int u, v; cin >> u >> v;
        el[u].PB(v);
        el[v].PB(u);
    }

    dfs(0, -1);

    assert(SZ(lop));
    int lll = 0;
    for (auto v: lop) {
        islop[v] = 1;
        lopId[v] = ++lll;
    }

    for (auto v: lop) {
        dfs2(v, -1, 1, v);
    }

    for (int i=0; i<N; i++){
        dfs3(i, -1, 1);
    }

    for (auto u: lop) {
        for (auto v: lop) {
            if (u == v) continue;
            int d1 = abs(lopId[u] - lopId[v]), d2 = lll - d1;
            d1--;
            d2--;

            for (auto x: lopCh[u]) {
                for (auto y: lopCh[v]) {
                    ans += 1.0 / (x+y+d1);
                    ans += 1.0 / (x+y+d2);
                    ans -= 1.0 / (x+y+d1+d2);
                }
            }
        }
    }

    cout << fixed << setprecision(10) << ans << endl;

    return 0;
}

// ntuj - bvo06ywud3cc0qaq56hhd


//bcw0x1bd2 {{{
#include<bits/stdc++.h>
#include<unistd.h>
using namespace std;
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define SZ(x) ((int)((x).size()))
#define ALL(x) begin(x),end(x)
#define REP(i,x) for (int i=0; i<(x); i++)
#define REP1(i,a,b) for (int i=(a); i<=(b); i++)

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;

#ifdef DARKHH
#define FILEIO(name)
#else
#define FILEIO(name) \
  freopen(name".in", "r", stdin); \
  freopen(name".out", "w", stdout);
#endif

#ifdef DARKHH
template<typename T>
void _dump( const char* s, T&& head ) { cerr<<s<<"="<<head<<endl; }

template<typename T, typename... Args>
void _dump( const char* s, T&& head, Args&&... tail ) {
  int c=0;
  while ( *s!=',' || c!=0 ) {
    if ( *s=='(' || *s=='[' || *s=='{' ) c++;
    if ( *s==')' || *s==']' || *s=='}' ) c--;
    cerr<<*s++;
  }
  cerr<<"="<<head<<", ";
  _dump(s+1,tail...);
}

#define dump(...) do { \
  fprintf(stderr, "%s:%d - ", __PRETTY_FUNCTION__, __LINE__); \
  _dump(#__VA_ARGS__, __VA_ARGS__); \
} while (0)

template<typename Iter>
ostream& _out( ostream &s, Iter b, Iter e ) {
  s<<"[";
  for ( auto it=b; it!=e; it++ ) s<<(it==b?"":" ")<<*it;
  s<<"]";
  return s;
}

template<typename A, typename B>
ostream& operator <<( ostream &s, const pair<A,B> &p ) { return s<<"("<<p.first<<","<<p.second<<")"; }
template<typename T>
ostream& operator <<( ostream &s, const vector<T> &c ) { return _out(s,ALL(c)); }
template<typename T, size_t N>
ostream& operator <<( ostream &s, const array<T,N> &c ) { return _out(s,ALL(c)); }
template<typename T>
ostream& operator <<( ostream &s, const set<T> &c ) { return _out(s,ALL(c)); }
template<typename A, typename B>
ostream& operator <<( ostream &s, const map<A,B> &c ) { return _out(s,ALL(c)); }
#else
#define dump(...)
#endif
// }}}
// Let's Fight! ~OAO~~

const int MXN = 100005;

int N,loid[MXN],islolo[MXN];
int bln[MXN],dep[MXN];
vector<int> E[MXN];
vector<int> lolo;

int ins[MXN];
vector<int> stk;
ld ans;

bool DFS1(int u, int f) {
  ins[u] = 1;
  stk.PB(u);
  for (auto v:E[u]) {
    if (v == f) continue;
    if (ins[v]) {
      while (stk.back() != v) {
        lolo.PB(stk.back());
        stk.pop_back();
      }
      lolo.PB(v);
      return 1;
    }
    if (DFS1(v,u)) return 1;
  }

  ins[u] = 0;
  stk.pop_back();
  return 0;
}
void DFS(int u, int f, int d, int bid) {
  dep[u] = d;
  bln[u] = bid;
  for (auto v:E[u]) {
    if (v == f) continue;
    if (islolo[v]) continue;
    DFS(v,u,d+1,bid);
  }
}
void calc(int u, int f, int d) {
  ans += 1.0/d;
  for (auto v:E[u]) {
    if (v == f) continue;
    if (islolo[v] and bln[u] != v) continue;
    calc(v,u,d+1);
  }
}
int main() {
  IOS;
  cin >> N;
  REP(i,N) {
    int u,v;
    cin >> u >> v;
    E[u].PB(v);
    E[v].PB(u);
  }
  // find lolo
  DFS1(0, 0);
  REP(i,SZ(lolo)) {
    int v = lolo[i];
    loid[v] = i;
    islolo[v] = 1;
  }

  for (auto v:lolo) DFS(v,v,1,v);

  ans = 0;
  REP(i,N) calc(i,i,1);

  REP(i,N) REP(j,N) {
    if (i == j) continue;
    if (bln[i] == bln[j]) continue;
    int d1 = abs(loid[bln[i]]-loid[bln[j]]);
    int d2 = SZ(lolo) - d1;
    d1--;
    d2--;
    ans += 1.0 / (dep[i]+dep[j]+d1);
    ans += 1.0 / (dep[i]+dep[j]+d2);
    ans -= 1.0 / (dep[i]+dep[j]+d1+d2);
  }
  cout << fixed << setprecision(10) << ans << endl;

  return 0;
}

// ntuj - 6n1i9gi3jpp5hsi1pdi8g


//bcw0x1bd2 {{{
#include<bits/stdc++.h>
#include<unistd.h>
using namespace std;
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define SZ(x) ((int)((x).size()))
#define ALL(x) begin(x),end(x)
#define REP(i,x) for (int i=0; i<(x); i++)
#define REP1(i,a,b) for (int i=(a); i<=(b); i++)

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;

#ifdef DARKHH
#define FILEIO(name)
#else
#define FILEIO(name) \
  freopen(name".in", "r", stdin); \
  freopen(name".out", "w", stdout);
#endif

#ifdef DARKHH
template<typename T>
void _dump( const char* s, T&& head ) { cerr<<s<<"="<<head<<endl; }

template<typename T, typename... Args>
void _dump( const char* s, T&& head, Args&&... tail ) {
  int c=0;
  while ( *s!=',' || c!=0 ) {
    if ( *s=='(' || *s=='[' || *s=='{' ) c++;
    if ( *s==')' || *s==']' || *s=='}' ) c--;
    cerr<<*s++;
  }
  cerr<<"="<<head<<", ";
  _dump(s+1,tail...);
}

#define dump(...) do { \
  fprintf(stderr, "%s:%d - ", __PRETTY_FUNCTION__, __LINE__); \
  _dump(#__VA_ARGS__, __VA_ARGS__); \
} while (0)

template<typename Iter>
ostream& _out( ostream &s, Iter b, Iter e ) {
  s<<"[";
  for ( auto it=b; it!=e; it++ ) s<<(it==b?"":" ")<<*it;
  s<<"]";
  return s;
}

template<typename A, typename B>
ostream& operator <<( ostream &s, const pair<A,B> &p ) { return s<<"("<<p.first<<","<<p.second<<")"; }
template<typename T>
ostream& operator <<( ostream &s, const vector<T> &c ) { return _out(s,ALL(c)); }
template<typename T, size_t N>
ostream& operator <<( ostream &s, const array<T,N> &c ) { return _out(s,ALL(c)); }
template<typename T>
ostream& operator <<( ostream &s, const set<T> &c ) { return _out(s,ALL(c)); }
template<typename A, typename B>
ostream& operator <<( ostream &s, const map<A,B> &c ) { return _out(s,ALL(c)); }
#else
#define dump(...)
#endif
// }}}
// Let's Fight! ~OAO~~

const int MXN = 100005;

int N,loid[MXN],islolo[MXN];
int bln[MXN],dep[MXN];
vector<int> E[MXN];
vector<int> lolo;

int ins[MXN];
vector<int> stk;
ld ans;

bool DFS1(int u, int f) {
  ins[u] = 1;
  stk.PB(u);
  for (auto v:E[u]) {
    if (v == f) continue;
    if (ins[v]) {
      while (stk.back() != v) {
        lolo.PB(stk.back());
        stk.pop_back();
      }
      lolo.PB(v);
      return 1;
    }
    if (DFS1(v,u)) return 1;
  }

  ins[u] = 0;
  stk.pop_back();
  return 0;
}
void DFS(int u, int f, int d, int bid) {
  dep[u] = d;
  bln[u] = bid;
  for (auto v:E[u]) {
    if (v == f) continue;
    if (islolo[v]) continue;
    DFS(v,u,d+1,bid);
  }
}
void calc(int u, int f, int d) {
  ans += 1.0/d;
  for (auto v:E[u]) {
    if (v == f) continue;
    if (islolo[v] and bln[u] != v) continue;
    calc(v,u,d+1);
  }
}
int main() {
  IOS;
  cin >> N;
  REP(i,N) {
    int u,v;
    cin >> u >> v;
    E[u].PB(v);
    E[v].PB(u);
  }
  // find lolo
  DFS1(0, 0);
  REP(i,SZ(lolo)) {
    int v = lolo[i];
    loid[v] = i;
    islolo[v] = 1;
  }

  for (auto v:lolo) DFS(v,v,1,v);

  ans = 0;
  REP(i,N) calc(i,i,1);

  REP(i,N) REP(j,N) {
    if (i == j) continue;
    if (bln[i] == bln[j]) continue;
    int d1 = abs(loid[bln[i]]-loid[bln[j]]);
    int d2 = SZ(lolo) - d1;
    d1--;
    d2--;
    ans += 1.0 / (dep[i]+dep[j]+d1);
    ans += 1.0 / (dep[i]+dep[j]+d2);
    ans -= 1.0 / (dep[i]+dep[j]+d1+d2);
  }
  cout << fixed << setprecision(10) << ans << endl;

  return 0;
}

// ntuj - eatsqwzg88w3dnwe5kzxt


#include <bits/stdc++.h>
using namespace std;
const int N=3005;
int n,tot,fst[N],to[2*N],nxt[2*N],cir[N],pos[N],len,dep[N],fa[N],subt[N];
bool vis[N];
void addedge(int u,int v) {
	nxt[++tot]=fst[u];fst[u]=tot;to[tot]=v;
	nxt[++tot]=fst[v];fst[v]=tot;to[tot]=u;
}
void fnd(int u) {
	if (len) return;
	vis[u]=true;
	for (int i=fst[u];i&&!len;i=nxt[i])
		if (to[i]!=fa[u]) {
			if (vis[to[i]]) {
				for (int j=u;j!=to[i];j=fa[j]) cir[++len]=j,pos[j]=len;
				cir[++len]=to[i],pos[to[i]]=len;
				return;
			}
			fa[to[i]]=u;
			fnd(to[i]);
		}
}
void dfs(int u) {
	for (int i=fst[u];i;i=nxt[i])
		if (to[i]!=fa[u]&&!pos[to[i]]) {
			fa[to[i]]=u;
			dep[to[i]]=dep[u]+1;
			subt[to[i]]=subt[u];
			dfs(to[i]);
		}
}
int main() {
	scanf("%d",&n);
	for (int i=1,u,v;i<=n;i++) {
		scanf("%d%d",&u,&v);
		addedge(u+1,v+1);
	}
	fnd(1);
	for (int i=1;i<=len;i++) {
		fa[cir[i]]=0;
		dep[cir[i]]=0;
		subt[cir[i]]=i;
		dfs(cir[i]);
	}
	double ans=0;
	for (int u=1;u<=n;u++)
		for (int v=1;v<=n;v++) {
			if (subt[u]==subt[v]) ans+=1.0/(abs(dep[u]-dep[v])+1);
			else {
				int A=dep[u]+dep[v]+abs(subt[u]-subt[v])+1,B=dep[u]+dep[v]+len-abs(subt[u]-subt[v])+1,C=dep[u]+dep[v]+len;
				ans+=1.0/A+1.0/B-1.0/C;
			}
		}
	printf("%.10f\n",ans);
}


#include <bits/stdc++.h>
using namespace std;
const int N=3005;
int n,tot,fst[N],to[2*N],nxt[2*N],cir[N],pos[N],len,dep[N],fa[N],subt[N],st[N],top,dis[N];
bool vis[N];
void addedge(int u,int v) {
	nxt[++tot]=fst[u];fst[u]=tot;to[tot]=v;
	nxt[++tot]=fst[v];fst[v]=tot;to[tot]=u;
}
void fnd(int u) {
	if (len) return;
	vis[u]=true;
	for (int i=fst[u];i&&!len;i=nxt[i])
		if (to[i]!=fa[u]) {
			if (vis[to[i]]) {
				for (int j=u;j!=to[i];j=fa[j]) cir[++len]=j,pos[j]=len;
				cir[++len]=to[i],pos[to[i]]=len;
				return;
			}
			fa[to[i]]=u;
			fnd(to[i]);
		}
}
void dfs(int u) {
	st[++top]=u;
	for (int i=fst[u];i;i=nxt[i])
		if (to[i]!=fa[u]&&!pos[to[i]]) {
			fa[to[i]]=u;
			dep[to[i]]=dep[u]+1;
			subt[to[i]]=subt[u];
			dfs(to[i]);
		}
}
int main() {
	scanf("%d",&n);
	for (int i=1,u,v;i<=n;i++) {
		scanf("%d%d",&u,&v);
		addedge(u+1,v+1);
	}
	fnd(1);
	double ans=0;
	for (int i=1;i<=len;i++) {
		fa[cir[i]]=dep[cir[i]]=0;
		subt[cir[i]]=i;
		top=0;
		dfs(cir[i]);
		for (int j=1;j<=top;j++) {
			for (int k=1;k<=top;k++) vis[st[k]]=false;
			static int q[N];
			int h=0,t=0;
			q[t++]=st[j];
			dis[q[0]]=1;
			vis[q[0]]=true;
			while (h<t) {
				int u=q[h++];
				ans+=1.0/dis[u];
				for (int k=fst[u];k;k=nxt[k])
					if (!vis[to[k]]&&(to[k]==cir[i]||!pos[to[k]])) {
						q[t++]=to[k];
						vis[to[k]]=true;
						dis[to[k]]=dis[u]+1;
					}
			}
		}
	}
	for (int u=1;u<=n;u++)
		for (int v=1;v<=n;v++)
			if (subt[u]!=subt[v]) {
				int A=dep[u]+dep[v]+abs(subt[u]-subt[v])+1,B=dep[u]+dep[v]+len-abs(subt[u]-subt[v])+1,C=dep[u]+dep[v]+len;
				ans+=1.0/A+1.0/B-1.0/C;
			}
	printf("%.10f\n",ans);
}


#include <bits/stdc++.h>
using namespace std;
#define N 3030
#define K 14
int n;
vector< int > v[ N ];
void init(){
  scanf( "%d" , &n );
  for( int i = 0 ; i < n ; i ++ ){
    int ai , bi;
    scanf( "%d%d" , &ai , &bi );
    v[ ai ].push_back( bi );
    v[ bi ].push_back( ai );
  }
}
bool oncyc[ N ] , instk[ N ];
int vst[ N ] , p[ N ][ K ] , dep[ N ] , stk[ N ];
int cycsz;
void go( int now , int prt , int tdep ){
  p[ now ][ 0 ] = prt;
  dep[ now ] = tdep;
  stk[ tdep ] = now;
  vst[ now ] = 1;
  instk[ now ] = true;
  for( int son : v[ now ] ){
    if( son == prt ) continue;
    if( vst[ son ] ){
      if( !instk[ son ] ) continue;
      cycsz = tdep - dep[ son ] + 1;
      for( int i = dep[ son ] ; i <= tdep ; i ++ )
        oncyc[ stk[ i ] ] = true;
    }else
      go( son , now , tdep + 1 );
  }
  instk[ now ] = false;
}
int cyc[ N ];
void go2( int now , int prt , int sum ){
  if( oncyc[ now ] ) sum ++;
  cyc[ now ] = sum;
  vst[ now ] = 2;
  for( int son : v[ now ] ){
    if( son == prt || vst[ son ] == 2 )
      continue;
    go2( son , now , sum );
  }
}
void build_pp(){
  for( int i = 1 ; i < K ; i ++ )
    for( int j = 0 ; j < n ; j ++ )
      p[ j ][ i ] = p[ p[ j ][ i - 1 ] ][ i - 1 ];
}
inline int lca( int ui , int vi ){
  if( dep[ ui ] > dep[ vi ] ) swap( ui , vi );
  int dlt = dep[ vi ] - dep[ ui ];
  for( int i = 0 ; i < K ; i ++ )
    if( ( dlt >> i ) & 1 )
      vi = p[ vi ][ i ];
  if( ui == vi ) return ui;
  for( int i = K - 1 ; i >= 0 ; i -- )
    if( p[ ui ][ i ] != p[ vi ][ i ] ){
      ui = p[ ui ][ i ];
      vi = p[ vi ][ i ];
    }
  return p[ ui ][ 0 ];
}
inline double cal( int a , int b ){
  if( a == b ) return 1.0;
  int tlca = lca( a , b );
  int bet = dep[ b ] + dep[ a ] - 2 * dep[ tlca ] + 1;
  int cnt = cyc[ b ] + cyc[ a ] - 2 * cyc[ tlca ] + oncyc[ tlca ];
  if( cnt <= 1 ) return 1.0 / (double)bet;
  bet -= cnt;
  int p1 = cnt , p2 = cycsz - cnt + 2;
  // printf( "%d<->%d bet: %d, p1: %d p2: %d cycsz: %d\n" , a , b , bet , p1 , p2 , cycsz );
  return 1.0 / (double)( bet + p1 ) +
         1.0 / (double)( bet + p2 ) -
         1.0 / (double)( bet + cycsz );
}
void solve(){
  go( 0 , 0 , 0 );
  go2( 0 , 0 , 0 );
  build_pp();
  double ans = 0.0;
  for( int i = 0 ; i < n ; i ++ )
    for( int j = 0 ; j < n ; j ++ )
      ans += cal( i , j );
  printf( "%.9f\n" , ans );
}
int main(){
  init();
  solve();
}


#include<bits/stdc++.h>

#define x first
#define y second
#define pb push_back

using namespace std;

typedef long long INT;
typedef vector<int> VI;
typedef pair<int, int> pii;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

template <class T> inline void gn(T &x) {char c, sg=0; while(c=getchar(), (c>'9' || c<'0') && c!='-'); for((c=='-' ? sg=1, c=getchar() : 0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0'; if(sg) x=-x;}
template <class T1, class T2> inline void gn(T1 &x1, T2 &x2) {gn(x1), gn(x2);}
int power(int a, int b, int m, int ans=1){for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m; return ans;}

#define NN 3030
VI adj[NN];
int vst[NN], fa[NN];
int flag[NN];
int id[NN];

int dfs(int u){
	vst[u]=1;
	for(int v : adj[u]){
		if(v==fa[u]) continue;
		if(vst[v]){
			int len=0;
			while(u!=v){
				flag[u]=++len;
				id[len]=u;
				u=fa[u];
			}
			flag[u]=++len;
			id[len]=u;
			return len;
		}
		fa[v]=u;
		int res=dfs(v);
		if(res) return res;
	}
	return 0;
}

int top[NN], dep[NN];
void dfs(int u, int root, int f=-1){
	top[u]=root;
	for(int v : adj[u]){
		if(v==f || flag[v]) continue;
		dep[v]=dep[u]+1;
		dfs(v, root, u);
	}
}

int dp[NN];
void dfs1(int u, int f=-1){
	for(int v : adj[u]){
		if(v==f || flag[v]) continue;
		dp[v]=dp[u]+1;
		dfs1(v, u);
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	int n;
	cin >> n;
	for(int i=0; i<n; i++){
		int u, v;
		gn(u, v);
		adj[u].pb(v);
		adj[v].pb(u);
	}

	int len=dfs(0);
	for(int i=1; i<=len; i++) dfs(id[i], id[i]);

	double ans=0;
	for(int i=0; i<n; i++){
		int tmp=flag[top[i]];
		flag[top[i]]=0;
		dp[i]=0; dfs1(i);
		flag[top[i]]=tmp;
		for(int j=0; j<n; j++){
			if(top[i]==top[j]){
				ans+=1.0/(dp[j]+1);
				continue;
			}
			int a=dep[i]+dep[j]+2;
			int b=abs(flag[top[i]]-flag[top[j]])-1;
			int c=len-b-2;
			ans+=1.0/(a+b)+1.0/(a+c)-1.0/(a+b+c);
		}
	}

	printf("%.15lf\n", ans);

	return 0;
}


#include<bits/stdc++.h>

#define x first
#define y second
#define pb push_back

using namespace std;

typedef long long INT;
typedef vector<int> VI;
typedef pair<int, int> pii;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

template <class T> inline void gn(T &x) {char c, sg=0; while(c=getchar(), (c>'9' || c<'0') && c!='-'); for((c=='-' ? sg=1, c=getchar() : 0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0'; if(sg) x=-x;}
template <class T1, class T2> inline void gn(T1 &x1, T2 &x2) {gn(x1), gn(x2);}
int power(int a, int b, int m, int ans=1){for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m; return ans;}

#define NN 3030
VI adj[NN];
int vst[NN], fa[NN];
int flag[NN];
int id[NN];

int dfs(int u){
	vst[u]=1;
	for(int v : adj[u]){
		if(v==fa[u]) continue;
		if(vst[v]){
			int len=0;
			while(u!=v){
				flag[u]=++len;
				id[len]=u;
				u=fa[u];
			}
			flag[v]=++len;
			id[len]=v;
			return len;
		}
		fa[v]=u;
		int res=dfs(v);
		if(res) return res;
	}
	return 0;
}

int top[NN], dep[NN];
void dfs(int u, int root, int f=-1){
	top[u]=root;
	for(int v : adj[u]){
		if(v==f || flag[v]) continue;
		dep[v]=dep[u]+1;
		dfs(v, root, u);
	}
}

int dp[NN];
void dfs1(int u, int f=-1){
	for(int v : adj[u]){
		if(v==f || flag[v]) continue;
		dp[v]=dp[u]+1;
		dfs1(v, u);
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	int n;
	cin >> n;
	for(int i=0; i<n; i++){
		int u, v;
		gn(u, v);
		adj[u].pb(v);
		adj[v].pb(u);
	}

	int len=dfs(1);
	for(int i=1; i<=len; i++) dfs(id[i], id[i]);

	double ans=0;
	for(int i=0; i<n; i++){
		dp[i]=0; dfs1(i);
		for(int j=0; j<n; j++) if(i!=j){
			if(top[i]==top[j]){
				if(j==top[i]) ans+=1.0/(dep[i]+1);
				else ans+=1.0/(dp[j]+1);
				continue;
			}
			int a=dep[i]+dep[j]+2;
			int b=abs(flag[top[i]]-flag[top[j]])-1;
			int c=len-b-2;
			ans+=1.0/(a+b)+1.0/(a+c)-1.0/(a+b+c);
		}
	}

	printf("%.15lf\n", ans+n);

	return 0;
}


#include<bits/stdc++.h>

#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fLL
#define mod 1000000007
#define pb push_back
#define sq(x) ((x)*(x))
#define sz(a) ((int)a.size())
#define eps 1e-8
#define x first
#define y second
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define bit(x, y) (((x)>>(y))&1)
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) ((x) ? (__builtin_clzll(x)) : 0)
#define bctz(x) (__builtin_ctz(x))
#define bctzl(x) (__builtin_ctzll(x))
#define shit(a) (1 << (a))
#define rev(a) (power(a, mod-2, mod))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> ppi;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, U b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, U b) {if(a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}
template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}
template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}
template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
int power(int a, int b, int m, int ans=1) {
	for(; b; b>>=1, a=1LL*a*a%m) if(b&1) ans=1LL*ans*a%m;
	return ans;
}

#define NN 3333
VI adj[NN];
int n;
int deg[NN];
int col[NN];
int rc;
int q[NN], qf, qb;
int deep[NN];
int dst[NN][NN];

void dfs(int u, int fa=0) {
	deep[u] = deep[fa] + 1;
	for(int v : adj[u]) {
		if(v == fa) continue;
		if(col[v] >= 0) continue;
		col[v] = col[u];
		dfs(v, u);
	}
}

void ser(int u, int fa, int root) {
	for(int v : adj[u]) {
		if(v == fa or col[u] != col[v]) continue;
		dst[root][v] = dst[root][u] + 1;
		ser(v, u, root);
	}
}
DO ans;

void calc(int u, int v) {
	if(col[u] == col[v]) {
		ans += 1.0/(dst[u][v] + 1);
		return ;
	}
	int X=deep[u] + deep[v];
	int Y=abs(col[u]-col[v])-1;
	int Z=rc-Y-2;
	ans += 1.0/(X+Y)+1.0/(X+Z)-1.0/(X+Y+Z);
}

void solve() {
	cin >> n;
	for(int i=0; i<n; i++) {
		int u, v; gn(u); gn(v);
		u++; v++;
		adj[u].pb(v);
		adj[v].pb(u);
		deg[u]++; deg[v]++;
	}
	for(int i=1; i<=n; i++) if(deg[i] == 1) q[qb++] = i;
	while(qb > qf) {
		int u = q[qf++];
		col[u] = -1;
		for(int v : adj[u]) {
			deg[v]--;
			if(deg[v]==1) q[qb++] = v;
		}
	}
	for(int i=1; i<=n; i++) if(col[i]==0) col[i]=++rc, dfs(i);
	for(int i=1; i<=n; i++) {
		ser(i, 0, i);
		for(int j=1; j<=n; j++) {
			calc(i, j);
		}
	}
	printf("%.10lf\n", ans);
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	solve();

	return 0;
}


#include<bits/stdc++.h>

#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fLL
#define mod 1000000007
#define pb push_back
#define sq(x) ((x)*(x))
#define sz(a) ((int)a.size())
#define eps 1e-8
#define x first
#define y second
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define bit(x, y) (((x)>>(y))&1)
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) ((x) ? (__builtin_clzll(x)) : 0)
#define bctz(x) (__builtin_ctz(x))
#define bctzl(x) (__builtin_ctzll(x))
#define shit(a) (1 << (a))
#define rev(a) (power(a, mod-2, mod))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> ppi;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, U b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, U b) {if(a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}
template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}
template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}
template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
int power(int a, int b, int m, int ans=1) {
	for(; b; b>>=1, a=1LL*a*a%m) if(b&1) ans=1LL*ans*a%m;
	return ans;
}

#define NN 3333
VI adj[NN];
int n;
int deg[NN];
int col[NN];
int rc;
int q[NN], qf, qb;
int deep[NN];

void dfs(int u, int fa=0) {
	deep[u] = deep[fa] + 1;
	for(int v : adj[u]) {
		if(v == fa) continue;
		if(col[v] >= 0) continue;
		col[v] = col[u];
		dfs(v, u);
	}
}

DO ans;

void calc(int u, int v) {
	if(col[u] == col[v]) {
		ans += 1.0/(abs(deep[u]-deep[v])+1);
		return ;
	}
	int X=deep[u] + deep[v];
	int Y=abs(col[u]-col[v])-1;
	int Z=rc-Y-2;
	ans += 1.0/(X+Y)+1.0/(X+Z)-1.0/(X+Y+Z);
}

void solve() {
	cin >> n;
	for(int i=0; i<n; i++) {
		int u, v; gn(u); gn(v);
		u++; v++;
		adj[u].pb(v);
		adj[v].pb(u);
		deg[u]++; deg[v]++;
	}
	for(int i=1; i<=n; i++) if(deg[i] == 1) q[qb++] = i;
	while(qb > qf) {
		int u = q[qf++];
		col[u] = -1;
		for(int v : adj[u]) {
			deg[v]--;
			if(deg[v]==1) q[qb++] = v;
		}
	}
	for(int i=1; i<=n; i++) if(col[i]==0) col[i]=++rc;
	for(int i=1; i<=n; i++) if(~col[i]) dfs(i);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			calc(i, j);
		}
	}
	printf("%.10lf\n", ans);
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	solve();

	return 0;
}


#include<bits/stdc++.h>

#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fLL
#define mod 1000000007
#define pb push_back
#define sq(x) ((x)*(x))
#define sz(a) ((int)a.size())
#define eps 1e-8
#define x first
#define y second
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define bit(x, y) (((x)>>(y))&1)
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) ((x) ? (__builtin_clzll(x)) : 0)
#define bctz(x) (__builtin_ctz(x))
#define bctzl(x) (__builtin_ctzll(x))
#define shit(a) (1 << (a))
#define rev(a) (power(a, mod-2, mod))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> ppi;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, U b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, U b) {if(a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}
template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}
template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}
template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
int power(int a, int b, int m, int ans=1) {
	for(; b; b>>=1, a=1LL*a*a%m) if(b&1) ans=1LL*ans*a%m;
	return ans;
}

#define NN 3333
VI adj[NN];
int n;
int deg[NN];
int col[NN];
int rc;
int q[NN], qf, qb;
int deep[NN];

void dfs(int u, int fa=0) {
	deep[u] = deep[fa] + 1;
//	cerr<<u<<endl;
	for(int v : adj[u]) {
		if(v == fa) continue;
		if(col[v] >= 0) continue;
		col[v] = col[u];
		dfs(v, u);
	}
}

DO ans;

void calc(int u, int v) {
	if(col[u] == col[v]) {
		ans += 1.0/(abs(deep[u]-deep[v])+1);
		return ;
	}
	int X=deep[u] + deep[v];
	int Y=abs(col[u]-col[v])-1;
	int Z=rc-Y-2;
	ans += 1.0/(X+Y)+1.0/(X+Z)-1.0/(X+Y+Z);
}

void solve() {
	cin >> n;
	for(int i=0; i<n; i++) {
		int u, v; gn(u); gn(v);
		u++; v++;
		adj[u].pb(v);
		adj[v].pb(u);
		deg[u]++; deg[v]++;
	}
	for(int i=1; i<=n; i++) if(deg[i] == 1) q[qb++] = i;
	while(qb > qf) {
		int u = q[qf++];
		col[u] = -1;
		for(int v : adj[u]) {
			deg[v]--;
			if(deg[v]==1) q[qb++] = v;
		}
	}
	for(int i=1; i<=n; i++) if(col[i]==0) col[i]=++rc, dfs(i);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			calc(i, j);
		}
	}
	printf("%.10lf\n", ans);
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	solve();

	return 0;
}


#include<bits/stdc++.h>

#define x first
#define y second
#define pb push_back

using namespace std;

typedef long long INT;
typedef vector<int> VI;
typedef pair<int, int> pii;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

template <class T> inline void gn(T &x) {char c, sg=0; while(c=getchar(), (c>'9' || c<'0') && c!='-'); for((c=='-' ? sg=1, c=getchar() : 0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0'; if(sg) x=-x;}
template <class T1, class T2> inline void gn(T1 &x1, T2 &x2) {gn(x1), gn(x2);}
int power(int a, int b, int m, int ans=1){for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m; return ans;}

#define NN 3030
VI adj[NN];
int vst[NN], fa[NN];
int flag[NN];
int id[NN];

int dfs(int u){
	vst[u]=1;
	for(int v : adj[u]){
		if(v==fa[u]) continue;
		if(vst[v]){
			int len=0;
			while(u!=v){
				flag[u]=++len;
				id[len]=u;
				u=fa[u];
			}
			flag[u]=++len;
			id[len]=u;
			return len;
		}
		fa[v]=u;
		int res=dfs(v);
		if(res) return res;
	}
	return 0;
}

int top[NN], dep[NN];
void dfs(int u, int root, int f=-1){
	top[u]=root;
	for(int v : adj[u]){
		if(v==f || flag[v]) continue;
		dep[v]=dep[u]+1;
		dfs(v, root, u);
	}
}

int dp[NN];
void dfs1(int u, int f=-1){
	for(int v : adj[u]){
		if(v==f || flag[v]) continue;
		dp[v]=dp[u]+1;
		dfs1(v, u);
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	int n;
	cin >> n;
	for(int i=0; i<n; i++){
		int u, v;
		gn(u, v);
		adj[u].pb(v);
		adj[v].pb(u);
	}

	int len=dfs(0);
	for(int i=1; i<=len; i++) dfs(id[i], id[i]);

	double ans=0;
	for(int i=0; i<n; i++){
		dp[i]=0; dfs1(i);
		for(int j=0; j<n; j++){
			if(top[i]==top[j]){
				if(j==top[i]) ans+=1.0/(dep[i]+1);
				else ans+=1.0/(dp[j]+1);
				continue;
			}
			int a=dep[i]+dep[j]+2;
			int b=abs(flag[top[i]]-flag[top[j]])-1;
			int c=len-b-2;
			ans+=1.0/(a+b)+1.0/(a+c)-1.0/(a+b+c);
		}
	}

	printf("%.15lf\n", ans);

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;

const int N = 3005;
bool flag[N] , v[N];
int n;
int adj[N<<1] , next[N<<1] , g[N] , tot;
int stack[N] , stn , kai;
double ans;

void ins(int x,int y)
{
	adj[++tot]=y; next[tot]=g[x]; g[x]=tot;
}

void find_h(int x,int fa)
{
	v[x] = 0;
	for(int p=g[x];p;p=next[p])
	if (v[adj[p]])
	{
		stack[++stn]=adj[p];
		find_h(adj[p],p);
		if (tot) return;
		stack[stn--]=-1;
	}
	else
	if ((p^1) != fa && stn>0)
		while (stack[stn+1] != adj[p])
		flag[stack[stn--]]=1 , tot++;
}

void Init()
{
	scanf("%d",&n);
	int x,y;
	tot = 1;
	fo(i,1,n)
	{
		scanf("%d%d",&x,&y);
		ins(x,y); ins(y,x);
	}

	ms(stack,255);
	ms(v,1);
	stack[stn=1]=1;
	tot=0;
	find_h(1,0);
}

//x????a???????,c??????
void dfs(int x,int a,int c)
{
	double temp = ans;
	if (x != kai)
	{
		if (tot==2 || c<=1)
		{
			ans += 1 / double(a);
		}
		else
		{
			ans += 1 / double(a);
			ans += 1 / double(a-c+tot-c+2);
			ans -= 1 / double(a+tot-c);
		}
	}
	v[x]=0;
	for(int p=g[x];p;p=next[p])
	if (v[adj[p]])
		if (flag[adj[p]]) dfs(adj[p],a+1,c+1);
		else	dfs(adj[p],a+1,c);

}

void Work()
{
	ans = 0;
	fo(i,0,n-1)
	{
		ans++;
		kai = i;
		ms(v,1);
		if (!flag[i]) dfs(i,1,0);
		else dfs(i,1,1);
	}
	printf("%.11lf\n",ans);
}

int main()
{

	Init();
	Work();

	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define rg register
#define fo(i,a,b) for(rg int i=a;i<=b;i++)
#define fd(i,a,b) for(rg int i=a;i>=b;i--)
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
const int N = 3005;
bool flag[N] , v[N];
int n;
int adj[N<<1] , next[N<<1] , g[N] , tot;
int stack[N] , stn , kai;
double ans;
void ins(int x,int y)
{
	adj[++tot]=y; next[tot]=g[x]; g[x]=tot;
}
void find_h(int x,int fa)
{
	v[x] = 0;
	for(int p=g[x];p;p=next[p])
	if (v[adj[p]])
	{
		stack[++stn]=adj[p];
		find_h(adj[p],p);
		if (tot) return;
		stack[stn--]=-1;
	}
	else
	if ((p^1) != fa && stn>0)
		while (stack[stn+1] != adj[p])
		flag[stack[stn--]]=1 , tot++;
}
void Init()
{
	scanf("%d",&n);
	int x,y;
	tot = 1;
	fo(i,1,n)
	{
		scanf("%d%d",&x,&y);
		ins(x,y); ins(y,x);
	}

	ms(stack,255);
	ms(v,1);
	stack[stn=1]=1;
	tot=0;
	find_h(1,0);
}
void dfs(int x,int a,int c)
{
	double temp = ans;
	if (x != kai)
	{
		if (tot==2 || c<=1)
		{
			ans += 1 / double(a);
		}
		else
		{
			ans += 1 / double(a);
			ans += 1 / double(a-c+tot-c+2);
			ans -= 1 / double(a+tot-c);
		}
	}
	v[x]=0;
	for(int p=g[x];p;p=next[p])
	if (v[adj[p]])
		if (flag[adj[p]]) dfs(adj[p],a+1,c+1);
		else	dfs(adj[p],a+1,c);

}
void Work()
{
	ans = 0;
	fo(i,0,n-1)
	{
		ans++;
		kai = i;
		ms(v,1);
		if (!flag[i]) dfs(i,1,0);
		else dfs(i,1,1);
	}
	printf("%.11lf\n",ans);
}
int main()
{
	Init();
	Work();
	return 0;
}


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

using namespace std;

const int MAXN = 3005;
int To[MAXN * 2],Next[MAXN * 2],Final[MAXN],tot;
int Circle[MAXN],Deep[MAXN],Fa[MAXN][MAXN],Lst[MAXN],Top[MAXN],P[MAXN],N,Up,Down;

void Link(int u,int v)
{
	To[++ tot] = v,Next[tot] = Final[u],Final[u] = tot;
}
int Get(int a) {return Top[a] == a ? a : Top[a] = Get(Top[a]);}
void Dfs(int Now,int Pre)
{
	Deep[Now] = Deep[Pre] + 1;
	Top[Now] = Now;
	for(int i = Final[Now];i;i = Next[i])
	if (To[i] != Pre)
	{
		if (Deep[To[i]] > Deep[Now]) continue;
		if (Deep[To[i]]) {Up = To[i],Down = Now;continue;} else
			Lst[To[i]] = Now,Dfs(To[i],Now),Top[To[i]] = Now;
	}
	for(int i = 1;i <= N;i ++)
	if (Top[i])
	{
		Fa[Now][i] = Fa[i][Now] = Get(i);
	}
}

void Mark(int Now,int Cir)
{
	if (!Circle[Now]) Circle[Now] = Cir;
	for(int i = Final[Now];i;i = Next[i])
	if (!Circle[To[i]]) Mark(To[i],Circle[Now]);
}
int Dis(int u,int v)
{
	return Deep[u] + Deep[v] - 2 * Deep[Fa[u][v]] + 1;
}

int main()
{
	scanf("%d", &N);
	for(int i = 1;i <= N;i ++)
	{
		int u,v;scanf("%d%d", &u, &v);
		u ++,v ++;
		Link(u,v),Link(v,u);
	}
	Dfs(1,0);
	int cnt = 0;
	for(int cur = Down;;cur = Lst[cur])
	{
		Circle[cur] = cur;P[++ cnt] = cur;if (cur == Up) break;
	}
	for(;cnt;cnt --) Mark(P[cnt],P[cnt]);
	double Ans = 0;
	for(int x = 1;x <= N;x ++)
		for(int y = 1;y <= N;y ++)
		{
			if (x == y) Ans = Ans + 1; else
			{
				int i = x,j = y;
				if (Circle[i] == Circle[j]) Ans += 1.0 / Dis(i,j); else
				{
					int X = Dis(Circle[j],j) + Dis(Circle[i],i);
					if (Deep[Circle[j]] < Deep[Circle[i]]) swap(i,j);
					int Y = Dis(Circle[i],Circle[j]) - 2,Z = Dis(Circle[j],Down) + Dis(Up,Circle[i]) - 2;
					Ans += 1.0 / (X + Y) + 1.0 / (X + Z) - 1.0 / (X + Y + Z);
				}
			}
		}
	printf("%.11f\n", Ans);
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int n,m,dep[5000],id[5000],cnt,sum,acc[5000],lca[3020][3020],f[5000];
int dfn[5000],low[5000],ist[5000],belong[5000],tot[5000],maxid;
double Ans;
stack<int>a;
vector<int>v[5000];
inline void tarjan(int x,int fa){
	dfn[x]=low[x]=++cnt;
	a.push(x);
	ist[x]=1;
	for(int i=0;i<v[x].size();i++)
	  if(v[x][i]!=fa){
	    if(!dfn[v[x][i]]){
	  	  tarjan(v[x][i],x);
	  	  low[x]=min(low[x],low[v[x][i]]);
	    }else if(ist[v[x][i]]){
	  	  low[x]=min(low[x],dfn[v[x][i]]);
	    }
	  }
	if(low[x]==dfn[x]){
	  sum++;
	  while(1){
	  	int u=a.top();
	  	a.pop();
	  	ist[u]=0;
	  	belong[u]=sum;
	  	tot[sum]++;
	  	if(u==x)break;
	  }
	}
}
inline int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
inline void work(int x,int ac,int fa){
	acc[x]=ac;
	f[x]=x;
	for(int i=0;i<v[x].size();i++)
	  if(v[x][i]!=fa&&tot[belong[v[x][i]]]==1){
	  	dep[v[x][i]]=dep[x]+1;
	  	work(v[x][i],ac,x);
	  	if(sf(v[x][i])!=sf(x))
		  f[sf(v[x][i])]=sf(x);
	  }
	for(int i=1;i<=n;i++)
	  if(acc[i]==ac)lca[x][i]=lca[i][x]=sf(i);
}
inline void dfs(int x,int fa){
	id[x]=id[fa]+1,dep[x]=1,acc[x]=x;
	work(x,x,x);
	for(int i=0;i<v[x].size();i++)
	  if(v[x][i]!=fa&&!id[v[x][i]]){
	  	if(tot[belong[v[x][i]]]>1)dfs(v[x][i],x);
	  }
}
int main(){
    int i,j,k,x,y;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
      scanf("%d%d",&x,&y);
      x++,y++;
      v[x].push_back(y);
      v[y].push_back(x);
    }
    for(i=1;i<=n;i++)
      if(!dfn[i])tarjan(i,0);
    for(i=1;i<=n;i++)
      if(tot[belong[i]]>1){
      	id[i]=1;
      	maxid=tot[belong[i]];
      	dfs(i,0);
      	break;
      }
   for(i=1;i<=n;i++)
      for(j=1;j<=n;j++){
      	if(acc[i]==acc[j])Ans+=1.0/(dep[i]+dep[j]-2*dep[lca[i][j]]+1);
      	  else {
      	  	int x=dep[i]+dep[j],y=abs(id[acc[i]]-id[acc[j]])-1,z=maxid-y-2;
      	  	Ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
      	  }
      }
    printf("%0.7lf\n",Ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#define DB double
using namespace std;
int n,tot;
const int N=3005;
int head[N],to[N<<1],nt[N<<1];
inline int read()
{
    int res = 0; char ch = getchar(); bool XX = false;
    for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
    for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
    return XX ? -res : res;
}
void add(int f,int t)
{
	to[++tot]=t;nt[tot]=head[f];head[f]=tot;
}
namespace solve2
{
	int top,tot;
	DB ans;
	int in[N],zhan[N],cir[N],incir[N],belong[N],f[N][15],dep[N];
	int findcir(int x,int fa)
	{
		if(in[x])
		{
			int t;
			do
			{
				t=zhan[top--];
				incir[t]=1;cir[++tot]=t;
			}while(x!=t);
			return 1;
		}
		zhan[++top]=x;in[x]=1;
		for(int i=head[x];i;i=nt[i])
			if(to[i]!=fa&&findcir(to[i],x))return 1;
		in[x]=0;--top;
		return 0;
	}

	void dfs(int x,int fa,int c)
	{
		belong[x]=c;f[x][0]=fa;dep[x]=dep[fa]+1;
		for(int i=1;i<15;++i)f[x][i]=f[f[x][i-1]][i-1];
		for(int i=head[x];i;i=nt[i])
			if(!incir[to[i]]&&to[i]!=fa)dfs(to[i],x,c);
	}
	int LCA(int x,int y)
	{
		if(dep[x]<dep[y])swap(x,y);
		for(int i=14;i>=0;--i)
			if(dep[f[x][i]]>=dep[y])x=f[x][i];
		if(x==y)return x;
		for(int i=14;i>=0;--i)
			if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
		return f[x][0];
	}
	int Dis(int x,int y){return dep[x]+dep[y]-2*dep[LCA(x,y)]+1;}
	int jue(int x){return x>0?x:-x;}
	void work()
	{
		findcir(1,0);
		for(int i=1;i<=tot;++i)dfs(cir[i],0,i);
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
			{
				if(belong[i]==belong[j])ans+=1.0/Dis(i,j);
				else
				{
					int x=dep[i]+dep[j],y=jue(belong[i]-belong[j])-1,z=tot-2-y;
					ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
				}
			}
		printf("%0.7f",ans);
	}
}
int main()
{
	cin>>n;
	for(int i=1,x,y;i<=n;++i)
	{
		x=read()+1;y=read()+1;
		add(x,y);add(y,x);
	}
	solve2::work();
	fclose(stdin);fclose(stdout);
	return 0;
}
/*
5 5 3 4 2 3 2 4 0 4 1 2

20 19
0 1
1 2
1 3
0 4
2 5
5 6
2 7
1 8
3 9
0 10
4 11
5 12
1 13
11 14
3 15
7 16
2 17
14 18
18 19

112.5777778
*/


#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
template<typename T> void ckmax (T&a, T b) { if (b > a) a = b; }
template<typename T> void ckmin (T&a, T b) { if (b < a) a = b; }
struct _in {
	const _in operator,(int&a)const {
		a = 0; char k = getchar(); int f = 1;
		for(;!isdigit(k); k = getchar()) if (k == '-') f = -1;
		for(; isdigit(k); k = getchar()) a = a * 10 + k - '0';
		a *= f; return*this;
	}
}in;

const int N = 3000 + 5;
int fr[N << 1], to[N << 1], h[N], tot;
void ade(int u, int v) { tot++; fr[tot] = h[u]; to[tot] = v; h[u] = tot; }
int n, stk[N], top, vis[N], dep[N], inc[N], C[N], Ctop;;

void dfs1 (int u, int f) {
	stk[++top] = u, vis[u] = 1, dep[u] = dep[f] + 1;
	// debug ("%d %d %d %d\n", u, f, dep[u], dep[f]);
	for (int i = h[u]; i; i = fr[i]) if (to[i] != f) {
		int v = to[i];
		if (vis[ to[i] ]) {
			if (dep[ to[i] ] > dep[u]) continue;
			else rep (j, dep[ to[i] ], dep[u]) inc[stk[j]] = 1, C[++Ctop] = stk[j];
		}
		else dfs1 (to[i], u);
	}
	top--;
}

double ans, tmp;
int rt;

void dfs2 (int u, int f, int Y) {
	vis[u] = 1;
	if (Y <= 0 && dep[u] - 1) ans += tmp = (1.00 / (dep[u]));
	else if (dep[u] - 1) ans += tmp = (1.00 / (dep[u] - 1 + 1) + 1.00 / (dep[u] - 1 - Y + (Ctop - Y) + 1) - 1.00 / (dep[u] - 1 - Y + Ctop));
	// debug ("%d %d %lf\n", rt, u, tmp);
	// debug ("%d %d %d\n", u, f, Y);
	for (int i = h[u]; i; i =fr[i]) if (to[i] != f) {
		if (vis[ to[i] ]) continue;
		if (!inc[ to[i] ]) {
			if (inc[u]) dfs2 (to[i], u, Y);
			else dfs2 (to[i], u, Y);
		}
		else {
			if (!inc[u]) dfs2 (to[i], u, 0);
			else dfs2 (to[i], u, Y + 1);
		}
	}
}

int main ()
{
	in, n;
	rep (i, 1, n) { int x, y; in, x, y; ++x, ++y; ade (x, y), ade (y, x); }
	rep (i, 1, n) {
		rt = i;
		// debug ("XXXXXXXXXXXXXXXXXXXXXXXX\n");
		memset (vis, 0, sizeof vis);
		dfs1 (i, 0);
		memset (vis, 0, sizeof vis);
		dfs2 (i, 0, inc[i] ? 0 : -1);
		memset (dep, 0, sizeof dep);
		Ctop = 0;
		// printf ("%.10f\n", ans);
	}
	printf ("%.10f\n", ans + n);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxN = 3000 + 5;
int n;
vector<int> G[maxN];

vector<int> loop;
int no[maxN];
bool vis[maxN];

int stk[maxN], len = 0;
bool DFS(int u, int fa) {
  stk[len ++] = u;
  vis[u] = true;
  for(int v : G[u]) if(v != fa) {
    if(vis[v]) {
      do {
        len --;
        loop.push_back(stk[len]);
        no[stk[len]] = (int)loop.size() - 1;
      } while(stk[len] != v);
      return true;
    } else {
      if(DFS(v, u)) return true;
    }
  }
  -- len;
  return false;
}

double ans = 0;

vector<int> l[maxN];
void Go(int u, int fa) {
  l[u].assign(1, 0);
  for(int v : G[u]) if(v != fa) {
    Go(v, u);
    for(int x : l[u]) for(int y : l[v]) {
      ans += 1.0 / (x + y + 1 + 1);
    }
    for(int y : l[v]) l[u].push_back(y + 1);
    l[v].clear();
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for(int i = 0; i < n; ++ i) {
    int x, y; cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  memset(vis, 0, sizeof(vis));
  memset(no, -1, sizeof(no));
  bool foundCycle = DFS(0, -1);
  assert(foundCycle);
  for(int u : loop) {
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i); break;
    }
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i); break;
    }
    Go(u, -1);
  }
  for(int A : loop) for(int B : loop) {
    int i = no[A], j = no[B];
    if(i >= j) continue;
    int x = j - i, y = (int)loop.size() + i - j;
    for(int u : l[A]) for(int v : l[B]) {
      ans += 1.0 / (u + v + x + 1) + 1.0 / (u + v + y + 1) - 1.0 / (u + v + x + y);
      // printf("%d %d %d %d\n", u, v, x, y);
    }
  }
  cout << fixed << setprecision(10) << ans * 2.0 + n << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxN = 3000 + 5;
int n;
vector<int> G[maxN];

vector<int> loop;
int no[maxN];
bool vis[maxN];

int stk[maxN], len = 0;
bool DFS(int u, int fa) {
  stk[len ++] = u;
  for(int v : G[u]) if(v != fa) {
    if(vis[v]) {
      do {
        len --;
        loop.push_back(stk[len]);
        no[stk[len]] = (int)loop.size() - 1;
      } while(stk[len] != v);
      return true;
    } else {
      if(DFS(v, u)) return true;
    }
  }
  -- len;
  return false;
}

double ans = 0;

vector<int> l[maxN];
void Go(int u, int fa) {
  l[u].assign(1, 0);
  for(int v : G[u]) if(v != fa) {
    Go(v, u);
    for(int x : l[u]) for(int y : l[v]) {
      ans += 1.0 / (x + y);
    }
    for(int y : l[v]) l[u].push_back(y + 1);
    l[v].clear();
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for(int i = 1; i <= n; ++ i) {
    int x, y; cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  memset(vis, 0, sizeof(vis));
  memset(no, -1, sizeof(no));
  bool foundCycle = DFS(1, -1);
  assert(foundCycle);
  for(int u : loop) {
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    Go(u);
  }
  for(int A : loop) for(int B : loop) {
    int i = no[A], j = no[B];
    if(i >= j) continue;
    int x = j - i, y = (int)loop.size() + i - j;
    for(int u : l[A]) for(int v : l[B])
      ans += 1.0 / (u + v + x + 1) + 1.0 / (u + v + y + 1) - 1.0 / (u + v + x + y);
  }
  cout << fixed << setprecision(10) << ans * 2.0 << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxN = 3000 + 5;
int n;
vector<int> G[maxN];

vector<int> loop;
int no[maxN];
bool vis[maxN];

int stk[maxN], len = 0;
bool DFS(int u, int fa) {
  stk[len ++] = u;
  vis[u] = true;
  for(int v : G[u]) if(v != fa) {
    if(vis[v]) {
      do {
        len --;
        loop.push_back(stk[len]);
        no[stk[len]] = (int)loop.size() - 1;
      } while(stk[len] != v);
      return true;
    } else {
      if(DFS(v, u)) return true;
    }
  }
  -- len;
  return false;
}

double ans = 0;

vector<int> l[maxN];
void Go(int u, int fa) {
  l[u].assign(1, 0);
  for(int v : G[u]) if(v != fa) {
    Go(v, u);
    for(int x : l[u]) for(int y : l[v]) {
      ans += 1.0 / (x + y + 1 + 1);
    }
    for(int y : l[v]) l[u].push_back(y + 1);
    l[v].clear();
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for(int i = 0; i < n; ++ i) {
    int x, y; cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  memset(vis, 0, sizeof(vis));
  memset(no, -1, sizeof(no));
  bool foundCycle = DFS(0, -1);
  assert(foundCycle);
  for(int u : loop) {
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i); break;
    }
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i); break;
    }
    Go(u, -1);
  }
  for(int A : loop) for(int B : loop) {
    int i = no[A], j = no[B];
    if(i >= j) continue;
    int x = j - i, y = (int)loop.size() + i - j;
    for(int u : l[A]) for(int v : l[B]) {
      ans += 1.0 / (u + v + x + 1) + 1.0 / (u + v + y + 1) - 1.0 / (u + v + x + y);
      printf("%d %d %d %d\n", u, v, x, y);
    }
  }
  cout << fixed << setprecision(10) << ans * 2.0 + n << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxN = 3000 + 5;
int n;
vector<int> G[maxN];

vector<int> loop;
int no[maxN];
bool vis[maxN];

int stk[maxN], len = 0;
bool DFS(int u, int fa) {
  stk[len ++] = u;
  vis[u] = true;
  for(int v : G[u]) if(v != fa) {
    if(vis[v]) {
      do {
        len --;
        loop.push_back(stk[len]);
        no[stk[len]] = (int)loop.size() - 1;
      } while(stk[len] != v);
      return true;
    } else {
      if(DFS(v, u)) return true;
    }
  }
  -- len;
  return false;
}

double ans = 0;

vector<int> l[maxN];
void Go(int u, int fa) {
  l[u].assign(1, 0);
  for(int v : G[u]) if(v != fa) {
    Go(v, u);
    for(int x : l[u]) for(int y : l[v]) {
      ans += 1.0 / (x + y);
    }
    for(int y : l[v]) l[u].push_back(y + 1);
    l[v].clear();
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for(int i = 1; i <= n; ++ i) {
    int x, y; cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  memset(vis, 0, sizeof(vis));
  memset(no, -1, sizeof(no));
  bool foundCycle = DFS(1, -1);
  assert(foundCycle);
  for(int u : loop) {
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    Go(u, -1);
  }
  for(int A : loop) for(int B : loop) {
    int i = no[A], j = no[B];
    if(i >= j) continue;
    int x = j - i, y = (int)loop.size() + i - j;
    for(int u : l[A]) for(int v : l[B])
      ans += 1.0 / (u + v + x + 1) + 1.0 / (u + v + y + 1) - 1.0 / (u + v + x + y);
  }
  cout << fixed << setprecision(10) << ans * 2.0 << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxN = 3000 + 5;
int n;
vector<int> G[maxN];

vector<int> loop;
int no[maxN];
bool vis[maxN];

int stk[maxN], len = 0;
bool DFS(int u, int fa) {
  stk[len ++] = u;
  for(int v : G[u]) if(v != fa) {
    if(vis[v]) {
      do {
        len --;
        loop.push_back(stk[len]);
        no[stk[len]] = (int)loop.size() - 1;
      } while(stk[len] != v);
      return true;
    } else {
      if(DFS(v, u)) return true;
    }
  }
  -- len;
  return false;
}

double ans = 0;

vector<int> l[maxN];
void Go(int u, int fa) {
  l[u].assign(1, 0);
  for(int v : G[u]) if(v != fa) {
    Go(v, u);
    for(int x : l[u]) for(int y : l[v]) {
      ans += 1.0 / (x + y);
    }
    for(int y : l[v]) l[u].push_back(y + 1);
    l[v].clear();
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for(int i = 1; i <= n; ++ i) {
    int x, y; cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  memset(vis, 0, sizeof(vis));
  memset(no, -1, sizeof(no));
  bool foundCycle = DFS(1, -1);
  assert(foundCycle);
  for(int u : loop) {
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    Go(u, -1);
  }
  for(int A : loop) for(int B : loop) {
    int i = no[A], j = no[B];
    if(i >= j) continue;
    int x = j - i, y = (int)loop.size() + i - j;
    for(int u : l[A]) for(int v : l[B])
      ans += 1.0 / (u + v + x + 1) + 1.0 / (u + v + y + 1) - 1.0 / (u + v + x + y);
  }
  cout << fixed << setprecision(10) << ans * 2.0 << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxN = 3000 + 5;
int n;
vector<int> G[maxN];

vector<int> loop;
int no[maxN];
bool vis[maxN];

int stk[maxN], len = 0;
bool DFS(int u, int fa) {
  stk[len ++] = u;
  vis[u] = true;
  for(int v : G[u]) if(v != fa) {
    if(vis[v]) {
      do {
        len --;
        loop.push_back(stk[len]);
        no[stk[len]] = (int)loop.size() - 1;
      } while(stk[len] != v);
      return true;
    } else {
      if(DFS(v, u)) return true;
    }
  }
  -- len;
  return false;
}

double ans = 0;

vector<int> l[maxN];
void Go(int u, int fa) {
  l[u].assign(1, 0);
  for(int v : G[u]) if(v != fa) {
    Go(v, u);
    for(int x : l[u]) for(int y : l[v]) {
      ans += 1.0 / (x + y + 1);
    }
    for(int y : l[v]) l[u].push_back(y + 1);
    l[v].clear();
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for(int i = 1; i <= n; ++ i) {
    int x, y; cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  memset(vis, 0, sizeof(vis));
  memset(no, -1, sizeof(no));
  bool foundCycle = DFS(1, -1);
  assert(foundCycle);
  for(int u : loop) {
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    for(auto i = G[u].begin(); i != G[u].end(); ++ i) if(no[*i] >= 0) {
      G[u].erase(i);
    }
    Go(u, -1);
  }
  for(int A : loop) for(int B : loop) {
    int i = no[A], j = no[B];
    if(i >= j) continue;
    int x = j - i, y = (int)loop.size() + i - j;
    for(int u : l[A]) for(int v : l[B])
      ans += 1.0 / (u + v + x + 1) + 1.0 / (u + v + y + 1) - 1.0 / (u + v + x + y);
  }
  cout << fixed << setprecision(10) << ans * 2.0 << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define N 3030
#define K 14
int n;
vector< int > v[ N ];
void init(){
  scanf( "%d" , &n );
  for( int i = 0 ; i < n ; i ++ ){
    int ai , bi;
    scanf( "%d%d" , &ai , &bi );
    v[ ai ].push_back( bi );
    v[ bi ].push_back( ai );
  }
}
bool oncyc[ N ] , instk[ N ];
int vst[ N ] , p[ N ][ K ] , dep[ N ] , stk[ N ];
int cycsz;
void go( int now , int prt , int tdep ){
  p[ now ][ 0 ] = prt;
  dep[ now ] = tdep;
  stk[ tdep ] = now;
  vst[ now ] = 1;
  instk[ now ] = true;
  for( int son : v[ now ] ){
    if( son == prt ) continue;
    if( vst[ son ] ){
      if( !instk[ son ] ) continue;
      cycsz = tdep - dep[ son ] + 1;
      for( int i = dep[ son ] ; i <= tdep ; i ++ )
        oncyc[ stk[ i ] ] = true;
    }else
      go( son , now , tdep + 1 );
  }
  instk[ now ] = false;
}
int cyc[ N ];
void go2( int now , int prt , int sum ){
  if( oncyc[ now ] ) sum ++;
  cyc[ now ] = sum;
  vst[ now ] = 2;
  for( int son : v[ now ] ){
    if( son == prt || vst[ son ] == 2 )
      continue;
    go2( son , now , sum );
  }
}
void build_pp(){
  for( int i = 1 ; i < K ; i ++ )
    for( int j = 0 ; j < n ; j ++ )
      p[ j ][ i ] = p[ p[ j ][ i - 1 ] ][ i - 1 ];
}
inline int lca( int ui , int vi ){
  if( dep[ ui ] > dep[ vi ] ) swap( ui , vi );
  int dlt = dep[ vi ] - dep[ ui ];
  for( int i = 0 ; i < K ; i ++ )
    if( ( dlt >> i ) & 1 )
      vi = p[ vi ][ i ];
  if( ui == vi ) return ui;
  for( int i = K - 1 ; i >= 0 ; i -- )
    if( p[ ui ][ i ] != p[ vi ][ i ] ){
      ui = p[ ui ][ i ];
      vi = p[ vi ][ i ];
    }
  return p[ ui ][ 0 ];
}
inline double cal( int a , int b ){
  if( a == b ) return 1.0;
  int tlca = lca( a , b );
  int bet = dep[ b ] + dep[ a ] - 2 * dep[ tlca ] + 1;
  int cnt = cyc[ b ] + cyc[ a ] - 2 * cyc[ tlca ] + oncyc[ tlca ];
  if( cnt <= 1 ) return 1.0 / (double)bet;
  bet -= cnt;
  int p1 = cnt , p2 = cycsz - cnt + 2;
  // printf( "%d<->%d bet: %d, p1: %d p2: %d cycsz: %d\n" , a , b , bet , p1 , p2 , cycsz );
  return 1.0 / (double)( bet + p1 ) +
         1.0 / (double)( bet + p2 ) -
         1.0 / (double)( bet + cycsz );
}
void solve(){
  go( 0 , 0 , 0 );
  go2( 0 , 0 , 0 );
  build_pp();
  double ans = 0.0;
  for( int i = 0 ; i < n ; i ++ )
    for( int j = 0 ; j < n ; j ++ )
      ans += cal( i , j );
  printf( "%.9f\n" , ans );
}
int main(){
  init();
  solve();
}

// ntuj - g470pm4xc7kt6go77ihka


// {{{ by WangYenJen
#include <bits/stdc++.h>
using namespace std;
// types
typedef long long ll;
typedef pair<int,int> pii;
// macro
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin() , (x).end()
#define REP(i , n) for(int i = 0; i < int(n); i++)
#define REP1(i , a , b) for(int i = a; i <= int(b); i++)
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define LC o<<1 , l , m
#define RC o<<1|1 , m + 1 , r
#define MS(x , v) memset(x , (v) , sizeof(x))
// input
inline bool SR(int &x) {
	return scanf("%d",&x) == 1;
}
inline bool SR(ll &x) {
	return scanf("%lld",&x) == 1;
}
inline bool SR(double &x) {
	return scanf("%lf",&x) == 1;
}
inline bool SR(char *s) {
	return scanf("%s",s) == 1;
}
inline bool RI() {
	return true;
}
template<typename I , typename... T> inline bool RI(I &x , T&... tail) {
	return SR(x) && RI(tail...);
}
// output
inline void SP(const int x) {
	printf("%d",x);
}
inline void SP(const ll x) {
	printf("%lld",x);
}
inline void SP(const double x) {
	printf("%.16lf",x);
}
inline void SP(const char *s) {
	printf("%s",s);
}
inline void PL() {
	puts("");
}
template<typename I , typename... T> inline void PL(const I x , const T... tail) {
	SP(x);
	if(sizeof...(tail)) putchar(' ');
	PL(tail...);
}
// debug
#define WangYenJen
#ifdef WangYenJen
template<typename I> void _DOING(const char *s , I&& x) {
    cerr << s << " = " << x << endl;
}
template<typename I , typename... T> void _DOING(const char *s , I&& x , T&&... tail) {
    int c = 0;
    while(*s != ',' || c != 0) {
        if(*s == '(' || *s == '[' || *s == '{') c++;
        if(*s == ')' || *s == ']' || *s == '}') c--;
        cerr << *s++;
    }
    cerr << " = " << x << " , ";
    _DOING(s + 1 , tail...);
}
#define debug(...) \
do {\
    fprintf(stderr , "%s:%d - ",__PRETTY_FUNCTION__,__LINE__);\
    _DOING(#__VA_ARGS__ , __VA_ARGS__);\
} while(0);
#else
#define debug(...)
#endif
// random function
inline int RAND() {
	static int x = 880301;
	return (x = x * 0xdefaced + 1) & 0x7fffffff;
}
// }}}

const int MAX_N = 3000 + 10;
double ans;
int cycle_cnt;
int deg[MAX_N];
bool vis[MAX_N];
bool tag[MAX_N];
vector<int> G[MAX_N];
void dfs(int u , int a , int b) {
	vis[u] = true;
	if(b <= 1) ans += 1.0 / a;
	else ans += 1.0 / a - 1.0 / (a - b + cycle_cnt) + 1.0 / (a - b + cycle_cnt - b + 2);
	for(int v : G[u]) if(!vis[v]) dfs(v, a + 1, b + tag[v]);
}
int main() {
    int n;
    RI(n);
	REP(i , n) {
	    int a , b;
	    RI(a , b);
		G[a].PB(b);
		G[b].PB(a);
		deg[a]++;
		deg[b]++;
	}
	vector<int> vec;
	REP(i , n) if(deg[i] == 1) vec.PB(i);
	REP(i , SZ(vec)) {
	    int u = vec[i];
        for(int v : G[u]) {
            if(--deg[v] == 1) vec.PB(v);
        }
	}
	cycle_cnt = n - SZ(vec);
	REP(i , n) if(deg[i] > 1) tag[i] = 1;
	REP(i , n) {
        MS(vis , 0);
        dfs(i , 1 , tag[i]);
	}
	// printf("%.10f\n",ans);
	PL(ans);
	return 0;
}

// ntuj - gypn145f8u9w32sn19od


#include<bits/stdc++.h>
using namespace std;
#define FZ(n) memset((n),0,sizeof(n))
#define FMO(n) memset((n),-1,sizeof(n))
#define MC(n,m) memcpy((n),(m),sizeof(n))
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define ALL(x) begin(x),end(x)
#define IOS do { ios_base::sync_with_stdio(0);cin.tie(0); } while (0)
#define SZ(x) ((int)(x).size())
#ifndef OFFLINE
    #define ONLINE_JUDGE
#endif
#ifdef ONLINE_JUDGE
#define FILEIO(name) \
    do { \
        freopen(name".in", "r", stdin); \
        freopen(name".out", "w", stdout); \
    } while (0)
#else
    #define FILEIO(name) do { } while(0)
#endif

#define _TOKEN_CAT2(x, y) x ## y
#define _TOKEN_CAT(x, y) _TOKEN_CAT2(x, y)
#define _MACRO_OVERL3(_1, _2, _3, _N, ...) _N
#define _RANGE1(a) int _TOKEN_CAT(_t, __LINE__)=0; _TOKEN_CAT(_t, __LINE__)<(a); (_TOKEN_CAT(_t, __LINE__))++
#define _RANGE2(i, a) int (i)=0; (i)<(a); (i)++
#define _RANGE3(i, a, b) int (i)=(a); (i)!=(b); (i)+=((b)>(a)?1:-1)
#define loop(...) for (_MACRO_OVERL3(__VA_ARGS__, _RANGE3, _RANGE2, _RANGE1)(__VA_ARGS__))

#ifdef OFFLINE
template<typename T>
void _dump(const char* s, T&& head) {
    cerr << s << " = " << head << " <<" << endl;
}

template<typename T, typename... Args>
void _dump(const char* s, T&& head, Args&&... tail) {
    int c = 0;
    while (*s!=',' || c!=0) {
        if (*s=='(' || *s=='[' || *s=='{' || *s=='<') c++;
        if (*s==')' || *s==']' || *s=='}' || *s=='>') c--;
        cerr << *s++;
    }
    cerr << " = " << head << ", ";
    _dump(s+1, tail...);
}

#define dump(...) do { \
    cerr << "\033[32m>> " << __LINE__ << ": " << __PRETTY_FUNCTION__ << endl; \
    cout << "   "; \
    _dump(#__VA_ARGS__, __VA_ARGS__); \
    cout << "\033[0m"; \
} while (0)
#else
#define dump(...)
#endif

#define au auto
template<class T>
using vec = vector<T>;

template<typename Iter>
ostream& _IterOutput_(ostream &o, Iter b, Iter e, const string ss="", const string se="") {
    o << ss;
    for (auto it=b; it!=e; it++) o << (it==b ? "" : ", ") << *it;
    return o << se;
}

template<typename T1, typename T2>
ostream& operator << (ostream &o, const pair<T1, T2> &pair) {
    return o << "(" << pair.F << ", " << pair.S << ")";
}

template<typename T>
ostream& operator << (ostream &o, const vector<T> &vec) {
    return _IterOutput_(o, ALL(vec), "[", "]");
}

template<typename T>
ostream& operator << (ostream &o, const set<T> &st) {
    return _IterOutput_(o, ALL(st), "{", "}");
}

template<typename T, size_t N>
ostream& operator << (ostream &o, const array<T, N> &arr) {
    return _IterOutput_(o, ALL(arr), "|", "|");
}

template<typename T1, typename T2>
ostream& operator << (ostream &o, const map<T1, T2> &mp) {
    o << "{";
    for (auto it=mp.begin(); it!=mp.end(); it++) {
        o << (it==mp.begin()?"":", ") << it->F << ":" << it->S;
    }
    o << "}";
    return o;
}

const int MX = 5555;
int N;
vector<int> el[MX];

bool ins[MX];
stack<int> st;
vector<int> lop;
bool dfs(int u, int fa) {
    ins[u] = 1;
    st.push(u);
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (ins[v]) {
            int w;
            do {
                w = st.top(); st.pop();
                lop.PB(w);
            } while (w != v);
            return 1;
        }
        if (dfs(v, u)) return 1;
    }
    return 0;
}

bool islop[MX];
int lopId[MX];
int fath[MX];
vector<int> lopCh[MX];

double ans;

void dfs2(int u, int fa, int d, int id) {
    lopCh[id].PB(d);
    fath[u] = id;
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (islop[v]) continue;
        dfs2(v, u, d+1, id);
    }
}

void dfs3(int u, int fa, int d) {
    ans += 1.0 / d;
    for (auto v: el[u]) {
        if (v == fa) continue;
        if (islop[v] && v != fath[u]) {
            continue;
        }
        dfs3(v, u, d+1);
    }
}

int32_t main() {
    IOS;
    cin >> N;
    for (int i=0; i<N; i++) {
        int u, v; cin >> u >> v;
        el[u].PB(v);
        el[v].PB(u);
    }

    dfs(0, -1);

    assert(SZ(lop));
    int lll = 0;
    for (auto v: lop) {
        islop[v] = 1;
        lopId[v] = ++lll;
    }

    for (auto v: lop) {
        dfs2(v, -1, 1, v);
    }

    for (int i=0; i<N; i++){
        dfs3(i, -1, 1);
    }

    for (auto u: lop) {
        for (auto v: lop) {
            if (u == v) continue;
            int d1 = abs(lopId[u] - lopId[v]), d2 = lll - d1;
            d1--;
            d2--;

            for (auto x: lopCh[u]) {
                for (auto y: lopCh[v]) {
                    ans += 1.0 / (x+y+d1);
                    ans += 1.0 / (x+y+d2);
                    ans -= 1.0 / (x+y+d1+d2);
                }
            }
        }
    }

    cout << fixed << setprecision(10) << ans << endl;

    return 0;
}

// ntuj - 44a4k30tyt9bqw49b2jz2


#include<bits/stdc++.h>
using namespace std;
#define N 3005
int vi[N],cir;
int ori[N][N];
int sccl[N][N];
vector<int> s[N],scc[N],g[N];
stack<int> sta;
int dfs_cnt=0,pre[N]={0},sccno[N]={0},scc_cnt=0;
int dfs(int u,int fa){
    int lowu,lowv,i;
    lowu=pre[u]=++dfs_cnt;
    sta.push(u);
    for(i=0;i<s[u].size();i++){
        int v=s[u][i];
        if(v==fa) continue;
        if(pre[v]==0){
            lowv=dfs(v,u);
            lowu=min(lowu,lowv);
        }
        else if(pre[v]<pre[u] && sccno[v]==0){
            lowu=min(lowu,pre[v]);
        }
    }
    if(lowu==pre[u]){
        ++scc_cnt;
        while(sta.size()){
            int x=sta.top();
            sta.pop();
            sccno[x]=scc_cnt;
            scc[scc_cnt].push_back(x);
            if(x==u) break;
        }
        cir=max(cir,(int)scc[scc_cnt].size());
    }
    return lowu;
}
void dfs1(int u,int add,int st){
    ori[st][u]=add;
    for(int i=0;i<s[u].size();i++){
        int v=s[u][i];
        if(vi[v]==st) continue;
        vi[v]=st;
        dfs1(v,add+1,st);
    }
}
void dfs2(int u,int add,int st){
    sccl[st][u]=add;
    //printf("%d..",u);
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(vi[v]==st) continue;
        vi[v]=st;
        dfs2(v,add+1,st);
    }
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        s[x].push_back(y);
        s[y].push_back(x);
    }
    dfs(0,-1);
    for(int i=0;i<n;i++){
        for(int j=0;j<s[i].size();j++){
            int x=sccno[i];
            int y=sccno[s[i][j]];
            if(x==y) continue;
            g[x].push_back(y);
            g[y].push_back(x);
        }
    }
    memset(vi,-1,sizeof(vi));
    for(int i=0;i<n;i++){
        vi[i]=i;
        dfs1(i,0,i);
    }
    memset(vi,-1,sizeof(vi));
    for(int i=1;i<=scc_cnt;i++){
        vi[i]=i;
        dfs2(i,0,i);
    }
    double ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j){
                ans+=1;
                continue;
            }
            int x=sccl[sccno[i]][sccno[j]];
            int y=ori[i][j]-x;
            int z=cir-y;
            if(y && z) ans+=1.0/(x+y+1)+1.0/(x+z+1)-1.0/(x+y+z);
            else ans +=1.0/(x+1);
        }
    }
    printf("%.12f\n",ans);
}

// ntuj - kg4g9znyi43tbymyl6pht


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

using namespace std;
const int N=5010;
int head[N],from[N],to[N<<2],nxt[N<<2],dep[N],q[N],vis[N],bel[N],num[N<<2],cnt;
double ans;
int tot,x,y,n,m;
int f[N][25];

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    return x*f;
}

inline void add(int u,int v,int w){
    nxt[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
    num[cnt]=w;
}

bool dfs(int u,int fa){
    vis[u]=1;
    for(int i=head[u];i;i=nxt[i]){
        if(num[i]!=fa){
            if(vis[to[i]]){
                for(int j=u;j!=to[i];j=from[j]) q[++tot]=j;
                q[++tot]=to[i];
                return true;
            }
            else{
                from[to[i]]=u;
                if(dfs(to[i],num[i])) return true;
            }
        }
    }
    return false;
}

void find(int u,int fa,int rt){
    bel[u]=rt; dep[u]=dep[fa]+1;
    f[u][0]=fa;
    for(int i=1;i<=15;i++)
        f[u][i]=f[f[u][i-1]][i-1];
    for(int i=head[u];i;i=nxt[i])
        if(to[i]!=fa&&!vis[to[i]]) find(to[i],u,rt);
}

int lca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    int dis=dep[x]-dep[y];
    for(int i=0;i<=15;i++)
        if(dis&(1<<i)) x=f[x][i];
    if(x==y) return x;
    for(int i=15;i>=0;i--)
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        x++;y++;
        add(x,y,i);add(y,x,i);
    }
    dfs(1,0);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=tot;i++) vis[q[i]]=1;
    for(int i=1;i<=tot;i++) find(q[i],0,i);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(bel[i]==bel[j]) ans+=(double)1/(dep[i]+dep[j]-2*dep[lca(i,j)]+1);
            else{
                int X=dep[i]+dep[j];
                int Y=abs(bel[i]-bel[j])-1;
                int Z=tot-Y-2;
                ans+=(double)1/(X+Y)+(double)1/(X+Z)-(double)1/(X+Y+Z);
            }
    printf("%.7f",ans);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
const int N = 3005;
bool flag[N] , v[N];
int n;
int adj[N<<1] , next[N<<1] , g[N] , tot;
int stack[N] , stn , kai;
double ans;
void ins(int x,int y)
{
	adj[++tot]=y; next[tot]=g[x]; g[x]=tot;
}
void find_h(int x,int fa)
{
	v[x] = 0;
	for(int p=g[x];p;p=next[p])
	if (v[adj[p]])
	{
		stack[++stn]=adj[p];
		find_h(adj[p],p);
		if (tot) return;
		stack[stn--]=-1;
	}
	else
	if ((p^1) != fa && stn>0)
		while (stack[stn+1] != adj[p])
		flag[stack[stn--]]=1 , tot++;
}
void Init()
{
	scanf("%d",&n);
	int x,y;
	tot = 1;
	fo(i,1,n)
	{
		scanf("%d%d",&x,&y);
		ins(x,y); ins(y,x);
	}

	ms(stack,255);
	ms(v,1);
	stack[stn=1]=1;
	tot=0;
	find_h(1,0);
}
void dfs(int x,int a,int c)
{
	double temp = ans;
	if (x != kai)
	{
		if (tot==2 || c<=1)
		{
			ans += 1 / double(a);
		}
		else
		{
			ans += 1 / double(a);
			ans += 1 / double(a-c+tot-c+2);
			ans -= 1 / double(a+tot-c);
		}
	}
	v[x]=0;
	for(int p=g[x];p;p=next[p])
	if (v[adj[p]])
		if (flag[adj[p]]) dfs(adj[p],a+1,c+1);
		else	dfs(adj[p],a+1,c);

}
void Work()
{
	ans = 0;
	fo(i,0,n-1)
	{
		ans++;
		kai = i;
		ms(v,1);
		if (!flag[i]) dfs(i,1,0);
		else dfs(i,1,1);
	}
	printf("%.11lf\n",ans);
}
int main()
{
	Init();
	Work();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3010;
vector<int> G[MAXN];
int n, kase, csz, du[MAXN], vis[MAXN];
double ans;
void dfs(int u, int a, int b) {
    vis[u] = kase;
    du[u] == 2 ? ++b : ++a;
    if(b <= 1) ans += 1.0 / (a + b);
    else ans += 1.0 / (b + a) + 1.0 / (a + csz - b + 2) - 1.0 / (a + csz);
    for(int v: G[u]) {
        if(vis[v] != kase) dfs(v, a, b);
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) {
        int a, b;
        scanf("%d%d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
        ++du[a], ++du[b];
    }
    queue<int> q;
    for(int i = 0; i < n; ++i)
        if(du[i] == 1) q.push(i);
    while(!q.empty()) {
        int u = q.front(); q.pop();
        for(auto v : G[u]) if(--du[v] == 1) q.push(v);
    }
    for(int i = 0; i < n; ++i) csz += du[i] == 2;
    for(int i = 0; i < n; ++i) {++kase; dfs(i, 0, 0);}
    //cout << ans << endl;
    printf("%.9f\n", ans);
}


/*=================================
# Created time: 2017-02-13 13:51
# Filename: 706c.cpp
# Description:
=================================*/
#define me AcrossTheSky&HalfSummer11
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>

#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define sqr(x) (x)*(x)
#define lowbit(x) (x)&(-x)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define fin(a) freopen(a,"r",stdin);
#define fout(a) freopen(a,"w",stdout);
#define Abs(x) ((x) > 0 ? (x) : (-(x)))
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)

#define maxn 100005
#define maxm 100005
#define MOD 1000000007
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

template<class T> inline
void read(T& num){
    num = 0; bool f = 1;char ch = getchar();
    while(ch < '0' || ch > '9') { if(ch == '-') f = 0;ch = getchar();}
    while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}
    num = f ? num: -num;
}
template<class T> inline
void write(T x,char ch){
    int s[100];
    if (x==0) {putchar('0'); putchar(ch); return;}
    if (x<0) {putchar('-'); x=-x;} int num=0;
    while (x){ s[num++]=(x%10); x=x/10;}
    FORM(i,num-1,0) putchar(s[i]+'0'); putchar(ch);
}
/*==================split line==================*/
int n,tot,siz;
int d[3005],d2[3005],last[3005];
double ans;
bool v[3005];
struct hh
{
    int next,to;
}e[7005];
queue<int> q;
void add(int a,int b)
{
    e[++tot].to=b;
    e[tot].next=last[a];
    last[a]=tot;
}
void insert(int a,int b)
{
    add(a,b);add(b,a);
}
void dfs(int now)
{
    int i,j;
    v[now]=true;
    for(i=last[now];i;i=e[i].next)
        if(!v[e[i].to])
        {
            d2[e[i].to]=d2[now]+1;
            if(!d[e[i].to]) d[e[i].to]=d[now]+1,ans+=1.0/d[e[i].to];
            else ans+=1.0/d2[e[i].to]-2.0/(d[e[i].to]+d2[e[i].to]+siz-2);
            dfs(e[i].to);
        }
    v[now]=false;
}
int main()
{
    int i,j,u,v,now;
    read(n); siz=n;
    for(i=1;i<=n;i++){
        read(u); read(v);
        u++;v++; d[u]++;d[v]++;
        insert(u,v);
    }
    for(i=1;i<=n;i++) if(d[i]==1) q.push(i);
    while(!q.empty()){
        now=q.front();q.pop();siz--;
        for(i=last[now];i;i=e[i].next)
            if(--d[e[i].to]==1) q.push(e[i].to);
    }
    for(i=1;i<=n;i++){
        memset(d,0,sizeof(d));
        memset(d2,0,sizeof(d2));
        d[i]=d2[i]=1;
        dfs(i);
    }
    printf("%lf",ans+(double)n);
    return 0;
}


#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int head[5010];
int from[5010];
int to[100010];
int nxt[100010];
int dep[5010];
int q[5010];
int cnt;
int vis[5010];
int bel[5010];
int num[100010];
double ans;
int tot;
int x,y,n,m;
int f[5010][17];
inline void add(int u,int v,int w){
    nxt[++cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v;
    num[cnt]=w;
}
bool dfs(int u,int fa){
    vis[u]=1;
    for(int i=head[u];i;i=nxt[i]){
        if(num[i]!=fa){
            if(vis[to[i]]){
                for(int j=u;j!=to[i];j=from[j]) q[++tot]=j;
                q[++tot]=to[i];
                return true;
            }
            else{
                from[to[i]]=u;
                if(dfs(to[i],num[i])) return true;
            }
        }
    }
    return false;
}
void find(int u,int fa,int rt){
    bel[u]=rt; dep[u]=dep[fa]+1;
    f[u][0]=fa;
    for(int i=1;i<=15;i++)
        f[u][i]=f[f[u][i-1]][i-1];
    for(int i=head[u];i;i=nxt[i])
        if(to[i]!=fa&&!vis[to[i]]) find(to[i],u,rt);
}

int lca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    int dis=dep[x]-dep[y];
    for(int i=0;i<=15;i++)
        if(dis&(1<<i)) x=f[x][i];
    if(x==y) return x;
    for(int i=15;i>=0;i--)
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        x++,y++;
        add(x,y,i);
        add(y,x,i);
    }
    dfs(1,0);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=tot;i++)
    {
        vis[q[i]]=1;
    }
    for(int i=1;i<=tot;i++)
    {
        find(q[i],0,i);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(bel[i]==bel[j])
            {
                ans+=(double)1/(dep[i]+dep[j]-2*dep[lca(i,j)]+1);
            }
            else
            {
                int X=dep[i]+dep[j];
                int Y=abs(bel[i]-bel[j])-1;
                int Z=tot-Y-2;
                ans+=(double)1/(X+Y)+(double)1/(X+Z)-(double)1/(X+Y+Z);
            }
        }
    }
    printf("%.7f",ans);
}


#include<bits/stdc++.h>
using namespace std;
const int N=3010;
vector<int>e[N];double ans=0;
int n,h,t,rt,tot,d[N],vis[N],q[N];
void dfs(int u,int a,int b){
if(d[u]==2)++b;else ++a;vis[u]=rt;
if(b==tot)ans+=1.0/(a+2);else if(b<=2)ans+=1.0/(a+b);
else ans+=1.0/(a+b)+1.0/(a+tot-b+2)-1.0/(a+tot);
for(auto v : e[u])if(vis[v]^rt)dfs(v,a,b);
}
int main(){
scanf("%d",&n),h=1;
for(int i=1,x,y;i<=n;i++)scanf("%d%d",&x,&y),++x,++y,e[x].push_back(y),e[y].push_back(x),++d[x],++d[y];
for(int i=1;i<=n;i++)if(d[i]==1)q[++t]=i;
for(int x;h<=t;){
x=q[h++];
for(auto v : e[x]){--d[v];if(d[v]==1)q[++t]=v;}
}
for(int i=1;i<=n;i++)if(d[i]==2)++tot;
for(int i=1;i<=n;i++)rt=i,dfs(rt,0,0);
printf("%0.10lf\n",ans);
return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N=3010;
vector<int>e[N]; double ans=0;
int n,h,t,rt,tot,d[N],vis[N],q[N];
void dfs(int u,int a,int b){
	if(d[u]==2) ++b; else ++a; vis[u]=rt;
	if(b==tot) ans+=1.0/(a+2); else if(b<=2) ans+=1.0/(a+b);
	else ans+=1.0/(a+b)+1.0/(a+tot-b+2)-1.0/(a+tot);
	for(auto v : e[u]) if(vis[v] ^ rt) dfs(v, a, b);
}
int main(){
	scanf("%d",&n),h=1;
	for(int i=1,x,y;i<=n;i++) scanf("%d%d",&x,&y),++x,++y,e[x].push_back(y),e[y].push_back(x),++d[x],++d[y];
	for(int i=1;i<=n;i++) if(d[i]==1) q[++t]=i;
	for(int x;h<=t;){
		x=q[h++];
		for(auto v : e[x]) {--d[v]; if(d[v]==1) q[++t]=v;}
	}
	for(int i=1;i<=n;i++) if(d[i]==2) ++tot;
	for(int i=1;i<=n;i++) rt=i,dfs(rt,0,0);
	printf("%0.10lf\n", ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=100010,M=1000010,P=1e9+7;
const int inf=0x3f3f3f3f;
const int INF=0xcfcfcfcf;
const db eps=1e-9,pi=asin(1)*2;
inline ll read();
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
inline int ADD(int a,int b) { return a+b>=P?a+b-P:a+b; }
inline int MINUS(int a,int b) { return a-b<0?a-b+P:a-b; }
#define plus(a,b) a=ADD(a,b)
#define minus(a,b) a=MINUS(a,b)
#define mul(a,b) a=(1ll*a*(b))%P
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pll pair<ll,ll>
#define mp(x,y) make_pair(x,y)

int head[N],ver[M],nxt[M];
int n,m,tot=1;
inline void add(int x,int y)
{
	ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
}

int pos[N],sz=0,ed=0;
bool visit[N];
inline bool dfs(int x,int fa)
{
	visit[x]=true;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(y==fa) continue;
		if(visit[y]) return ed=y,pos[x]=++sz;
		if(dfs(y,x)&&y!=ed) return pos[x]=++sz;
	}
	return visit[x]=false;
}

int f[N],d[N],size[N],son[N],top[N],rt[N],RT=0;
inline void dfs1(int x,int fa)
{
	f[x]=fa,d[x]=d[fa]+1,size[x]=1,rt[x]=RT;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(y==fa||pos[y]) continue;
		dfs1(y,x);
		size[x]+=size[y];
		if(size[y]>size[son[x]]) son[x]=y;
	}
}
inline void dfs2(int x,int t)
{
	top[x]=t;
	if(!son[x]) return ;
	dfs2(son[x],t);
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(y==f[x]||y==son[x]||pos[y]) continue;
		dfs2(y,y);
	}
}
inline int lca(int x,int y)
{
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
		x=f[fx],fx=top[x];
	}
	if(d[x]>d[y]) return y;
	return x;
}
inline int dis(int x,int y)
{
	return d[x]+d[y]-2*d[lca(x,y)];
}

#ifdef FILE
const int RS=1<<20;
char buf[RS],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,RS,stdin),p1==p2)?EOF:*p1++
#endif
inline ll read()
{
	ll s=0;
	bool flag=false;
	char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=true;
	for(;'0'<=ch&&ch<='9';ch=getchar()) s=(s<<3)+(s<<1)+(ch^'0');
	if(flag) return -s;
	return s;
}

int main()
{
#ifdef FILE
	freopen(FILE ".in","r",stdin);
	freopen(FILE ".out","w",stdout);
#endif
	n=read();
	for(int i=1;i<=n;i++)
	{
		int x=read()+1,y=read()+1;
		add(x,y),add(y,x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++) if(pos[i]) RT=i,dfs1(i,0),dfs2(i,i);
/*
	cerr<<"sz = "<<sz<<"\n";
	cerr<<"pos: \n";
	for(int i=1;i<=n;i++) cerr<<pos[i]<<" ";
	cerr<<"\n";
	cerr<<"rt: \n";
	for(int i=1;i<=n;i++) cerr<<rt[i]<<" ";
	cerr<<"\n";
	cerr<<"d: \n";
	for(int i=1;i<=n;i++) cerr<<d[i]<<" ";
	cerr<<"\n";
	cerr<<"top: \n";
	for(int i=1;i<=n;i++) cerr<<top[i]<<" ";
	cerr<<"\n";
	cerr<<"----------------\n";
//*/
	db ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(rt[i]==rt[j])
			{
				ans+=1.0/(dis(i,j)+1);
//				cerr<<i<<" "<<j<<" "<<dis(i,j)<<" "<<1.0/(dis(i,j)+1)<<"\n";
			}
			else
			{
				int x=d[i]+d[j],y=abs(pos[rt[i]]-pos[rt[j]])-1,z=sz-2-y;
				ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
//				cerr<<i<<" "<<j<<" "<<x<<" "<<y<<" "<<z<<" "<<1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z)<<"\n";
			}
		}
	}
	printf("%.15lf\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=100010,M=1000010,P=1e9+7;
const int inf=0x3f3f3f3f;
const int INF=0xcfcfcfcf;
const db eps=1e-9,pi=asin(1)*2;
inline ll read();
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
inline int ADD(int a,int b) { return a+b>=P?a+b-P:a+b; }
inline int MINUS(int a,int b) { return a-b<0?a-b+P:a-b; }
#define plus(a,b) a=ADD(a,b)
#define minus(a,b) a=MINUS(a,b)
#define mul(a,b) a=(1ll*a*(b))%P
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pll pair<ll,ll>
#define mp(x,y) make_pair(x,y)

int head[N],ver[M],nxt[M];
int n,m,tot=1;
inline void add(int x,int y)
{
	ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
}

int pos[N],sz=0,ed=0;
bool visit[N];
inline bool dfs(int x,int fa)
{
	visit[x]=true;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(y==fa) continue;
		if(visit[y]) return ed=y,pos[x]=++sz;
		if(dfs(y,x)&&y!=ed) return pos[x]=++sz;
	}
	return visit[x]=false;
}

int f[N],d[N],size[N],son[N],top[N],rt[N],RT=0;
inline void dfs1(int x,int fa)
{
	f[x]=fa,d[x]=d[fa]+1,size[x]=1,rt[x]=RT;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(y==fa||pos[y]) continue;
		dfs1(y,x);
		size[x]+=size[y];
		if(size[y]>size[son[x]]) son[x]=y;
	}
}
inline void dfs2(int x,int t)
{
	top[x]=t;
	if(!son[x]) return ;
	dfs2(son[x],t);
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(y==f[x]||y==son[x]||pos[y]) continue;
	}
}
inline int lca(int x,int y)
{
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
		x=f[fx],fx=top[x];
	}
	if(d[x]>d[y]) return y;
	return x;
}
inline int dis(int x,int y)
{
	return d[x]+d[y]-2*d[lca(x,y)];
}

#ifdef FILE
const int RS=1<<20;
char buf[RS],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,RS,stdin),p1==p2)?EOF:*p1++
#endif
inline ll read()
{
	ll s=0;
	bool flag=false;
	char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=true;
	for(;'0'<=ch&&ch<='9';ch=getchar()) s=(s<<3)+(s<<1)+(ch^'0');
	if(flag) return -s;
	return s;
}

int main()
{
#ifdef FILE
	freopen(FILE ".in","r",stdin);
	freopen(FILE ".out","w",stdout);
#endif
	n=read();
	for(int i=1;i<=n;i++)
	{
		int x=read()+1,y=read()+1;
		add(x,y),add(y,x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++) if(pos[i]) RT=i,dfs1(i,0),dfs2(i,i);
/*
	cerr<<"pos: \n";
	for(int i=1;i<=n;i++) cerr<<pos[i]<<" ";
	cerr<<"\n";
	cerr<<"rt: \n";
	for(int i=1;i<=n;i++) cerr<<rt[i]<<" ";
	cerr<<"\n";
	cerr<<"d: \n";
	for(int i=1;i<=n;i++) cerr<<d[i]<<" ";
	cerr<<"\n";
	cerr<<"----------------\n";
//*/
	db ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(rt[i]==rt[j]) ans+=1.0/(dis(i,j)+1);
			else
			{
				int x=d[i]+d[j],y=abs(pos[rt[i]]-pos[rt[j]])-1,z=sz-2-y;
				ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
//				cerr<<i<<" "<<j<<" "<<x<<" "<<y<<" "<<z<<" "<<1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z)<<"\n";
			}
		}
	}
	printf("%.15lf\n",ans);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 3010
template <typename T>inline T read()
{
    register T sum=0;
    register char cc=getchar();
    int sym=1;
    while(cc!='-'&&(cc>'9'||cc<'0'))cc=getchar();
    if(cc=='-')sym=-1,cc=getchar();
    sum=sum*10+cc-'0';
    cc=getchar();
    while(cc>='0'&&cc<='9')sum=sum*10+cc-'0',cc=getchar();
    return sym*sum;
}
template <typename T>inline T read(T &a)
{
    a=read<T>();
    return a;
}
template <typename T,typename... Others> inline void read(T& a, Others&... b)
{
    a=read(a);
	read(b...);
}
struct Edge
{
	int v;
	Edge *next;
	Edge(int a=0,Edge *b=NULL)
	{
		v=a;
		next=b;
	}
}*head[maxn];
int n,cnt,tp,sta[maxn],in[maxn],cir[maxn],dep[maxn],vis[maxn],rnk[maxn],col[maxn];
double ans;
bool dfs1(int k,int fa)
{
	sta[++tp]=k;
	vis[k]=true;
	for(Edge *i=head[k];i!=NULL;i=i->next)
	{
		if(i->v==fa)
			continue;
		if(vis[i->v])
		{
			int x=0;
			while(tp&&x!=i->v)
			{
				x=sta[tp--];
				cir[++cnt]=x;
				rnk[x]=cnt;
				in[x]=true;
			}
			return true;
		}
		if(dfs1(i->v,k))
			return true;
	}
	vis[k]=false;
	tp-=1;
	return false;
}
void dfs2(int k,int fa,int rt)
{
	col[k]=rt;
	dep[k]=dep[fa]+1;
	for(Edge *i=head[k];i!=NULL;i=i->next)
		if(i->v!=fa&&!in[i->v])
			dfs2(i->v,k,rt);
}
void dfs3(int k,int fa,int dis)
{
	ans+=1./dis;
	for(Edge *i=head[k];i!=NULL;i=i->next)
		if(i->v!=fa&&(i->v==col[k]||!in[i->v]))
			dfs3(i->v,k,dis+1);
}
int main()
{
	read(n);
	for(int i=1;i<=n;i++)
	{
		int x,y;
		read(x,y);
		x+=1,y+=1;
		head[x]=new Edge(y,head[x]);
		head[y]=new Edge(x,head[y]);
	}
	dfs1(1,0);
	for(int i=1;i<=cnt;i++)
		dfs2(cir[i],0,cir[i]);
	for(int i=1;i<=n;i++)
	{
		dfs3(i,0,1);
		for(int j=1;j<=n;j++)
		{
			if(col[i]==col[j])
				continue;
			ans+=1./(dep[i]+dep[j]+abs(rnk[col[i]]-rnk[col[j]])-1);
			ans+=1./(dep[i]+dep[j]+cnt-abs(rnk[col[i]]-rnk[col[j]])-1);
			ans-=1./(dep[i]+dep[j]+cnt-2);
		}
	}
	printf("%.10lf\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define  R register
using namespace std;
const int N=3100;

int n,tot,head[N],ver[N<<1],nex[N<<1];
int sta[N],top,sz,cir[N],col[N],dis[N],fa[N][20];
inline void add(int x,int y){
	ver[++tot]=y;nex[tot]=head[x];head[x]=tot;
}

inline int lca(int x,int y){
	if(dis[x]<dis[y]) swap(x,y);
	for(R int i=15;i>=0;i--) if(dis[fa[x][i]]>=dis[y]) x=fa[x][i];
	if(x==y) return x;
	for(R int i=15;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}

bool insta[N],incir[N];

inline bool find_circle(int x,int f){
	if(insta[x]){
		R int v;
		do{cir[++sz]=v=sta[top--];incir[v]=1;} while(v!=x);
		return 1;
	}
	sta[++top]=x;
	insta[x]=1;
	for(R int i=head[x];i;i=nex[i]){
		if(ver[i]==f) continue;
		if(find_circle(ver[i],x)) return 1;
	}
	sta[top--]=0;
	insta[x]=0;
	return 0;
}

inline void dfs(int x,int f,int be){
	col[x]=be;dis[x]=dis[f]+1;
	fa[x][0]=f;
	for(R int i=1;fa[x][i-1];i++) fa[x][i]=fa[fa[x][i-1]][i-1];
	for(R int i=head[x];i;i=nex[i]){
		if(ver[i]==f||incir[ver[i]]) continue;
		dfs(ver[i],x,be);
	}
}

double ans=0;

int main (){
	scanf("%d",&n);
	for(R int x,y,i=1;i<=n;i++){
		scanf("%d%d",&x,&y);x++;y++;
		add(x,y);add(y,x);
	}
	find_circle(1,0);
	for(R int i=1;i<=sz;i++) dfs(cir[i],0,i);//printf("%d	%d\n",i,cir[i]);
//	for(R int i=1;i<=n;i++) printf("%d	belongs to 	%d\n",i,col[i]);
	for(R int i=1;i<=n;i++){
		for(R int j=1;j<=n;j++){
			if(col[i]==col[j])  ans+=1.0/(dis[i]+dis[j]-2*dis[lca(i,j)]+1);
			else{
  				R int x=dis[i]+dis[j],y=abs(col[i]-col[j])-1,z=sz-2-y;
				ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
			}
//			printf("%d	%d	%lf\n",i,j,ans);
		}
	}
	printf("%.15lf\n",ans);
	return 0;
}


//by Sshwy
#include<algorithm>/*{{{*/
#include<cctype>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<vector>
using namespace std;
typedef pair<int,int> pii;
#define fi first
#define se second
#define pb push_back
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define ROF(i,a,b) for(int i=(a);i>=(b);--i)
namespace RA{
    int r(int p){return 1ll*rand()*rand()%p;}
    int r(int L,int R){return r(R-L+1)+L;}
}/*}}}*/
/******************heading******************/
const int N=3005;

vector<int> g[N];

int n;
double ans;
int dep[N],cir;
int a[N][2];

void dfs(int u,int p,int d){
    dep[u]=d;
    a[u][0]?a[u][1]=d:a[u][0]=d;
    for(int v:g[u])if(v!=p)dep[v]? cir=d-dep[v]+1:(dfs(v,u,d+1),0);
    dep[u]=0;
}
void calc(int u){
    memset(a,0,sizeof(a));
    cir=0;
    dfs(u,0,1);
    FOR(i,1,n){
        if(a[i][1])ans+=1.0/a[i][0]+1.0/a[i][1]-1.0/((a[i][0]+a[i][1]-2+cir)/2.0);
        else ans+=1.0/a[i][0];
    }
}
int main(){
    cin>>n;
    FOR(i,1,n){
        int u,v;
        cin>>u>>v;
        ++u,++v;
        g[u].pb(v),g[v].pb(u);
    }
    FOR(i,1,n)calc(i);
    printf("%.15lf",ans);
    return 0;
}


//by Sshwy
#include<algorithm>/*{{{*/
#include<cctype>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<vector>
using namespace std;
typedef pair<int,int> pii;
#define fi first
#define se second
#define pb push_back
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define ROF(i,a,b) for(int i=(a);i>=(b);--i)
namespace RA{
    int r(int p){return 1ll*rand()*rand()%p;}
    int r(int L,int R){return r(R-L+1)+L;}
}/*}}}*/
/******************heading******************/
const int N=3005;

vector<int> g[N];

int n;
double ans;
int dep[N],cir;
int a[N][2];

void dfs(int u,int p,int d){
    dep[u]=d;
    a[u][0]?a[u][1]=d:a[u][0]=d;
    for(int v:g[u])if(v!=p){
        if(dep[v]){//找到环
            cir=d-dep[v]+1;
            //printf("cir=%d\n",cir);
        }else {
            //printf("(%d,%d,%d) -> (%d,%d,%d)\n",u,p,d,v,u,d+1);
            dfs(v,u,d+1);
        }
    }
    dep[u]=0;
}
void calc(int u){
    //printf("calc(%d)\n",u);
    memset(dep,0,sizeof(dep));
    memset(a,0,sizeof(a));
    cir=0;
    dfs(u,0,1);
    //FOR(i,1,n)printf("%d%c",a[i][0]," \n"[i==n]);
    //FOR(i,1,n)printf("%d%c",a[i][1]," \n"[i==n]);
    FOR(i,1,n){
        if(a[i][1])ans+=1.0/a[i][0]+1.0/a[i][1]-1.0/((a[i][0]+a[i][1]-2+cir)/2.0);
        else ans+=1.0/a[i][0];
    }
}
int main(){
    cin>>n;
    FOR(i,1,n){
        int u,v;
        cin>>u>>v;
        ++u,++v;
        g[u].pb(v),g[v].pb(u);
    }
    FOR(i,1,n)calc(i);
    printf("%.15lf",ans);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3005;
int n,f,b,t1,t2,cnt,tot;
int deg[N],que[N],vis[N];
int p[N],noww[N<<1],goal[N<<1];
double ans;
void Link(int f,int t)
{
	noww[++cnt]=p[f];
	goal[cnt]=t,p[f]=cnt;
	noww[++cnt]=p[t];
	goal[cnt]=f,p[t]=cnt;
}
void DFS(int nde,int len,int cor)
{
	vis[nde]=true;
	if(deg[nde]==2) cor++;
	if(cor>=2) ans+=1.0/len+1.0/(len+tot-cor*2+2)-1.0/(len+tot-cor);
	else ans+=1.0/len;
	for(int i=p[nde],g;i;i=noww[i])
		if(!vis[g=goal[i]]) DFS(g,len+1,cor);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&t1,&t2),t1++,t2++;
		Link(t1,t2),deg[t1]++,deg[t2]++;
	}
	f=0,b=-1;
	for(int i=1;i<=n;i++)
		if(deg[i]==1) que[++b]=i;
	while(f<=b)
	{
		int tn=que[f++];
		for(int i=p[tn],g;i;i=noww[i])
			if((--deg[g=goal[i]])==1) que[++b]=g;
	}
	for(int i=1;i<=n;i++) tot+=(deg[i]==2);
	for(int i=1;i<=n;i++)
		memset(vis,0,sizeof vis),DFS(i,1,0);
	printf("%.7f",ans);
	return 0;
}


/*
»·Ì×Ê÷Ëæ»úµã·Ö¡£
ÏÈÃ¶¾ÙÒ»¸öiËãiÔÚµã·ÖÊ÷ÉÏÆÚÍûÉî¶È
Õâ¸öÆÚÍûÉî¶È=\sum_j P[jÊÇiµÄ×æÏÈ]
Õâ¸ö¸ÅÂÊÓÖµÈ¼ÛÓÚÄÜÕÒµ½Ò»Ìõiµ½jµÄÂ·¾¶,Ê¹µÃjÊÇÂ·¾¶ÉÏ×îÏÈ±»É¾È¥µÄµã¡£
¿¼ÂÇÃ¶¾ÙÂ·¾¶¼¯ÈÝ³â¼´¿É£¬±¾ÌâÖ»ÐèÒª¿¼ÂÇ½öÓÐµÄÒ»¸ö´ó»·¡£
*/

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int N=3005;

int n,fa[N],dfn[N],ord,mark[N],len,vis[N];
vector<int>G[N];

void dfs(int u)
{
	dfn[u]=++ord;
	for(auto&v:G[u])
		if(v^fa[u])
		{
			if(!dfn[v])
			{
				fa[v]=u;
				dfs(v);
			}
			else if(dfn[v]<dfn[u])
			{
				for(int p=u; p!=fa[v]; p=fa[p])
					mark[p]=1,++len;
			}
		}
}

double ans;

void dfs1(int u,int x,int y)
{
	vis[u]=1;
	++x;
	if(!y)
		ans+=1.0/x;
	else
	{
		ans+=1.0/x;
		ans+=1.0/(len-y-y+x);
		ans-=1.0/(x+len-y-1);
	}
	for(auto&v:G[u])
		if(!vis[v])
			dfs1(v,x,y+(mark[u]&&mark[v]));
}

int main()
{
	scanf("%d",&n);
	for(int i=1,a,b; i<=n; i++)
	{
		scanf("%d%d",&a,&b);
		++a;++b;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	dfs(1);
	for(int i=1; i<=n; i++)
	{
		fill(vis,vis+1+n,0);
		dfs1(i,0,0);
	}
	printf("%.9f",ans);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,flag,sum,tot,dis[3001][3001],e[100001],nt[100001],hd[100001],pa[100001],v[3001],d[3001],f[3001],sz[3001];
double ans;
void build(int x,int y){
	tot++;
	e[tot]=y;
	nt[tot]=hd[x];hd[x]=tot;
}
void dfs(int x,int fa){
	int i,y;
	if(v[x]){
		y=fa;
		d[x]=1;
		sum=1;
		while(y!=x){
			sum++;
			d[y]=sum;
			y=pa[y];
		}
		flag=1;
		return;
	}
	v[x]=1;
	for(i=hd[x];i;i=nt[i]){
		if(e[i]==fa)continue;
		pa[e[i]]=x;
		dfs(e[i],x);
		if(flag)return;
	}
}
void get(int x,int len,int fa){
	int i;
	//printf("%d %d %d\n",x,len,fa);
	if(d[x]&&!flag){
		flag=1;
		sz[fa]=len;
		f[fa]=d[x];
	}
	v[x]=1;
	dis[fa][x]=len;
	for(i=hd[x];i;i=nt[i]){
		if(v[e[i]])continue;
		get(e[i],len+1,fa);
	}
}
int main(){
	int i,j,x,y;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		x++;y++;
		build(x,y);build(y,x);
	}
	dfs(1,0);
	//printf("%d\n",sum);
	//for(i=1;i<=n;i++)printf("%d ",d[i]);puts("");
	for(i=1;i<=n;i++){
		flag=0;
		memset(v,0,sizeof(v));
		get(i,1,i);
		//printf("%d %d\n",f[i],sz[i]);
	}
	for(i=1;i<=n;i++){
	 for(j=1;j<=n;j++){
	 	//printf("%d %d\n",i,j);
	 	if(i==j)ans+=1;
	 	 else if(f[i]==f[j])ans+=1/(1.0*abs(dis[i][j]));
	 	  else{
	 	  	x=abs(f[i]-f[j])-1;
	 	  	y=sum-2-x;
	 	  	ans+=1.0/(sz[i]+sz[j]+x)+1.0/(sz[i]+sz[j]+y)-1.0/(sz[i]+sz[j]+x+y);
		   }
	 }
	 //printf("%d %.5lf\n",i,ans);
}
	printf("%.10lf",ans);
}


#include <cstdio>

const int MAXN = 3000;

struct edge{
	int to; edge *nxt;
}edges[2*MAXN + 5], *adj[MAXN + 5], *ecnt = edges;
void addedge(int u, int v) {
	edge *p = (++ecnt);
	p->to = v, p->nxt = adj[u], adj[u] = p;
	p = (++ecnt);
	p->to = u, p->nxt = adj[v], adj[v] = p;
}
#define rep(x) for(edge *p=adj[x];p;p=p->nxt)

bool vis[MAXN + 5], tag[MAXN + 5];
int a[MAXN + 5], cnt, siz;
void dfs1(int x, int f) {
	vis[a[++cnt] = x] = true;
	rep(x) {
		if( p->to == f ) continue;
		if( vis[p->to] ) {
			siz = 0;
			for(int j=cnt;;j--) {
				tag[a[j]] = true, siz++;
				if( a[j] == p->to ) break;
			}
		}
		else dfs1(p->to, x);
		if( siz ) break;
	}
	a[cnt--] = 0, vis[x] = false;
}

double ans;

double get(int s, int d) {
	if( s >= 2 ) {
		int p = s - 2, q = siz - s, r = d - s + 2;
		return 1.0 / (r + p) + 1.0 / (r + q) - 1.0 / (r + p + q);
	}
	else return 1.0 / d;
}
void dfs2(int x, int s, int d) {
	vis[x] = true, d++;
	if( tag[x] ) s++;
	ans += get(s, d);
	rep(x) {
		if( vis[p->to] ) continue;
		dfs2(p->to, s, d);
	}
}

int main() {
	int n; scanf("%d", &n);
	for(int i=1;i<=n;i++) {
		int a, b; scanf("%d%d", &a, &b);
		addedge(a + 1, b + 1);
	}
	dfs1(1, 0);
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=n;j++) vis[j] = false;
		dfs2(i, 0, 0);
	}
	printf("%.9f\n", ans);
}