#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
	double y,a,b,c,z;
	vector<int>t;
	string s;
	map<double,int>mp;
	vector<int>o;
	cin>>y;
	for(int i=0;i<y;i++)
	{
		cin>>s;
		int r=2;
		while(s.substr(r,1)!="+")
			r++;
		//cout<<r<<endl;
		a=stoi(s.substr(1,r-1));
		//cout<<a<<endl;
		int e=r;
		while(s.substr(e,1)!="/")
			e++;
		//cout<<e<<endl;
		b=stoi(s.substr(r+1,e-1-r));
		//cout<<b<<endl;
		int si=s.size()-e;
		c=stoi(s.substr(e+1,si));
	//cout<<a<<b<<c;
		z=(a+b)/c;
		mp[z]++;
		o.push_back(z);

	}
	while(!o.empty())
	{
		//cout<<o.front()<<" ";
		t.push_back(mp[o.front()]);
		o.erase(o.begin());
	}

	while(!t.empty())
	{
		cout<<t.front()<<" ";
		t.erase(t.begin());
	}

 return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
	double y,a,b,c,z;
	vector<double>t;
	char s;
	map<double,int>mp;
	vector<double>o;
	cin>>y;
	for(int i=0;i<y;i++)
	{
		cin>>s>>a>>s>>b>>s>>s>>c;
		z=(a+b)/c;
		mp[z]++;
		o.push_back(z);
	}
	while(!o.empty())
	{
		cout<<mp[o.front()]<<" ";
		o.erase(o.begin());
	}

 return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
	double y,a,b,c,z;
	vector<double>t;
	char s;
	map<double,int>mp;
	vector<double>o;
	cin>>y;
	for(int i=0;i<y;i++)
	{
		cin>>s>>a>>s>>b>>s>>s>>c;
		z=(a+b)/c;
		mp[z]++;
		o.push_back(z);
	}
	for(int i=0;i<y;i++)
	{
		cout<<mp[o[i]]<<" ";

	}

 return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
	double y,a,b,c,z;
	vector<double>t;
	string s;
	map<double,int>mp;
	vector<double>o;
	cin>>y;
	for(int i=0;i<y;i++)
	{
		cin>>s;
		int r=2;
		while(s.substr(r,1)!="+")
			r++;
		//cout<<r<<endl;
		a=stoi(s.substr(1,r-1));
		//cout<<a<<endl;
		int e=r;
		while(s.substr(e,1)!="/")
			e++;
		//cout<<e<<endl;
		b=stoi(s.substr(r+1,e-1-r));
		//cout<<b<<endl;
		int si=s.size()-e;
		c=stoi(s.substr(e+1,si));
	//cout<<a<<b<<c;
		z=(a+b)/c;
		mp[z]++;
		o.push_back(z);

	}
	while(!o.empty())
	{
		//cout<<o.front()<<" ";
		t.push_back(mp[o.front()]);
		o.erase(o.begin());
	}

	while(!t.empty())
	{
		cout<<t.front()<<" ";
		t.erase(t.begin());
	}

 return 0;
}


#include<iostream>
#include<map>
#include<cstdlib>
using namespace std;
int main()
{
	int n;
	cin >> n;
	map<double, int>m;
	double a, b, d, *r;
	r = (double*)malloc(sizeof(double)*n);
	char c;
	for (int i = 0; i < n; i++)
	{
		cin >> c >> a >> c >> b >> c >> c >> d;
		r[i] = (a + b) / d;
		m[r[i]]++;
	}
	for (int i = 0; i < n; i++)
	{
		cout << m[r[i]] << " ";
	}
	return 0;
}


#include<cstdio>
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<tuple>
#include<set>
#include<utility>
#include<map>
#include <unordered_map>
#include <bitset>
using namespace std;
typedef long long ll;
int N, A[200004], D[204];
int main() {
	int i, a, b, c, x; char c1, c2, c3, c4;
	cin >> N;
	for (i = 1; i <= N; i++) {
		cin >> c1 >> a >> c2 >> b >> c3 >> c4 >> c;
		x = (a + b) / c;
		A[i] = x; D[x]++;
	}
	for (i = 1; i <= N; i++) cout << D[A[i]] << " ";
}


#include<cstdio>
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<tuple>
#include<set>
#include<utility>
#include<map>
#include <unordered_map>
#include <bitset>
using namespace std;
typedef long long ll;
int N, A[200004], B[200004], D[204][104];
int gcd(int x, int y) {
	int t;
	if (x > y) swap(x, y);
	while (x) {
		t = y%x;
		y = x;
		x = t;
	}
	return y;
}
int main() {
	int i, a, b, c, x, y, z; char c1, c2, c3, c4;
	cin >> N;
	for (i = 1; i <= N; i++) {
		cin >> c1 >> a >> c2 >> b >> c3 >> c4 >> c;
		x = gcd(a + b, c);
		y = (a + b) / x;
		z = c / x;
		A[i] = y; B[i] = z; D[y][z]++;
	}
	for (i = 1; i <= N; i++) cout << D[A[i]][B[i]] << " ";
}


#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
int main()
{
	map <double, int> a;
	string s, s1, s2, s3;
	int n;

	double first, second, third, res;
	cin >> n;
	vector <double>b(n);
	for (int i = 0;i < n;i++)
	{
		first = 0.0;
		second = 0.0;
		third = 0.0;
		s1 = "";
		s2 = "";
		s3 = "";
		cin >> s;
		s1 = s.substr(1, s.find('+') - 1);
		s2 = s.substr(s.find('+') + 1, s.find(")") - s.find('+') - 1);
		s3 = s.substr(s.find('/') + 1, s.size());
		first = atof(s1.c_str());
		second = atof(s2.c_str());
		third = atof(s3.c_str());
		res = (first + second) / third;
		a[res]++;
		b[i] = res;

	}
	for (int i = 0;i < n;i++)
	{
		cout << a[b[i]]<<" ";
	}
	return 0;
}


#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
	map <double, int> a;
	string s, s1, s2, s3;
	int n;

	double first, second, third, res;
	cin >> n;
	double b[100000];
	for (int i = 0;i < n;i++)
	{
		first = 0.0;
		second = 0.0;
		third = 0.0;
		s1 = "";
		s2 = "";
		s3 = "";
		cin >> s;
		s1 = s.substr(1, s.find('+') - 1);
		s2 = s.substr(s.find('+') + 1, s.find(")") - s.find('+') - 1);
		s3 = s.substr(s.find('/') + 1, s.size());
		first = atof(s1.c_str());
		second = atof(s2.c_str());
		third = atof(s3.c_str());
		res = (first + second) / third;
		a[res]++;
		b[i] = res;

	}
	for (int i = 0;i < n;i++)
	{
		cout << a[b[i]]<<" ";
	}
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <functional>
using namespace std;

typedef long long ll;

int n;
map<int, int> p;
ll q[200009];

int main()
{
	cin >> n;

	int a, b, c;
	for (int i = 0; i < n; i++) {
		char tmp;
		cin >> tmp;
		scanf("%d+%d)/%d", &a, &b, &c);
		q[i] = (a + b) / c;
		p[q[i]]++;
	}

	for (int i = 0; i < n; i++)
		cout << p[q[i]] << " ";

	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <functional>
using namespace std;

typedef long long ll;

int n;
map<double, int> p;
double q[200009];

int main()
{
	cin >> n;

	int a, b, c;
	for (int i = 0; i < n; i++) {
		char tmp;
		cin >> tmp;
		scanf("%d+%d)/%d", &a, &b, &c);
		q[i] = 1.0 * (a + b) / c;
		p[q[i]]++;
	}

	for (int i = 0; i < n; i++)
		cout << p[q[i]] << " ";

	return 0;
}


n=int(input())

id=[0]*n
dict={}

for i in range(n):
    s=input()
    id[i]=eval(s)
    if id[i] not in dict:
        dict[id[i]]=1
    else:
        dict[id[i]]+=1

for i in range(n):
    print(dict[id[i]],end=' ')


n = int(input())
lst = []
d = dict()
for temp in range(n):
  input_str, z = input().split('/')
  x, y = input_str.split('+')
  x = x [1:]
  y = y [:len(y)-1]
  x = int(x)
  y = int(y)
  z = int(z)
  ans = (x+y)/z
  if(ans in d.keys()) : d[ans]+=1
  else : d[ans]=1
  lst.append(ans)
for i in lst:
  print(d[i], end=" ")


a = int(input())
k = []
z = [0]*a
for i in range(a):
    k.append(eval(input()))
for i in range(a):
    z[i] = k.count(k[i])
    print(z[i],end=" ")


n = int(input())
tot = [0.5 for i in range(n)]
output = []
for i in range(n):
    z = input()
    a = int(z[z.find('(')+1:z.find('+')])
    b = int(z[z.find('+')+1:z.find(')')])
    c = int(z[z.find('/')+1:])
    tot[i] = (a+b)/c
    output.append(1)
for i in range(n-1):
    for j in range(i+1, n):
        if tot[i] == tot[j]:
            output[i] += 1
            output[j] += 1
for i in range(len(output)):
    print(output[i], ' ', end="")


a = int(input())
dict = {}
k = []
for i in range(a):
    l = eval(input())
    k.append(l)
    if l not in dict:
        dict[l] = 1
    else:
        dict[l] += 1
for i in range(a): print(dict[k[i]],end=" ")


n=int(input())
dict1={}
dict2={}
for i in range(n):
    s=input()
    s=s.split('/')
    c=int(s[1])
    s=s[0].strip('(').strip(')').split('+')
    a=int(s[0])
    b=int(s[1])
    ans=(a+b)/c
    try:
        dict2[ans] += 1
    except:
        dict2[ans] = 1
    dict1[i] = ans
for i in range(n):
    print(dict2[dict1[i]],end=' ')


d = {}
l =[]
for i in range(int(input())):
    a,b,c = map(int,input().replace("(","").replace(")/"," ").replace("+"," ").split())
    ans = (a+b)/c
    l.append(ans)
    if ans in d: d[ans]+=1
    else: d[ans]=1

for i in l:
    print(d[i],end=" ")


d = {}
l =[]
for i in range(int(input())):
    a,b,c = map(int,input().replace("(","").replace(")/"," ").replace("+"," ").split())
    ans = (a+b)//c
    l.append(ans)
    if ans in d: d[ans]+=1
    else: d[ans]=1

for i in l:
    print(d[i],end=" ")


def fun(str):
    list = str.split('/')
    dem = int(list[1])
    list = list[0]
    list = list[1:-1]
    list1 = list.split('+')
    num = int(list1[0]) + int(list1[1])
    return num//dem

dict = {}
list = []
n = int(input())
while( n != 0):
    n = n-1
    str = input()
    ans = fun(str)
    if ans in dict:
        dict[ans] = dict[ans]+1
    else:
        dict[ans] = 1
    list.append(ans)

for i in range(len(list)):
    print (dict[list[i]], end=" ")


def fun(str):
    list = str.split('/')
    dem = int(list[1])
    list = list[0]
    list = list[1:-1]
    list1 = list.split('+')
    num = int(list1[0]) + int(list1[1])
    return num/dem

dict = {}
list = []
n = int(input())
while( n != 0):
    n = n-1
    str = input()
    ans = fun(str)
    if ans in dict:
        dict[ans] = dict[ans]+1
    else:
        dict[ans] = 1
    list.append(ans)

for i in range(len(list)):
    print (dict[list[i]], end=" ")


from collections import Counter
from math import gcd

m = int(input())

ans = list()

for i in range(m):
    s = input()

    a = int(s[1:s.index('+')])
    b = int(s[s.index('+') + 1: s.index(')')])
    c = int(s[s.index('/') + 1:])

    d = a + b

    g = gcd(c, d)

    ans.append(tuple([d // g, c // g]))

C = Counter(ans)

print(' '.join(map(str, [C[el] for el in ans])))


from collections import Counter

def getList(l, m):
  r = []
  cnt = Counter(l)
  for i in l:
    r.extend([cnt[i]])
  return r

m = int(input())
res = []
for i in range(m):
  a, b = [i for i in input().split("/")]
  a = a.split("+")
  a = [a[0].replace("(", ""), a[len(a) - 1].replace(")", "")]
  a = list(map(lambda x: int(x), a)); b = float(b)
  res.extend([sum(a)/b])

output = getList(res, m) + ["\n"]
for i in output:
  print(str(i) + " ", end = "")


from collections import Counter

def getList(l, m):
  r = []
  cnt = Counter(l)
  for i in l:
    r.extend([cnt[i]])
  return r

m = int(input())
res = []
for i in range(m):
  a, b = [i for i in input().split("/")]
  a = a.split("+")
  aux1 = a[0].replace("(", "")
  aux2 = a[len(a) - 1].replace(")", "")
  a = [aux1, aux2]
  a = list(map(lambda x: int(x), a))
  b = float(b)
  res.extend([sum(a)/b])
print(getList(res, m))


from collections import Counter

def getList(l, m):
  r = []
  cnt = Counter(l)
  for i in l:
    r.extend([cnt[i]])
  return r

m = int(input())
res = []
for i in range(m):
  a, b = [i for i in input().split("/")]
  a = a.split("+")
  aux1 = a[0].replace("(", "")
  aux2 = a[len(a) - 1].replace(")", "")
  a = [aux1, aux2]
  a = list(map(lambda x: int(x), a))
  b = float(b)
  res.extend([sum(a)/b])

output = getList(res, m)
for i in range(len(output)):
  if i == len(output) - 1: print(output[i])
  else: print(str(output[i]) + " ", end = "")


m = int(input())
l = []
dict1 = {}
for i in range(m):
    k = input().split("/")
    k[0] = k[0][1:len(k[0])-1]
    k[0] = k[0].split("+")
    val = (int(k[0][0]) + int(k[0][1]))/(int(k[1]))
    if(val in dict1):
        dict1[val] += 1
    else:
        dict1[val] = 1
    l.append(val)
for i in l:
    print(dict1[i],end = " ")


n=int(input())
a=[0]*n
for i in range(n):
    s=input()
    x,y=s.split('+')
    x=float(x[1:])
    u,v=y.split('/')
    v=float(v)
    u=float(u[:-1])
    a[i]=(x+u)/v
k={}
for i in range(n):
    if a[i] not in k:
        k[a[i]]=0
    k[a[i]]+=1
o=[0]*n
for i in range(n):
    o[i]=str(k[a[i]])
print(' '.join(o))


import re

n = int(input())
ships = {}
lst = []
r = re.compile('\((\d+)\+(\d+)\)\/(\d+)')

for i in range(n):
    line = input()
    m = r.match(line)
    coord = (int(m.group(1)) + int(m.group(2)))/int(m.group(3))
    ships[coord] = ships.get(coord, 0) + 1
    lst.append(coord)

for k in lst:
    print(ships[k])
    pass


n=int(input())
ct = {}
ctx = []
for ni in range(0, n):
	st = input().strip()[1:]
	p1 = st.index('+')
	a = int(st[:p1])
	st = st[p1+1:]
	p2 = st.index(')')
	b = int(st[:p2])
	c = int(st[p2+2:])
	v = ((a+b)/c)
	if v in ct: ct[v]+=1
	else: ct[v]=1
	ctx.append(v)
st = []
for cti in ctx: st.append(str(ct[cti]))
print(" ".join(st))


import re
n = int(input())
A = []
B = []
freq = {}
myDict1 = {}
for i in range(n):
    A.append(0)
for i in range(10**6):
    B.append(0)
for i in range(n):
    a = input()
    a = a.split('(')
    a = a[1].split('+')
    b = a[0];
    c = a[1].split(')')
    d = c[0]
    e = c[1].split('/')[1]
    ans = (int(b)+int(d))/int(e)
    if(ans in freq):
        freq[ans] += 1
    else:
        freq[ans] = 1
    myDict1[i] = ans
for key,value in myDict1.items():
    print(freq[value],end = " ")


x=int(input())
cnt={}
queue={}
a=set([])
for i in range(x):
    each=eval(input())
    if (each in a)==False:
        cnt[each]=0
    cnt[each]+=1
    queue[i]=each
    a.add(each)
for i in range(x):
    print(cnt[queue[i]],end=' ')


x=int(input())
cnt={}
queue={}
for i in range(x):
    each=eval(input())
    queue[i]=each
for i in range(x):
    count=1
    for j in range(x):
        if queue[j]==queue[i] and j!=i:
            count+=1
    print(count,end=' ')


x = int(input())
a = []
for i in range(x):
	s = input()
	a.append(eval(s))
b = []
for i in range(x):
	b.append(a.count(a[i]))
print(*b)


x = int(input())
a = []
b = dict()
for i in range(x):
	s = input()
	a.append(eval(s))
	if(a[i] not in b):
		b[a[i]] = 1
	else:
		b[a[i]] += 1

for i in range(x):
	print("%d "%b[a[i]], end = '')
print()


n=int(input())
d={}
for i in range(n):
    s=input()
    s=s.replace('(','')
    s=s.replace(')','')
    s=s.split('/')
    c=float(s[-1])
    s=s[0]
    s=s.split('+')
    a=float(s[0])
    b=float(s[1])
    ans=(a+b)/c
    if ans in d:
        d[ans].append(i)
    else:
        d[ans]=[i]
l=[0]*n
for k in d.keys():
    for i in d[k]:
        l[i]=str(len(d[k]))
print(' '.join(l))


m=int(input())
ans=[]
f={}
for _ in range(m):
    n=input()
    a=n.split('(')
    b=a[1].split(')')
    ad,bd=b[0].split('+')
    cd=b[1].split('/')[1]
    ans.append((int(ad)+int(bd))/int(cd))
    f[_]=(int(ad)+int(bd))/int(cd)
freq = {}
for item in ans:
    if (item in freq):
        freq[item] += 1
    else:
        freq[item] = 1

for i in range(m):
    print(freq[f[i]],end=" ")


def gcd(x, y):
    while y:
        x, y = y, x % y
    return x

n = int(input())
cnt = [0 for i in range(20000)]
v = [0 for i in range(n)]
for i in range(n):
    num, den = input().split("/")
    num = eval(num)
    den = eval(den)
    g = gcd(num, den)
    num //= g
    den //= g
    key = num * 100 + den
    v[i] = key
    cnt[key] += 1

for i in range(n):
    print(cnt[v[i]], end=" ")
print()


n = int(input())
arr = []
cc = {}
for i in range(n):
	line = input()
	ab, c = line.split('/')
	ab = ab[1:-1]
	a, b = ab.split('+')
	a, b, c = [int(x) for x in (a, b, c)]
	p = (a + b) // c
	arr.append(p)
	if p not in cc:
		cc[p] = 1
	else:
		cc[p] += 1
for i in range(n):
	if i > 0:
		print(' ', end="")
	print(cc[arr[i]], end="")


from fractions import Fraction
n = int(input())
arr = []
cc = {}
for i in range(n):
	line = input()
	ab, c = line.split('/')
	ab = ab[1:-1]
	a, b = ab.split('+')
	a, b, c = [int(x) for x in (a, b, c)]
	p = (a + b) / c
	arr.append(p)
	if p not in cc:
		cc[p] = 1
	else:
		cc[p] += 1
for i in range(n):
	if i > 0:
		print(' ', end="")
	print(cc[arr[i]], end="")


from fractions import Fraction
n = int(input())
arr = []
cc = {}
for i in range(n):
	line = input()
	ab, c = line.split('/')
	ab = ab[1:-1]
	a, b = ab.split('+')
	a, b, c = [int(x) for x in (a, b, c)]
	p = Fraction(a + b, c)
	arr.append(p)
	if p not in cc:
		cc[p] = 1
	else:
		cc[p] += 1
for i in range(n):
	if i > 0:
		print(' ', end="")
	print(cc[arr[i]], end="")


from fractions import gcd

ans = []
dic = {}

n = int(input())
for i in range(n):
  word = input()
  word = word.replace('(',',')
  word = word.replace('+',',')
  word = word.replace(')/',',')
  w = word.split(',')
  a = int(w[1])
  b = int(w[2])
  numerator = a + b
  denumerator = int(w[3])
  x = numerator // gcd(numerator, denumerator)
  y = denumerator // gcd(numerator, denumerator)
  ans.append((x, y))
  if (x, y) in dic:
    dic[(x, y)] += 1
  else:
    dic[(x, y)] = 1
for i in range(n):
  if i > 0:
    print(' ', end='')
  print(dic[ans[i]], end='')
print("\n", end='')


from collections import defaultdict
d = defaultdict(lambda : 0)

a = []
for _ in range(int(input())):
    s = input()
    a.append(s)
    d[eval(s)] += 1

for e in a:
    print(d[eval(e)], end = ' ')


# from dust i have come dust i will be

n=int(input())

id=[0]*n
dict={}

for i in range(n):
    s=input()
    id[i]=eval(s)
    if id[i] not in dict:
        dict[id[i]]=1
    else:
        dict[id[i]]+=1

for i in range(n):
    print(dict[id[i]],end=' ')


# from dust i have come dust i will be

n=int(input())

id=[None]*n
dict={}

for i in range(n):
    s=input()
    id[i]=int(eval(s))

    if id[i] not in dict:
        dict[id[i]]=1
    else:
        dict[id[i]]+=1

for i in range(n):
    print(dict[id[i]])


n=int(input())
dict1={}
dict2={}
for i in range(n):
    s=input()
    s=s.split('/')
    c=int(s[1])
    s=s[0].strip('(').strip(')').split('+')
    a=int(s[0])
    b=int(s[1])
    ans=(a+b)/c
    try:
        dict2[ans] += 1
    except:
        dict2[ans] = 1
    dict1[i] = ans
for i in range(n):
    print(dict2[dict1[i]],end=' ')


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <ctime>
#include <algorithm>
#define N 3123
template <typename T> inline void read(T &x) {
	x = 0; char c = getchar(); bool flag = false;
	while (!isdigit(c)) { if (c == '-')	flag = true; c = getchar(); }
	while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
	if (flag)	x = -x;
}
using namespace std;
int n;
struct edge{
	int nxt;
	int to;
}e[N << 1];
int head[N], ecnt = 1;
inline void addedge(int from, int to) {
	e[++ecnt] = (edge){head[from], to};
	head[from] = ecnt;
}
int d[N];
int que[N], front, rear;
bool notcir[N];//node
bool incir[N];//edge
inline void topo() {
	for (register int i = 1; i <= n; ++i)
		if (d[i] == 1)	que[++rear] = i, notcir[i] = true;
	while (front < rear) {
		int cur = que[++front];
		for (register int i= head[cur]; i; i = e[i].nxt) {
			int to = e[i].to; if (notcir[to])	continue;
			--d[to];
			if (d[to] == 1) {
				notcir[to] = true;
				que[++rear] = to;
			}
		}
	}
	for (register int p = 1; p <= n; ++p) if (!notcir[p]) {
		for (register int i = head[p]; i; i = e[i].nxt) {
			int to = e[i].to; if (notcir[to])	continue;
			incir[i] = true;
		}
	}
}
double f[N][N];
void dfs_in_tree(int u, int cur, int depp) {
	if (f[u][cur])	return ;
	//printf("depp = %d\n", depp);
	f[u][cur] = f[cur][u] = 1.0 / depp;
	for (register int i= head[cur]; i; i = e[i].nxt) {
		int to = e[i].to; if (incir[i])	continue;
		dfs_in_tree(u, to, depp + 1);
	}
}
int h[N], htot;
bool vis[N];
void find_cir(int cur) {
	h[++htot] = cur;
	vis[cur] = true;
	for (register int i = head[cur]; i; i = e[i].nxt) if (incir[i]) {
		int to = e[i].to; if (!vis[to])	find_cir(to);
	}
}
void dfs3(int cur, int u, int y, int z, int x, int faa) {
	f[cur][u] = f[u][cur] = 1.0 / (x + y) + 1.0 / (x + z) - 1.0 / (x + y + z);
	//printf("x = %d, y = %d, z=  %d\n", x, y, z);
	for (register int i= head[cur]; i; i = e[i].nxt) if (!incir[i]) {
		int to = e[i].to; if (to == faa)	continue;
		dfs3(to, u, y, z, x + 1, cur);
	}
}
void dfs2(int cur, int v, int y, int z, int x, int faa) {
	dfs3(v, cur, y, z, x + 1, 0);
	for (register int i = head[cur]; i; i = e[i].nxt) if (!incir[i]) {
		int to = e[i].to; if (to == faa)	continue;
		dfs2(to, v, y, z, x + 1, cur);
	}
}
inline void Cir() {
	for (register int i = 1; i <= n; ++i) {
		if (!notcir[i]) {
			find_cir(i);
			break;
		}
	}
	for (register int i = 1; i <= htot; ++i) {
		for (register int j = i + 1; j <= htot; ++j) {
			dfs2(h[i], h[j], j - i - 1, htot - j + i - 1, 1, 0);
		}
	}
}
int main() {
	read(n);
	for (register int i = 1; i <= n; ++i) {
		int u, v; read(u), read(v); ++u, ++v;
		addedge(u, v), addedge(v, u);
		++d[u], ++d[v];
	}
	topo();
	for (register int i = 1; i <= n; ++i) {
		dfs_in_tree(i, i, 1);
	}
	Cir();
	double res = 0;
	for (register int i = 1; i <= n; ++i) {
		for (register int j = 1; j <= n; ++j) {
			res += f[i][j];
			/*
			if (f[i][j] <= 0.003) {
				printf("WA!!!i = %d, j = %d\n", i, j);
			}
			*/
		}
	}
	printf("%.10lf\n", res);
	return 0;
}

/*
5
3 4
2 3
2 4
0 4
1 2
//13.16666667

3
0 1
1 2
0 2
//6

5
0 1
1 2
2 0
3 0
4 1
//13.1666666666
*/


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <ctime>
#include <algorithm>
#define N 4223
template <typename T> inline void read(T &x) {
	x = 0; char c = getchar(); bool flag = false;
	while (!isdigit(c)) { if (c == '-')	flag = true; c = getchar(); }
	while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
	if (flag)	x = -x;
}
using namespace std;
int n;
struct edge{
	int nxt;
	int to;
}e[N << 1];
int head[N], ecnt = 1;
inline void addedge(int from, int to) {
	e[++ecnt] = (edge){head[from], to};
	head[from] = ecnt;
}
int d[N];
int que[N << 1], front, rear;
bool notcir[N];//node
bool incir[N << 1];//edge
inline void topo() {
	for (register int i = 1; i <= n; ++i)
		if (d[i] == 1)	que[++rear] = i, notcir[i] = true;
	while (front < rear) {
		int cur = que[++front];
		for (register int i= head[cur]; i; i = e[i].nxt) {
			int to = e[i].to; if (notcir[to])	continue;
			--d[to];
			if (d[to] == 1) {
				notcir[to] = true;
				que[++rear] = to;
			}
		}
	}
	for (register int p = 1; p <= n; ++p) if (!notcir[p])
		for (register int i = head[p]; i; i = e[i].nxt) {
			int to = e[i].to; if (notcir[to])	continue;
			incir[i] = true;
		}
}
double f[N][N];
void dfs_in_tree(int u, int cur, int depp, int faa) {
	f[u][cur] = f[cur][u] = 1.0 / depp;
	for (register int i= head[cur]; i; i = e[i].nxt) {
		int to = e[i].to; if (incir[i] || to == faa)	continue;
		dfs_in_tree(u, to, depp + 1, cur);
	}
}
int h[N], htot;
bool vis[N];
void find_cir(int cur) {
	h[++htot] = cur;
	vis[cur] = true;
	for (register int i = head[cur]; i; i = e[i].nxt) if (incir[i]) {
		int to = e[i].to; if (!vis[to])	find_cir(to);
	}
}
void dfs3(int cur, int u, int y, int z, int x, int faa) {
	f[cur][u] = f[u][cur] = 1.0 / (x + y) + 1.0 / (x + z) - 1.0 / (x + y + z);
	for (register int i= head[cur]; i; i = e[i].nxt) if (!incir[i]) {
		int to = e[i].to; if (to == faa)	continue;
		dfs3(to, u, y, z, x + 1, cur);
	}
}
void dfs2(int cur, int v, int y, int z, int x, int faa) {
	dfs3(v, cur, y, z, x + 1, 0);
	for (register int i = head[cur]; i; i = e[i].nxt) if (!incir[i]) {
		int to = e[i].to; if (to == faa)	continue;
		dfs2(to, v, y, z, x + 1, cur);
	}
}
inline void Cir() {
	for (register int i = 1; i <= n; ++i)
		if (!notcir[i]) {
			find_cir(i);
			break;
		}
	for (register int i = 1; i <= htot; ++i)
		for (register int j = i + 1; j <= htot; ++j)
			dfs2(h[i], h[j], j - i - 1, htot - j + i - 1, 1, 0);
}
int main() {
	read(n);
	for (register int i = 1; i <= n; ++i) {
		int u, v; read(u), read(v); ++u, ++v;
		addedge(u, v), addedge(v, u);
		++d[u], ++d[v];
	}
	topo();
	for (register int i = 1; i <= n; ++i)
		dfs_in_tree(i, i, 1, 0);
	Cir();
	double res = 0;
	for (register int i = 1; i <= n; ++i)
		for (register int j = 1; j <= n; ++j)
			res += f[i][j];
	printf("%.10lf\n", res);
	return 0;
}

/*
5
3 4
2 3
2 4
0 4
1 2
//13.16666667

3
0 1
1 2
0 2
//6

5
0 1
1 2
2 0
3 0
4 1
//13.1666666666

7
0 1
1 2
2 0
2 3
2 4
0 5
1 6
//22.5
*/


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <ctime>
#include <algorithm>
#define N 4223
template <typename T> inline void read(T &x) {
	x = 0; char c = getchar(); bool flag = false;
	while (!isdigit(c)) { if (c == '-')	flag = true; c = getchar(); }
	while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); }
	if (flag)	x = -x;
}
using namespace std;
int n;
struct edge{
	int nxt;
	int to;
}e[N << 1];
int head[N], ecnt = 1;
inline void addedge(int from, int to) {
	e[++ecnt] = (edge){head[from], to};
	head[from] = ecnt;
}
int d[N];
int que[N << 1], front, rear;
bool notcir[N];//node
bool incir[N << 1];//edge
inline void topo() {
	for (register int i = 1; i <= n; ++i)
		if (d[i] == 1)	que[++rear] = i, notcir[i] = true;
	while (front < rear) {
		int cur = que[++front];
		for (register int i= head[cur]; i; i = e[i].nxt) {
			int to = e[i].to; if (notcir[to])	continue;
			--d[to];
			if (d[to] == 1) {
				notcir[to] = true;
				que[++rear] = to;
			}
		}
	}
	for (register int p = 1; p <= n; ++p) if (!notcir[p]) {
		for (register int i = head[p]; i; i = e[i].nxt) {
			int to = e[i].to; if (notcir[to])	continue;
			incir[i] = true;
		}
	}
}
double f[N][N];
void dfs_in_tree(int u, int cur, int depp, int faa) {
	//if (f[u][cur])	return ;
	//printf("dit : u = %d, cur = %d\n", u, cur);
	//printf("depp = %d\n", depp);
	f[u][cur] = f[cur][u] = 1.0 / depp;
	for (register int i= head[cur]; i; i = e[i].nxt) {
		int to = e[i].to; if (incir[i] || to == faa)	continue;
		dfs_in_tree(u, to, depp + 1, cur);
	}
}
int h[N], htot;
bool vis[N];
void find_cir(int cur) {
	h[++htot] = cur;
	vis[cur] = true;
	for (register int i = head[cur]; i; i = e[i].nxt) if (incir[i]) {
		int to = e[i].to; if (!vis[to])	find_cir(to);
	}
}
void dfs3(int cur, int u, int y, int z, int x, int faa) {
	f[cur][u] = f[u][cur] = 1.0 / (x + y) + 1.0 / (x + z) - 1.0 / (x + y + z);
	//printf("x = %d, y = %d, z=  %d\n", x, y, z);
	for (register int i= head[cur]; i; i = e[i].nxt) if (!incir[i]) {
		int to = e[i].to; if (to == faa)	continue;
		dfs3(to, u, y, z, x + 1, cur);
	}
}
void dfs2(int cur, int v, int y, int z, int x, int faa) {
	dfs3(v, cur, y, z, x + 1, 0);
	for (register int i = head[cur]; i; i = e[i].nxt) if (!incir[i]) {
		int to = e[i].to; if (to == faa)	continue;
		dfs2(to, v, y, z, x + 1, cur);
	}
}
inline void Cir() {
	for (register int i = 1; i <= n; ++i) {
		if (!notcir[i]) {
			find_cir(i);
			break;
		}
	}
	for (register int i = 1; i <= htot; ++i) {
		for (register int j = i + 1; j <= htot; ++j) {
			dfs2(h[i], h[j], j - i - 1, htot - j + i - 1, 1, 0);
		}
	}
}
int main() {
	read(n);
	for (register int i = 1; i <= n; ++i) {
		int u, v; read(u), read(v); ++u, ++v; //printf("		%d, %d\n", u, v);
		addedge(u, v), addedge(v, u);
		++d[u], ++d[v];
	}
	topo();
	for (register int i = 1; i <= n; ++i) {
		//puts("-------------");
		dfs_in_tree(i, i, 1, 0);
	}
	Cir();
	double res = 0;
	for (register int i = 1; i <= n; ++i) {
		for (register int j = 1; j <= n; ++j) {
			res += f[i][j];

			/*
			if (f[i][j] <= 0.003) {
				printf("WA!!!i = %d, j = %d\n", i, j);
			}
			*/

		}
	}
	printf("%.10lf\n", res);
	return 0;
}

/*
5
3 4
2 3
2 4
0 4
1 2
//13.16666667

3
0 1
1 2
0 2
//6

5
0 1
1 2
2 0
3 0
4 1
//13.1666666666

7
0 1
1 2
2 0
2 3
2 4
0 5
1 6
//22.5
*/


/*
    Author: zxy_hhhh
    date: 2019/05/20
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
    ll _x=0;int _ch=getchar(),_f=1;
    for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
    if (_ch=='-'){_f=0;_ch=getchar();}
    for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
    return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 3005
int nx[maxn<<1],to[maxn<<1],hd[maxn],cnt;
inline void add(int u,int v) {nx[++cnt]=hd[u],to[cnt]=v,hd[u]=cnt;}
int sta[maxn],top;
int in[maxn],len,n;
bool vis[maxn],flag;
void dfs(int u,int fa) {
    sta[++top]=u,vis[u]=1;
    cross(i,u) if (to[i]!=fa) {
        if (!vis[to[i]]) dfs(to[i],u);
        else {
            flag=1;
            while(sta[top+1]!=to[i]) {
                in[sta[top]]=1,top--,len++;
            }
            return ;
        }
        if (flag) return ;
    }
    top--;
}
double Ans;
void solve(int x,int y) {
    if (y<=1) Ans+=1/double(x);
    else {
        int Sum=x-y+len;
        Ans-=1/double(Sum);
        Ans+=1/double(Sum-(y-2));
        Ans+=1/double(Sum-(len-y));
    }
}
void DFS(int u,int len1,int len2) {
    vis[u]=1,solve(len1,len2);
    cross(i,u) if (!vis[to[i]])
        DFS(to[i],len1+1,len2+in[to[i]]);
}
int main() {
    n=rd();
    rep(i,1,n) {
        int x=rd()+1,y=rd()+1;
        add(x,y),add(y,x);
    }
    dfs(1,0);
    rep(i,1,n) {
        memset(vis,0,sizeof vis);
        DFS(i,1,in[i]);
    }
    printf("%.10lf\n",Ans);
}//hello


# include <cstdio>
# include <iostream>
# include <queue>
# define R register int

using namespace std;

const int N=3005;
int n,h=1,x,y,tp,dep[N],cid[N];
int firs[N],col[N],sta[N],cir[N],vis[N];
int f[N][16],inq[N],d[N];
double ans;
struct edge
{
    int too,nex;
}g[N<<1];
queue <int> q;

void add (int x,int y)
{
    g[++h].nex=firs[x];
    firs[x]=h;
    g[h].too=y;
}

void Paint (int x,int c)
{
    col[x]=c;
    int j;
    for (R i=firs[x];i;i=g[i].nex)
    {
        j=g[i].too;
        if(dep[j]) continue;
        if(cir[j]) continue;
        dep[j]=dep[x]+1;
        f[j][0]=x;
        for (R k=1;k<=15;++k)
            f[j][k]=f[ f[j][k-1] ][k-1];
        Paint(j,c);
    }
}

int lca (int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    for (R i=15;i>=0;--i)
        if(dep[y]-(1<<i)>=dep[x]) y=f[y][i];
    if(x==y) return x;
    for (R 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 dis (int x,int y)
{
    return dep[x]+dep[y]-2*dep[ lca(x,y) ];
}

double cal (int x,int y)
{
    if(x==y) return 1;
    if(cir[x]&&cir[y])
    {
        int d=max(cid[x],cid[y])-min(cid[x],cid[y]);
        return 1.0/(d+1)+1.0/(tp-d+1)-1.0/tp;
    }
    else
    {
        if(col[x]==col[y]) return 1.0/(dis(x,y)+1);
        int d=max(cid[ col[x] ],cid[ col[y] ])-min(cid[ col[x] ],cid[ col[y] ]);
        int dt=dep[x]-dep[ col[x] ]+dep[y]-dep[ col[y] ];
        return 1.0/(dt+d+1)+1.0/(dt+tp-d+1)-1.0/(tp+dt);
    }
}

void find_cir()
{
	for (R i=1;i<=n;++i)
		if(d[i]==1) q.push(i),inq[i]=1;
	int beg,j;
	while(q.size())
	{
		beg=q.front(); q.pop();
		for (R i=firs[beg];i;i=g[i].nex)
		{
			j=g[i].too;
			if(inq[j]) continue;
			d[j]--;
			if(d[j]==1) q.push(j),inq[j]=1;
		}
	}
	for (R i=1;i<=n;++i)
		if(inq[i]==0) cir[i]=1;
}

void dfs (int x)
{
	sta[++tp]=x; vis[x]=1; cid[x]=tp;
	int j;
	for (R i=firs[x];i;i=g[i].nex)
	{
		j=g[i].too;
		if(vis[j]) continue;
		if(!cir[j]) continue;
		dfs(j);
	}
}

int main()
{
    scanf("%d",&n);
    for (R i=1;i<=n;++i)
    {
        scanf("%d%d",&x,&y); x++; y++;
        add(x,y); add(y,x);
        d[x]++; d[y]++;
    }
	find_cir();
	for (R i=1;i<=n;++i)
		if(cir[i]) { dfs(i); break; }
	for (R i=1;i<=tp;++i)
		dep[ sta[i] ]=1,Paint(sta[i],sta[i]);
    for (R i=1;i<=n;++i)
        for (R j=i+1;j<=n;++j)
			ans+=cal(i,j);
	printf("%.10lf",ans*2+n);
    return 0;
}


#include<cstdio>
const int N=3030;
int n;
int hd[N],nxt[N<<1],to[N<<1],cnt;
int fa[N],is_on[N],len=0,pos[N];
double ans=0;
inline void init(int x,int y){
	cnt++;
	nxt[cnt]=hd[x];
	hd[x]=cnt;
	to[cnt]=y;
}
int fl=0;
inline void find(int x,int pre){
	fa[x]=pre;if(fl) return;
	for(int i=hd[x];i;i=nxt[i]){
		int u=to[i];if(fl) return;
		if(u!=pre){
			if(fa[u]){
				int t=x;
				while(t!=u){
					is_on[t]=1;
					t=fa[t];
					len++;
				}
				is_on[u]=1;
				len++;fl=1;
				return;
			}
			find(u,x);
		}
	}
}
int tun=0;
inline void getans(double x,double z){
	if(z<=1) ans+=1/x;
	else{
		ans+=1/x+1/(x+len-z-z+2)-1/(x-z+len);
	}
}
inline void dfs(int x,int dep,int num){
//	printf("%d %d %d\n",x,dep,num);
	pos[x]=tun;getans(dep,num);
	for(int i=hd[x];i;i=nxt[i]){
		int u=to[i];
		if(pos[u]!=tun){
			dfs(u,dep+1,num+is_on[u]);
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		init(x,y);
		init(y,x);
	}
	find(1,1);
	for(int i=0;i<n;i++){
//		ans=0;printf("this %d turn::\n",i);
		tun++;
		dfs(i,1,is_on[i]);
//		printf("%.9lf\n",ans);puts("");
	}
	printf("%.9lf",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define N 3100
int n,tot,top,cnt;
int head[N],nex[N<<1],to[N<<1];
int st[N],deep[N],cir[N],inc[N];
double ans;
vector<int>vec[N];
void add(int x,int y)
{
	tot++;
	nex[tot]=head[x];head[x]=tot;
	to[tot]=y;
}
void dfs(int x,int y)
{
	st[++top]=x;
	for(int i=head[x];i;i=nex[i])
		if(i!=(y^1))
		{
			if(!deep[to[i]])deep[to[i]]=deep[x]+1,dfs(to[i],i);
			else if(deep[to[i]]<deep[x])
			{
				for(int j=top;st[j]!=to[i];j--)
					cir[++cnt]=st[j],inc[st[j]]=1;
				cir[++cnt]=to[i];inc[to[i]]=1;
			}
		}
	top--;
}
void cal(int x,int y,int tar)
{
	deep[x]=deep[y]+1;
	vec[tar].push_back(deep[x]);
	for(int i=head[x];i;i=nex[i])
		if(to[i]!=y&&!inc[to[i]])
			cal(to[i],x,tar);
}
double get(int v1,int v2,int v3)
{return 1.0/(v3+v2)+1.0/(v3+v1)-1.0/(v1+v2+v3);}
void dfs1(int x,int y,int dep)
{
	ans+=1.0/dep;
	for(int i=head[x];i;i=nex[i])
		if(to[i]!=y)
		{
			if(inc[x]&&inc[to[i]])continue;
			dfs1(to[i],x,dep+1);
		}
}
int main()
{
	//freopen("tt.in","r",stdin);
	scanf("%d",&n);tot=1;
	for(int i=1,x,y;i<=n;i++)
	{
		scanf("%d%d",&x,&y);x++;y++;
		add(x,y);add(y,x);
	}
	deep[1]=1;dfs(1,0);
	for(int i=1;i<=cnt;i++)
		cal(cir[i],0,i);
	for(int i=1;i<=cnt;i++)
		for(int j=i+1;j<=cnt;j++)
		{
			int c1=j-i-1,c2=cnt-c1-2;
			for(int k=0;k<vec[i].size();k++)
				for(int w=0;w<vec[j].size();w++)
					ans+=get(c1,c2,vec[i][k]+vec[j][w])*2;
		}
	for(int i=1;i<=n;i++)
		dfs1(i,0,1);
	printf("%.7lf\n",ans);
	return 0;
}


/*
　　　　　／＞　 フ
　　　　　| 　_　 _|
　 　　　／`ミ _x 彡
　　 　 /　　　 　 |
　　　 /　  ヽ　　 ?
　／￣|　　 |　|　|
　| (￣ヽ＿_ヽ_)_)
　＼二つ
 */

#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MP make_pair
#define ll long long
#define fi first
#define se second
using namespace std;

template <typename T>
void read(T &x) {
    x = 0; bool f = 0;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
    for (;isdigit(c);c=getchar()) x=x*10+(c^48);
    if (f) x=-x;
}

template<typename F>
inline void write(F x, char ed = '\n') {
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}

template <typename T>
inline void Mx(T &x, T y) { x < y && (x = y); }

template <typename T>
inline void Mn(T &x, T y) { x > y && (x = y); }

const int N = 3050;
vector<int> vec;
int To[N], h[N], to[N<<1], ne[N<<1], vis[N], tot, rt, m, n;
inline void add(int x, int y) {
	ne[++tot] = h[x], to[h[x] = tot] = y;
}

void gethua(int x, int fa) {
	vis[x] = 1;
	for (int i = h[x]; i; i = ne[i]) {
		int y = to[i]; if (y == fa) continue;
		if (rt != -1) return;
		To[x] = y;
		if (vis[y]) {
			rt = x, vec.push_back(x);
			for (int t = y; t != x; t = To[t]) vec.push_back(t);
			return;
		}
		gethua(y, x);
	}
}

double ans;
void dfs2(int x, int fa, int X, int Y, int Z) {
	ans = ans + 1.0 / (X + Y) + 1.0 / (X + Z) - 1.0 / (X + Y + Z);
	for (int i = h[x]; i; i = ne[i])
		if (vis[to[i]] == -1 && to[i] != fa) dfs2(to[i], x, X + 1, Y, Z);
}

int jue(int x) { return x > 0 ? x : -x; }
void dfs(int x, int fa, int X) {
	ans = ans + 1.0 / X;
	if (~vis[x]) {
		int sz = vec.size();
		for (int i = 0;i < sz; i++) {
			if (vec[i] == x) continue;
			dfs2(vec[i], x, X + 1, jue(i - vis[x]) - 1, sz - jue(i - vis[x]) - 1);
		}
		for (int i = h[x]; i; i = ne[i])
			if (vis[to[i]] == -1 && to[i] != fa) dfs(to[i], x, X + 1);
		return;
	}
	for (int i = h[x]; i; i = ne[i])
		if (to[i] != fa) dfs(to[i], x, X + 1);
}

int main() {
	read(n); rt = -1;
	for (int i = 1, x, y;i <= n; i++)
		read(x), read(y), add(x, y), add(y, x);
	gethua(0, -1); memset(vis, -1, sizeof(vis));
	for (int i = 0;i < (int)vec.size(); i++) vis[vec[i]] = i;
	for (int i = 0;i < n; i++) dfs(i, -1, 1);
	printf ("%.10lf\n", ans);
	return 0;
}


/*
　　　　　／＞　 フ
　　　　　| 　_　 _|
　 　　　／`ミ _x 彡
　　 　 /　　　 　 |
　　　 /　  ヽ　　 ?
　／￣|　　 |　|　|
　| (￣ヽ＿_ヽ_)_)
　＼二つ
 */

#include <queue>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MP make_pair
#define ll long long
#define fi first
#define se second
using namespace std;

template <typename T>
void read(T &x) {
    x = 0; bool f = 0;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
    for (;isdigit(c);c=getchar()) x=x*10+(c^48);
    if (f) x=-x;
}

template<typename F>
inline void write(F x, char ed = '\n') {
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}

template <typename T>
inline void Mx(T &x, T y) { x < y && (x = y); }

template <typename T>
inline void Mn(T &x, T y) { x > y && (x = y); }

const int N = 3050;
vector<int> vec;
int To[N], h[N], to[N<<1], ne[N<<1], vis[N], tot, rt, m, n;
inline void add(int x, int y) {
	ne[++tot] = h[x], to[h[x] = tot] = y;
}

void gethua(int x, int fa) {
	vis[x] = 1;
	for (int i = h[x]; i; i = ne[i]) {
		int y = to[i]; if (y == fa) continue;
		if (rt != -1) return;
		To[x] = y;
		if (vis[y]) {
			rt = x, vec.push_back(x);
			for (int t = y; t != x; t = To[t]) vec.push_back(t);
			return;
		}
		gethua(y, x);
	}
}

double ans;
void dfs2(int x, int fa, int X, int Y, int Z) {
	ans = ans + 1.0 / (X + Y) + 1.0 / (X + Z) - 1.0 / (X + Y + Z);
	for (int i = h[x]; i; i = ne[i])
		if (vis[to[i]] == -1 && to[i] != fa) dfs2(to[i], x, X + 1, Y, Z);
}

int jue(int x) { return x > 0 ? x : -x; }
void dfs(int x, int fa, int X) {
	ans = ans + 1.0 / X;
	if (~vis[x]) {
		int sz = vec.size();
		for (int i = 0;i < sz; i++) {
			if (vec[i] == x) continue;
			dfs2(vec[i], x, X + 1, jue(i - vis[x]) - 1, sz - jue(i - vis[x]) - 1);
		}
		if (fa == -1) {
			for (int i = h[x]; i; i = ne[i])
				if (vis[to[i]] == -1) dfs(to[i], x, X + 1);
		}
		return;
	}
	for (int i = h[x]; i; i = ne[i])
		if (to[i] != fa) dfs(to[i], x, X + 1);
}

int main() {
	read(n); rt = -1;
	for (int i = 1, x, y;i <= n; i++)
		read(x), read(y), add(x, y), add(y, x);
	gethua(0, -1); memset(vis, -1, sizeof(vis));
	for (int i = 0;i < (int)vec.size(); i++) vis[vec[i]] = i;
	for (int i = 0;i < n; i++) dfs(i, -1, 1);
	printf ("%.10lf\n", ans);
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;const int N=3*1e3+10;typedef long long ll;typedef double db;
int v[N<<1];int x[N<<1];int ct;int al[N];bool isr[N];
int n;int tot;int ed;int st;db ans;
inline void add(int u,int V){
//printf("add %d %d\n",u,V);
v[++ct]=V;x[ct]=al[u];al[u]=ct;}
struct bcj
{
	int fa[N];
	inline void ih(){for(int i=1;i<=n;i++)fa[i]=i;}
	inline int f(int x){return fa[x]=(fa[x]==x)?x:f(fa[x]);}
	inline bool u(int x,int y){x=f(x);y=f(y);
//	printf("u %d %d\n",x,y);
	if(x==y)return false;fa[x]=y;return true;}
}s;
inline void dfs(int u,int f,int dep1,int dep2)
{
	dep1++;dep2+=isr[u];
//	printf("dfs %d %d %d %d\n",u,f,dep1,dep2);
	if(dep2==0||dep2==1)ans+=1.0/(dep1);
	else
	{
		//printf("tw=%d: x+y:%d  x+z:%d  x+y+z:%d\n",u,dep1,dep1-dep2+(tot-dep2),dep1+(tot-dep2-2));
		ans+=1.0/dep1;
		ans+=1.0/(dep1-dep2+(tot-dep2));
		ans-=1.0/(dep1+(tot-dep2-2));
	}
	//ans+=1.0/(dep1+dep2)+1.0/(dep1+tot-dep2)-1.0/(dep1+tot);
	for(int i=al[u];i;i=x[i])if(v[i]!=f)dfs(v[i],u,dep1,dep2);
}
inline bool mrk(int u,int tar,int f)
{
	//printf("mrk %d %d\n",u,tar);
	if(u==tar)
	{
		//printf("find %d %d\n",u,tar);
		return isr[u]=true;
	}
	for(int i=al[u];i;i=x[i])
		if(v[i]!=f)if(mrk(v[i],tar,u))return isr[u]=true;
	return false;
}
int main()
{
	scanf("%d",&n);s.ih();
	for(int i=1,u,v;i<=n;i++)
	{
		scanf("%d%d",&u,&v);u++;v++;
		if(s.u(u,v)==false)st=u,ed=v;
		else add(u,v),add(v,u);
	}
	//printf("st=%d,ed=%d\n",st,ed);
	mrk(st,ed,0);
//	for(int i=1;i<=n;i++)printf("%d ",isr[i]);printf("\n");
	for(int i=1;i<=n;i++)tot+=isr[i];tot+=2;
	for(int i=1;i<=n;i++)
	{
	//	printf("line %d --------\n",i);
		dfs(i,0,0,0);
	}
	printf("%.10lf",ans);return 0;
}


#include <queue>
#include <iomanip>
#include <iostream>
#include <algorithm>

struct Vertex {
    bool vis;
    int head, top, dist;
    Vertex() : vis(false), head(0), top(0), dist(0) {}
} vertex[3005];
struct Edge {
    int to, next;
    Edge(int __to = 0, int __next = 0) :
        to(__to), next(__next) {}
} edge[6005];

int n, ptr, dist[3005][3005];
std::vector<int> circle;

void addEdge(int u, int v) {
    edge[++ptr] = Edge(v, vertex[u].head), vertex[u].head = ptr;
    edge[++ptr] = Edge(u, vertex[v].head), vertex[v].head = ptr;
}

int findCircle(int p, int f) {
    vertex[p].vis = true;
    // std::cout << p - 1 << ' ' << f - 1 << std::endl;
    for (int i = vertex[p].head; i; i = edge[i].next) {
        int x = edge[i].to, temp;
        if (x == f) continue;
        if (vertex[x].vis) {
            vertex[x].top = x;
            vertex[p].top = p;
            circle.push_back(x);
            circle.push_back(p);
            // std::cout << "---1 " << x - 1 << ' ' << p - 1 << std::endl;
            return 1;
        } else if (temp = findCircle(x, p)) {
            // std::cout << "---- " << temp << std::endl;
            if (temp == 1 && !vertex[p].top) {
                // std::cout << "---2 " << x - 1 << ' ' << p - 1 << std::endl;
                vertex[p].top = p;
                circle.push_back(p);
                return 1;
            } else {
                // std::cout << "---3 " << x - 1 << ' ' << p - 1 << std::endl;
                return -1;
            }
        }
    }
    // std::cout << p - 1 << std::endl;
    vertex[p].vis = false;
    return 0;
}

void BFS(int s) {
    for (int i = 1; i <= n; ++i)
        vertex[i].vis = false;
    std::queue<int> q;
    q.push(s), vertex[s].vis = true, dist[s][s] = 0;
    while (!q.empty()) {
        int p = q.front();
        q.pop();
        for (int i = vertex[p].head; i; i = edge[i].next) {
            int x = edge[i].to;
            if (vertex[x].vis) continue;
            vertex[x].vis = true, q.push(x);
            dist[s][x] = dist[s][p] + 1;
        }
    }
}

void findTop(int s) {
    std::queue<int> q;
    q.push(s), vertex[s].vis = true;
    while (!q.empty()) {
        int p = q.front();
        q.pop();
        for (int i = vertex[p].head; i; i = edge[i].next) {
            int x = edge[i].to;
            if (vertex[x].top)
                continue;
            vertex[x].top = s, q.push(x);
        }
    }
}

int main() {
    double ans = 0;
    std::cin >> n;
    for (int i = 1; i <= n; ++i) {
        int u, v;
        std::cin >> u >> v;
        addEdge(u + 1, v + 1);
    }
    findCircle(1, 0);
    for (int i = 1; i <= n; ++i)
        BFS(i);
    for (auto x : circle)
        findTop(x);
    for (int i = 2; i <= n; ++i)
    for (int j = 1; j != i; ++j) {
        double temp = 0.0;
        if (vertex[i].top == vertex[j].top) {
            temp = 1.0 / (dist[i][j] + 1);
        } else {
            double x = vertex[i].dist + vertex[j].dist + 2,
                   y = dist[vertex[i].top][vertex[j].top] - 1,
                   z = circle.size() - y - 2;
            temp = 1 / (x + y) + 1 / (x + z) - 1 / (x + y + z);
            std::cout << i << ' ' << j << ' ' << x << ' ' << y << ' ' << z << std::endl;
        }
        std::cout << i << ' ' << j << ' ' << temp << std::endl;
        ans += temp;
    }
    std::cout << circle.size() << std::endl;
    std::cout << std::fixed << std::setprecision(9) << ans << std::endl;
    return 0;
}


#include <queue>
#include <iomanip>
#include <iostream>
#include <algorithm>

struct Vertex {
    bool vis;
    int head, top, dist;
    Vertex() : vis(false), head(0), top(0), dist(0) {}
} vertex[3005];
struct Edge {
    int to, next;
    Edge(int __to = 0, int __next = 0) :
        to(__to), next(__next) {}
} edge[6005];

int n, ptr, dist[3005][3005];
std::vector<int> circle;

void addEdge(int u, int v) {
    edge[++ptr] = Edge(v, vertex[u].head), vertex[u].head = ptr;
    edge[++ptr] = Edge(u, vertex[v].head), vertex[v].head = ptr;
}

int findCircle(int p, int f) {
    vertex[p].vis = true;
    // std::cout << p - 1 << ' ' << f - 1 << std::endl;
    for (int i = vertex[p].head; i; i = edge[i].next) {
        int x = edge[i].to, temp;
        if (x == f) continue;
        if (vertex[x].vis) {
            vertex[x].top = x;
            vertex[p].top = p;
            circle.push_back(x);
            circle.push_back(p);
            // std::cout << "---1 " << x - 1 << ' ' << p - 1 << std::endl;
            return 1;
        } else if (temp = findCircle(x, p)) {
            // std::cout << "---- " << temp << std::endl;
            if (temp == 1 && !vertex[p].top) {
                // std::cout << "---2 " << x - 1 << ' ' << p - 1 << std::endl;
                vertex[p].top = p;
                circle.push_back(p);
                return 1;
            } else {
                // std::cout << "---3 " << x - 1 << ' ' << p - 1 << std::endl;
                return -1;
            }
        }
    }
    // std::cout << p - 1 << std::endl;
    vertex[p].vis = false;
    return 0;
}

void BFS(int s) {
    for (int i = 1; i <= n; ++i)
        vertex[i].vis = false;
    std::queue<int> q;
    q.push(s), vertex[s].vis = true, dist[s][s] = 0;
    while (!q.empty()) {
        int p = q.front();
        q.pop();
        for (int i = vertex[p].head; i; i = edge[i].next) {
            int x = edge[i].to;
            if (vertex[x].vis) continue;
            vertex[x].vis = true, q.push(x);
            dist[s][x] = dist[s][p] + 1;
        }
    }
}

void findTop(int s) {
    std::queue<int> q;
    q.push(s), vertex[s].vis = true;
    while (!q.empty()) {
        int p = q.front();
        q.pop();
        for (int i = vertex[p].head; i; i = edge[i].next) {
            int x = edge[i].to;
            if (vertex[x].top)
                continue;
            vertex[x].top = s, q.push(x);
        }
    }
}

int main() {
    double ans = 0;
    std::cin >> n;
    for (int i = 1; i <= n; ++i) {
        int u, v;
        std::cin >> u >> v;
        addEdge(u + 1, v + 1);
    }
    findCircle(1, 0);
    for (int i = 1; i <= n; ++i)
        BFS(i);
    for (auto x : circle)
        findTop(x);
    for (int i = 1; i <= n; ++i)
        vertex[i].dist = dist[i][vertex[i].top];
    for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
        double temp = 0.0;
        if (vertex[i].top == vertex[j].top) {
            temp = 1.0 / (dist[i][j] + 1);
        } else {
            double x = vertex[i].dist + vertex[j].dist + 2,
                   y = dist[vertex[i].top][vertex[j].top] - 1,
                   z = circle.size() - y - 2;
            temp = 1 / (x + y) + 1 / (x + z) - 1 / (x + y + z);
            // std::cout << i << ' ' << j << ' ' << x << ' ' << y << ' ' << z << std::endl;
        }
        // std::cout << i - 1 << ' ' << j - 1 << ' ' << temp << std::endl;
        ans += temp;
    }
    // for (int i = 1; i <= n; ++i)
    //     std::cout << vertex[i].dist << ' ';
    // std::cout << std::endl;
    // std::cout << circle.size() << std::endl;
    std::cout << std::fixed << std::setprecision(9) << ans << std::endl;
    return 0;
}


#include <queue>
#include <iomanip>
#include <iostream>
#include <algorithm>

struct Vertex {
    bool vis;
    int head, top, dist;
    Vertex() : vis(false), head(0), top(0), dist(0) {}
} vertex[3005];
struct Edge {
    int to, next;
    Edge(int __to = 0, int __next = 0) :
        to(__to), next(__next) {}
} edge[6005];

int n, ptr, dist[3005][3005];
std::vector<int> circle;

void addEdge(int u, int v) {
    edge[++ptr] = Edge(v, vertex[u].head), vertex[u].head = ptr;
    edge[++ptr] = Edge(u, vertex[v].head), vertex[v].head = ptr;
}

int findCircle(int p, int f) {
    vertex[p].vis = true;
    // std::cout << p - 1 << ' ' << f - 1 << std::endl;
    for (int i = vertex[p].head; i; i = edge[i].next) {
        int x = edge[i].to, temp;
        if (x == f) continue;
        if (vertex[x].vis) {
            vertex[x].top = x;
            vertex[p].top = p;
            circle.push_back(x);
            circle.push_back(p);
            // std::cout << "---1 " << x - 1 << ' ' << p - 1 << std::endl;
            return 1;
        } else if (temp = findCircle(x, p)) {
            // std::cout << "---- " << temp << std::endl;
            if (temp == 1 && !vertex[p].top) {
                // std::cout << "---2 " << x - 1 << ' ' << p - 1 << std::endl;
                vertex[p].top = p;
                circle.push_back(p);
                return 1;
            } else {
                // std::cout << "---3 " << x - 1 << ' ' << p - 1 << std::endl;
                return -1;
            }
        }
    }
    // std::cout << p - 1 << std::endl;
    vertex[p].vis = false;
    return 0;
}

void BFS(int s) {
    for (int i = 1; i <= n; ++i)
        vertex[i].vis = false;
    std::queue<int> q;
    q.push(s), vertex[s].vis = true, dist[s][s] = 0;
    while (!q.empty()) {
        int p = q.front();
        q.pop();
        for (int i = vertex[p].head; i; i = edge[i].next) {
            int x = edge[i].to;
            if (vertex[x].vis) continue;
            vertex[x].vis = true, q.push(x);
            dist[s][x] = dist[s][p] + 1;
        }
    }
}

void findTop(int s) {
    std::queue<int> q;
    q.push(s), vertex[s].vis = true;
    while (!q.empty()) {
        int p = q.front();
        q.pop();
        for (int i = vertex[p].head; i; i = edge[i].next) {
            int x = edge[i].to;
            if (vertex[x].top)
                continue;
            vertex[x].top = s, q.push(x);
        }
    }
}

int main() {
    double ans = 0;
    std::cin >> n;
    for (int i = 1; i <= n; ++i) {
        int u, v;
        std::cin >> u >> v;
        addEdge(u + 1, v + 1);
    }
    findCircle(1, 0);
    for (int i = 1; i <= n; ++i)
        BFS(i);
    for (auto x : circle)
        findTop(x);
    for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) {
        double temp = 0.0;
        if (vertex[i].top == vertex[j].top) {
            temp = 1.0 / (dist[i][j] + 1);
        } else {
            double x = vertex[i].dist + vertex[j].dist + 2,
                   y = dist[vertex[i].top][vertex[j].top] - 1,
                   z = circle.size() - y - 2;
            temp = 1 / (x + y) + 1 / (x + z) - 1 / (x + y + z);
            // std::cout << i << ' ' << j << ' ' << x << ' ' << y << ' ' << z << std::endl;
        }
        // std::cout << i << ' ' << j << ' ' << temp << std::endl;
        ans += temp;
    }
    // std::cout << circle.size() << std::endl;
    std::cout << std::fixed << std::setprecision(9) << ans << std::endl;
    return 0;
}


#include <stdio.h>
int fr[3010],ne[6010],v[6010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int bk[3010],sd[3010],hu[3010],fa[3010],sl=0;
void dfs1(int u,int f)
{
	bk[u]=1;fa[u]=f;
	sd[u]=sd[f]+1;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)continue;
		if(bk[v[i]])
		{
			if(sd[v[i]]<sd[u])
			{
				int t=u;
				while(1)
				{
					hu[sl++]=t;
					if(t==v[i])break;
					t=fa[t];
				}
			}
		}
		else
			dfs1(v[i],u);
	}
}
int hd[3010],ro[3010],lc[3010][3010],wz[3010];
void dfs2(int u,int f,int rt)
{
	fa[u]=f;ro[u]=rt;
	sd[u]=sd[f]+1;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f||hd[v[i]])
			continue;
		dfs2(v[i],u,rt);
	}
}
int dfs3(int a,int b)
{
	if(a==b)
		return lc[a][b]=a;
	if(lc[a][b])
		return lc[a][b];
	if(sd[a]>sd[b])
		lc[a][b]=dfs3(fa[a],b);
	else
		lc[a][b]=dfs3(a,fa[b]);
	return lc[a][b];
}
int getdis(int a,int b)
{
	int l=dfs3(a,b);
	return sd[a]+sd[b]-sd[l]*2+1;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		a+=1;b+=1;
		addb(a,b);addb(b,a);
	}
	dfs1(1,0);
	for(int i=0;i<sl;i++)
	{
		hd[hu[i]]=1;
		wz[hu[i]]=i;
	}
	for(int i=0;i<sl;i++)
		dfs2(hu[i],0,hu[i]);
	long double ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(ro[i]==ro[j])
				ans+=1.0/getdis(i,j);
			else
			{
				int a=sd[i]+sd[j];
				int b=wz[ro[i]]-wz[ro[j]];
				if(b<0)b=-b;
				b-=1;int c=sl-2-b;
				ans+=1.0/(a+b);
				ans+=1.0/(a+c);
				ans-=1.0/(a+b+c);
			}
		}
	}
	printf("%.10Lf",ans);
	return 0;
}


#include <stdio.h>
int fr[3010],ne[6010],v[6010],bs=0;
void addb(int a,int b)
{
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
int bk[3010],sd[3010],hu[3010],fa[3010],sl=0;
void dfs1(int u,int f)
{
	bk[u]=1;fa[u]=f;
	sd[u]=sd[f]+1;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)continue;
		if(bk[v[i]])
		{
			if(sd[v[i]]<sd[u])
			{
				int t=u;
				while(1)
				{
					hu[sl++]=t;
					if(t==v[i])break;
					t=fa[t];
				}
			}
		}
		else
			dfs1(v[i],u);
	}
}
int hd[3010],ro[3010],lc[3010][3010],wz[3010];
void dfs2(int u,int f,int rt)
{
	fa[u]=f;ro[u]=rt;
	sd[u]=sd[f]+1;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f||hd[v[i]])
			continue;
		dfs2(v[i],u,rt);
	}
}
int dfs3(int a,int b)
{
	if(a==b)
		return lc[a][b]=a;
	if(lc[a][b])
		return lc[a][b];
	if(sd[a]>sd[b])
		lc[a][b]=dfs3(fa[a],b);
	else
		lc[a][b]=dfs3(a,fa[b]);
	return lc[a][b];
}
int getdis(int a,int b)
{
	int l=dfs3(a,b);
	return sd[a]+sd[b]-sd[l]*2+1;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<n;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		a+=1;b+=1;
		addb(a,b);addb(b,a);
	}
	dfs1(1,0);
	for(int i=0;i<sl;i++)
	{
		hd[hu[i]]=1;
		wz[hu[i]]=i;
	}
	for(int i=0;i<sl;i++)
		dfs2(hu[i],0,hu[i]);
	double ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(ro[i]==ro[j])
				ans+=1.0/getdis(i,j);
			else
			{
				int a=sd[i]+sd[j];
				int b=wz[ro[i]]-wz[ro[j]];
				if(b<0)b=-b;
				b-=1;int c=sl-2-b;
				ans+=1.0/(a+b);
				ans+=1.0/(a+c);
				ans-=1.0/(a+b+c);
			}
		}
	}
	printf("%.10lf",ans);
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
lod ans;
vector<int> e[MAXN];
int vis[MAXN],stk[MAXN],a[MAXN],id[MAXN],gf[MAXN],dis[MAXN],rt,top=0,num=0;
void dfs(int x,int father)
{
	vis[x]=1,stk[++top]=x;
//	cout<<x<<endl;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (vis[v])
		{
			if (num) continue;
			int y;
			while (y=stk[top--])
			{
				a[++num]=y,id[y]=num;
				if (y==v) break;
			}
		}
		else dfs(v,x);
	}
	if (stk[top]==x) top--;
}
void Dfs(int x,int father,int Gf)
{
	gf[x]=Gf;
	dis[x]=dis[father]+1;
	for (auto v:e[x])
		if (!id[v]&&v!=father) Dfs(v,x,Gf);
}
void getans(int x,int dep)
{
	vis[x]=1;
	if (x!=rt)
	{
		if (gf[x]==gf[rt]) ans+=1/(lod)dep;
		else
		{
			lod a=dis[x]+dis[rt],b=abs(id[gf[x]]-id[gf[rt]])-1,c=num-2-b;
			ans+=1/(a+b)+1/(a+c)-1/(a+b+c);
		}
	}
	for (auto v:e[x])
		if (!vis[v]) getans(v,dep+1);
}
int main()
{
	int n=read();
	for (int i=1;i<=n;i++)
	{
		int u=read()+1,v=read()+1;
		e[u].PB(v),e[v].PB(u);
	}
	dfs(1,0);
	for (int i=1;i<=num;i++) Dfs(a[i],0,a[i]);
	ans=n;
	for (int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		rt=i,getans(i,1);
	}
	printf("%.10Lf\n",ans);
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
lod ans;
vector<int> e[MAXN];
int vis[MAXN],stk[MAXN],a[MAXN],id[MAXN],gf[MAXN],dis[MAXN],rt,top=0,num=0;
void dfs(int x,int father)
{
	vis[x]=1,stk[++top]=x;
//	cout<<x<<endl;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (vis[v])
		{
			if (num) continue;
			int y;
			while (y=stk[top--])
			{
				a[++num]=y,id[y]=num;
//				cout<<num<<" "<<y<<endl;
				if (y==v) break;
			}
		}
		else dfs(v,x);
	}
	if (stk[top]==x) top--;
}
void Dfs(int x,int father,int Gf)
{
	gf[x]=Gf;
	dis[x]=dis[father]+1;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (!id[v]) Dfs(v,x,Gf);
	}
}
void getans(int x,int dep)
{
	vis[x]=1;
	if (x!=rt)
	{
		if (gf[x]==gf[rt]) ans+=(lod)1/dep;
		else
		{
			lod a=dis[x]+dis[rt],b=abs(id[gf[x]]-id[gf[rt]])-1,c=num-2-b;
//			cout<<a<<" "<<b<<" "<<c<<endl;
			ans+=1/(a+b)+1/(a+c)-1/(a+b+c);
		}
	}
	for (auto v:e[x])
		if (!vis[v]) getans(v,dep+1);
}
int main()
{
	int n=read();
	for (int i=1;i<=n;i++)
	{
		int u=read()+1,v=read()+1;
		e[u].PB(v),e[v].PB(u);
	}
	dfs(1,0);
	for (int i=1;i<=num;i++) Dfs(a[i],0,a[i]);
	ans=n;
	for (int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		rt=i,getans(i,1);
	}
	printf("%.9Lf\n",ans);
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
double ans;
vector<int> e[MAXN];
int vis[MAXN],stk[MAXN],a[MAXN],id[MAXN],gf[MAXN],dis[MAXN],rt,top=0,num=0;
void dfs(int x,int father)
{
	vis[x]=1,stk[++top]=x;
//	cout<<x<<endl;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (vis[v])
		{
			if (num) continue;
			int y;
			while (y=stk[top--])
			{
				a[++num]=y,id[y]=num;
				if (y==v) break;
			}
		}
		else dfs(v,x);
	}
	if (stk[top]==x) top--;
}
void Dfs(int x,int father,int Gf)
{
	gf[x]=Gf;
	dis[x]=dis[father]+1;
	for (auto v:e[x])
		if (!id[v]&&v!=father) Dfs(v,x,Gf);
}
void getans(int x,int dep)
{
	vis[x]=1;
	if (x!=rt)
	{
		if (gf[x]==gf[rt]) ans+=(double)1/(double)dep;
		else
		{
			int a=dis[x]+dis[rt],b=abs(id[gf[x]]-id[gf[rt]])-1,c=num-2-b;
//			cout<<a<<" "<<b<<" "<<c<<endl;
			ans+=(double)1/((double)a+b)+(double)1/((double)a+c)-(double)1/((double)a+b+c);
		}
	}
	for (auto v:e[x])
		if (!vis[v]) getans(v,dep+1);
}
int main()
{
	int n=read();
	for (int i=1;i<=n;i++)
	{
		int u=read()+1,v=read()+1;
		e[u].PB(v),e[v].PB(u);
	}
	dfs(1,0);
	for (int i=1;i<=num;i++) Dfs(a[i],0,a[i]);
	ans=(double)n;
	for (int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		rt=i,getans(i,1);
	}
	printf("%.10lf\n",ans);
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
lod ans;
vector<int> e[MAXN];
int vis[MAXN],stk[MAXN],a[MAXN],id[MAXN],gf[MAXN],dis[MAXN],rt,top=0,num=0;
void dfs(int x,int father)
{
	vis[x]=1,stk[++top]=x;
//	cout<<x<<endl;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (vis[v])
		{
			if (num) continue;
			int y;
			while (y=stk[top--])
			{
				a[++num]=y,id[y]=num;
				if (y==v) break;
			}
		}
		else dfs(v,x);
	}
	if (stk[top]==x) top--;
}
void Dfs(int x,int father,int Gf)
{
	gf[x]=Gf;
	dis[x]=dis[father]+1;
	for (auto v:e[x])
		if (!id[v]&&v!=father) Dfs(v,x,Gf);
}
void getans(int x,int dep)
{
	vis[x]=1;
	if (x!=rt)
	{
		if (gf[x]==gf[rt]) ans+=(lod)1/(lod)dep;
		else
		{
			int a=dis[x]+dis[rt],b=abs(id[gf[x]]-id[gf[rt]])-1,c=num-2-b;
//			cout<<a<<" "<<b<<" "<<c<<endl;
			ans+=(lod)1/((lod)a+b)+(lod)1/((lod)a+c)-(lod)1/((lod)a+b+c);
		}
	}
	for (auto v:e[x])
		if (!vis[v]) getans(v,dep+1);
}
int main()
{
	int n=read();
	for (int i=1;i<=n;i++)
	{
		int u=read()+1,v=read()+1;
		e[u].PB(v),e[v].PB(u);
	}
	dfs(1,0);
	for (int i=1;i<=num;i++) Dfs(a[i],0,a[i]);
	ans=(lod)n;
	for (int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		rt=i,getans(i,1);
	}
	printf("%.10Lf\n",ans);
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
lod ans;
vector<int> e[MAXN];
int vis[MAXN],stk[MAXN],a[MAXN],id[MAXN],gf[MAXN],dis[MAXN],rt,top=0,num=0;
void dfs(int x,int father)
{
	vis[x]=1,stk[++top]=x;
//	cout<<x<<endl;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (vis[v])
		{
			if (num) continue;
			int y;
			while (y=stk[top--])
			{
				a[++num]=y,id[y]=num;
//				cout<<num<<" "<<y<<endl;
				if (y==v) break;
			}
		}
		else dfs(v,x);
	}
	if (stk[top]==x) top--;
}
void Dfs(int x,int father,int Gf)
{
	gf[x]=Gf;
	dis[x]=dis[father]+1;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (!id[v]) Dfs(v,x,Gf);
	}
}
void getans(int x,int dep)
{
	vis[x]=1;
	if (x!=rt)
	{
		if (gf[x]==gf[rt]) ans+=(lod)1/dep,cout<<dep<<endl;
		else
		{
			lod a=dis[x]+dis[rt],b=abs(id[gf[x]]-id[gf[rt]])-1,c=num-2-b;
			cout<<a<<" "<<b<<" "<<c<<endl;
			ans+=1/(a+b)+1/(a+c)-1/(a+b+c);
		}
	}
	for (auto v:e[x])
		if (!vis[v]) getans(v,dep+1);
}
int main()
{
	int n=read();
	for (int i=1;i<=n;i++)
	{
		int u=read()+1,v=read()+1;
		e[u].PB(v),e[v].PB(u);
	}
	dfs(1,0);
	for (int i=1;i<=num;i++) Dfs(a[i],0,a[i]);
	ans=n;
	for (int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		rt=i,getans(i,1);
	}
	printf("%.9Lf\n",ans);
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{
	int f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
lod ans;
vector<int> e[MAXN];
int vis[MAXN],stk[MAXN],a[MAXN],id[MAXN],gf[MAXN],dis[MAXN],rt,top=0,num=0;
void dfs(int x,int father)
{
	vis[x]=1,stk[++top]=x;
//	cout<<x<<endl;
	for (auto v:e[x])
	{
		if (v==father) continue;
		if (vis[v])
		{
			if (num) continue;
			int y;
			while (y=stk[top--])
			{
				a[++num]=y,id[y]=num;
				if (y==v) break;
			}
		}
		else dfs(v,x);
	}
	if (stk[top]==x) top--;
}
void Dfs(int x,int father,int Gf)
{
	gf[x]=Gf;
	dis[x]=dis[father]+1;
	for (auto v:e[x])
		if (!id[v]&&v!=father) Dfs(v,x,Gf);
}
void getans(int x,int dep)
{
	vis[x]=1;
	if (x!=rt)
	{
		if (gf[x]==gf[rt]) ans+=1/(lod)dep;
		else
		{
			lod a=dis[x]+dis[rt],b=abs(id[gf[x]]-id[gf[rt]])-1,c=num-2-b;
			ans+=1/(a+b)+1/(a+c)-1/(a+b+c);
		}
	}
	for (auto v:e[x])
		if (!vis[v]) getans(v,dep+1);
}
int main()
{
	int n=read();
	for (int i=1;i<=n;i++)
	{
		int u=read()+1,v=read()+1;
		e[u].PB(v),e[v].PB(u);
	}
	dfs(1,0);
	for (int i=1;i<=num;i++) Dfs(a[i],0,a[i]);
	ans=(lod)n;
	for (int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof vis);
		rt=i,getans(i,1);
	}
	printf("%.10Lf\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)3e3 + 1;
int n, m, seq[maxn], idx[maxn], dep[maxn];
vector<int> e[maxn];
bool vis[maxn], ban[maxn];
bool pfs(int u) {
	vis[u] = 1;
	seq[m++] = u;
	for(auto &v : e[u])
		if(vis[v]) {
			if(m > 1 && v == seq[m - 2])
				continue;
			for(int i = m - 3; i >= 0; --i)
				if(v == seq[i]) {
					rotate(seq, seq + i, seq + m);
					m -= i;
					break;
				}
			return 1;
		} else if(pfs(v)) {
			return 1;
		}
	--m;
	vis[u] = 0;
	return 0;
}
int f[maxn][maxn], g[maxn][maxn], h[maxn];
int dfs(int u, int fa) {
	int su = 1;
	f[u][0] = 1;
	g[u][0] = 1;
	for(auto &v : e[u]) {
		if(v == fa || ban[v])
			continue;
		idx[v] = idx[u];
		dep[v] = dep[u] + 1;
		int sv = dfs(v, u);
		memset(f[u] + su, 0, sv * sizeof(int));
		memset(g[u] + su, 0, sv * sizeof(int));
		for(int i = 0; i < su; ++i) if(f[u][i])
			for(int j = 0; j < sv; ++j) if(f[v][j])
				g[u][i + j + 1] += 2 * f[u][i] * f[v][j];
		for(int i = 0; i < sv; ++i) {
			f[u][i + 1] += f[v][i];
			g[u][i] += g[v][i];
		}
		su += sv;
	}
	return su;
}
int main() {
	scanf("%d", &n);
	for(int i = 0; i < n; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pfs(1);
	memset(vis, 0, n * sizeof(bool));
	for(int i = 0; i < m; ++i)
		ban[seq[i]] = 1;
	for(int i = 0; i < m; ++i) {
		idx[seq[i]] = i;
		dep[seq[i]] = 0;
		int si = dfs(seq[i], -1);
		for(int j = 0; j < si; ++j)
			h[j + 1] += g[seq[i]][j];
	}
	for(int i = 0; i < n; ++i)
		for(int j = 0; j < n; ++j)
			if(idx[i] != idx[j]) {
				int u = abs(idx[i] - idx[j]), v = m - u, w = dep[i] + dep[j];
				++h[u + w + 1];
				++h[v + w + 1];
				--h[u + v + w];
			}
	double ans = 0;
	for(int i = 1; i <= n; ++i)
		ans += (double)h[i] / i;
	printf("%.20f\n", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxn = (int)3e3 + 1;
int n, m, seq[maxn], idx[maxn], dep[maxn];
vector<int> e[maxn];
bool vis[maxn], ban[maxn];
bool pfs(int u) {
	vis[u] = 1;
	seq[m++] = u;
	for(auto &v : e[u])
		if(vis[v]) {
			if(m > 1 && v == seq[m - 2])
				continue;
			for(int i = m - 3; i >= 0; --i)
				if(v == seq[i]) {
					rotate(seq, seq + i, seq + m);
					m -= i;
					break;
				}
			return 1;
		} else if(pfs(v)) {
			return 1;
		}
	--m;
	vis[u] = 0;
	return 0;
}
int f[maxn][maxn], g[maxn][maxn], h[maxn];
int dfs(int u, int fa) {
	int su = 1;
	f[u][0] = 1;
	g[u][0] = 1;
	for(auto &v : e[u]) {
		if(v == fa || ban[v])
			continue;
		idx[v] = idx[u];
		dep[v] = dep[u] + 1;
		int sv = dfs(v, u);
		memset(f[u] + su, 0, sv * sizeof(int));
		memset(g[u] + su, 0, sv * sizeof(int));
		for(int i = 0; i < su && f[u][i]; ++i)
			for(int j = 0; j < sv && f[v][j]; ++j)
				g[u][i + j + 1] += 2 * f[u][i] * f[v][j];
		for(int i = 0; i < sv && f[v][i]; ++i) {
			f[u][i + 1] += f[v][i];
			g[u][i] += g[v][i];
		}
		su += sv;
	}
	return su;
}
int main() {
	scanf("%d", &n);
	for(int i = 0; i < n; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	pfs(1);
	memset(vis, 0, n * sizeof(bool));
	for(int i = 0; i < m; ++i)
		ban[seq[i]] = 1;
	for(int i = 0; i < m; ++i) {
		idx[seq[i]] = i;
		dep[seq[i]] = 0;
		int si = dfs(seq[i], -1);
		for(int j = 0; j < si && g[seq[i]][j]; ++j)
			h[j + 1] += g[seq[i]][j];
	}
	for(int i = 0; i < n; ++i)
		for(int j = 0; j < n; ++j)
			if(idx[i] != idx[j]) {
				int u = abs(idx[i] - idx[j]), v = m - u, w = dep[i] + dep[j];
				++h[u + w + 1];
				++h[v + w + 1];
				--h[u + v + w];
			}
	double ans = 0;
	for(int i = 1; i <= n; ++i)
		ans += (double)h[i] / i;
	printf("%.20f\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
inline int read()
{
	int x = 0 , f = 1; char ch = getchar();
	while(ch < '0' || ch > '9')	{if(ch == '-')	f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
const int N = 3005;
int n , top , root , tot;
struct Edge
{
	int to; Edge *nxt;
	Edge(int to = 0,Edge *nxt = NULL) : to(to) , nxt(nxt) {}
} *head[N] , pool[N << 1] , *tail = pool;
inline void add(int u,int v) { head[u] = new (tail ++) Edge(v,head[u]);}
bool vis[N];
int st[N] , pos[N] , dep[N] , anc[N] , fa[N][13];
bool flag;
void find_circle(int x,int fa)
{
	vis[x] = 1; st[++ top] = x;
	for(Edge *i = head[x];i;i = i -> nxt)
	{
		int to = i -> to;
		if(to == fa) continue;
		if(vis[to]) return (void)(root = to , flag = 1);
		find_circle(to,x);
		if(flag) return ;
	}
	vis[x] = 0; top --;
}
void get(int x,int rot)
{
	anc[x] = rot;
	dep[x] = dep[fa[x][0]] + 1;
	for(int i = 1;i <= 12;i ++) fa[x][i] = fa[fa[x][i - 1]][i - 1];
	for(Edge *i = head[x];i;i = i -> nxt)
	{
		int to = i -> to;
		if(to == fa[x][0] || pos[to]) continue;
		fa[to][0] = x;
		get(to,rot);
	}
}
inline int LCA(int x,int y)
{
	if(dep[x] < dep[y]) swap(x,y);
	for(int i = 12;i >= 0;i --) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	if(x == y) return x;
	for(int i = 12;i >= 0;i --) if(fa[x][i] != fa[y][i]) x = fa[x][i] , y = fa[y][i];
	return fa[x][0];
}
inline int dis(int x,int y) { return dep[x] + dep[y] - (dep[LCA(x,y)] << 1) + 1;}
int main()
{
	n = read(); double ans = 0;
	for(int i = 1 , u , v;i <= n;i ++) u = read() + 1 , v = read() + 1 , add(u,v) , add(v,u);
	find_circle(1,0); pos[root] = ++ tot;
	while(st[top] != root) pos[st[top --]] = ++ tot;
	for(int i = 1;i <= n;i ++) if(pos[i]) get(i,i);
	for(int i = 1 , x , y , z;i <= n;i ++) for(int j = 1;j <= n;j ++)
	{
		if(anc[i] != anc[j])
		{
			x = dep[i] - dep[anc[i]] + dep[j] - dep[anc[j]] + 2;
			y = (pos[anc[i]] - pos[anc[j]] - 1 + tot) % tot;
			z = (pos[anc[j]] - pos[anc[i]] - 1 + tot) % tot;
			ans += 1.0 / (double)(x + y) + 1.0 / (double)(x + z) - 1.0 / (double)(x + y + z);
		}
		else ans += 1.0 / (double)dis(i,j);
	}
	printf("%.10f\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;
const int N = 3010;
vector<int> e[N];
int n, d[N], rt, tot, vis[N];
int q[N], h = 1, t = 0;
double ans = 0;

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);
	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>

typedef long long ll;
typedef unsigned long long ull;

using namespace std;

const int MAXN=3010;

int n,inR[MAXN],dep[MAXN],jmp[13][MAXN];
int top,stk[MAXN],ins[MAXN],bl[MAXN],rt,ringo[MAXN];
vector<int> T[MAXN],Ring;

void dfs(int x,int fa)
{
	ins[stk[++top]=x]=1;
	for(int v:T[x])
		if(v!=fa)
		{
			if(ins[v])
				throw v;
			dfs(v,x);
		}
	ins[stk[top--]]=0;
}

void dfst(int x,int fa)
{
	bl[x]=rt;
	dep[x]=dep[fa]+1;
	jmp[0][x]=fa;
	for(int v:T[x])
		if(v!=fa&&!inR[v])
			dfst(v,x);
}

int dis(int x,int y) //point distance
{
	assert(bl[x]==bl[y]);
	int _x=x,_y=y;
	if(dep[x]<dep[y])
		swap(x,y);
	for(int j=12;~j;j--)
		if(dep[jmp[j][x]]>=dep[y])
			x=jmp[j][x];
	if(x==y)
		return dep[_x]+dep[_y]-2*dep[x]+1;
	for(int j=12;~j;j--)
		if(jmp[j][x]!=jmp[y][j])
			x=jmp[j][x],y=jmp[y][j];
	return dep[_x]+dep[_y]-2*(dep[_x]-1)+1;
}

int main()
{
	scanf("%d",&n);
	for(int i=1,u,v;i<=n;i++)
		scanf("%d%d",&u,&v),
		++u,++v,
		T[u].push_back(v),
		T[v].push_back(u);
	try {dfs(1,0);}
	catch(int t)
	{
		for(int i=1,f=0;i<=top;i++)
		{
			f|=stk[i]==t;
			if(f)
				ringo[stk[i]]=Ring.size(),Ring.push_back(stk[i]),inR[stk[i]]=1;
		}
	}
	for(int p:Ring)
		rt=p,dfst(p,0);
	for(int j=1;j<=12;j++)
		for(int i=1;i<=n;i++)
			jmp[j][i]=jmp[j-1][jmp[j-1][i]];
	double Ans=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			if(bl[i]==bl[j])
				Ans+=1.0/dis(i,j);
			else
			{
				int L=ringo[bl[i]],R=ringo[bl[j]];
				if(L>R)
					swap(L,R);
				int x=dep[i]+dep[j],y=R-L-1,z=Ring.size()-(R-L+1);
				Ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
			}
		}
	printf("%.15lf\n",Ans);
}


#include<bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;

using namespace std;

const int MAXN=3010;

int n,inR[MAXN],dep[MAXN],jmp[13][MAXN];
int top,stk[MAXN],ins[MAXN],bl[MAXN],rt,ringo[MAXN];
vector<int> T[MAXN],Ring;

void dfs(int x,int fa)
{
	ins[stk[++top]=x]=1;
	for(int v:T[x])
		if(v!=fa)
		{
			if(ins[v])
				throw v;
			dfs(v,x);
		}
	ins[stk[top--]]=0;
}

void dfst(int x,int fa)
{
	bl[x]=rt;
	dep[x]=dep[fa]+1;
	jmp[0][x]=fa;
	for(int v:T[x])
		if(v!=fa&&!inR[v])
			dfst(v,x);
}

int dis(int x,int y) //point distance
{
	assert(bl[x]==bl[y]);
	int _x=x,_y=y;
	if(dep[x]<dep[y])
		swap(x,y);
	for(int j=12;~j;j--)
		if(dep[jmp[j][x]]>=dep[y])
			x=jmp[j][x];
	if(x==y)
		return dep[_x]+dep[_y]-2*dep[x]+1;
	for(int j=12;~j;j--)
		if(jmp[j][x]!=jmp[j][y])
			x=jmp[j][x],y=jmp[j][y];
	return dep[_x]+dep[_y]-2*(dep[x]-1)+1;
}

int main()
{
	scanf("%d",&n);
	for(int i=1,u,v;i<=n;i++)
		scanf("%d%d",&u,&v),
		++u,++v,
		T[u].push_back(v),
		T[v].push_back(u);
	try {dfs(1,0);}
	catch(int t)
	{
		for(int i=1,f=0;i<=top;i++)
		{
			f|=stk[i]==t;
			if(f)
				ringo[stk[i]]=Ring.size(),Ring.push_back(stk[i]),inR[stk[i]]=1;
		}
	}
	for(int p:Ring)
		rt=p,dfst(p,0);
	for(int j=1;j<=12;j++)
		for(int i=1;i<=n;i++)
			jmp[j][i]=jmp[j-1][jmp[j-1][i]];
	double Ans=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			if(bl[i]==bl[j])
				Ans+=1.0/dis(i,j);
			else
			{
				int L=ringo[bl[i]],R=ringo[bl[j]];
				if(L>R)
					swap(L,R);
				int x=dep[i]+dep[j],y=R-L-1,z=Ring.size()-(R-L+1);
				Ans+=1.0/(x+y)+1.0/(x+z)-1.0/(x+y+z);
			}
		}
	printf("%.15lf\n",Ans);
}


#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<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;
inline void ins(int x,int y)
{
	adj[++tot]=y; next[tot]=g[x]; g[x]=tot;
}
inline 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++;
}
inline 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);
}
inline 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);

}
inline 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<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);
}

//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;
}


// start fold
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<bitset>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)>>1)
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; short f=1; char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') x=x*10+(c^'0'),c=getchar();
	x*=f;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[30]; short m=0;
	if(x<0) putchar('-'),x=-x;
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T>il void prt(T a[],int n) {for(ri i=0; i<n; ++i) out(a[i],' '); enter;}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=998244353;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
} using namespace MOD_CALC;
namespace i207M
{
// end fold
#define N 3005
int n;
vector<int>E[N];
int du[N];
int sz;
void topo()
{
	static int q[N]; int hd=1,tl=0;
	for(ri i=1; i<=n; ++i) if(du[i]==1) q[++tl]=i;
	while(hd<=tl)
	{
		int x=q[hd++];
		for(solid v:E[x])
			if(--du[v]==1) q[++tl]=v;
	}
	for(ri i=1; i<=n; ++i) if(du[i]==2) ++sz;
}
double ans;
bool vis[N];
void dfs(int x,int d,int h)
{
	if(vis[x]) return;
	vis[x]=1;
	h+=(du[x]==2);
	if(h>=2) ans+=1.0/d+1.0/(d-h+2+sz-h)-1.0/(d+sz-h);
	else ans+=1.0/d;
	for(solid v:E[x]) dfs(v,d+1,h);
}
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);
#endif
	in(n);
	for(ri i=1,a,b; i<=n; ++i)
	{
		in(a,b); ++a,++b;
		E[a].pb(b),E[b].pb(a);
		++du[a],++du[b];
	}
	topo();
	for(ri i=1; i<=n; ++i)
	{
		mem(vis,0);
		dfs(i,1,0);
	}
	printf("%.10f\n",ans);
	return 0;
}
// start fold
}
signed main()
{
	i207M::main();
	return 0;
}
// end fold


#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int N = 3010;
vector<int> e[N];
int n, d[N], rt, tot, vis[N];
int q[N], h = 1, t = 0;
double ans = 0;

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);
	for(int i = 1, x, y; i <= n; i++) {
		scanf("%d%d", &x, &y), ++x, ++y;
		e[x].pb(y), e[y].pb(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;
#define N 6060
int n;
struct apple
{
    int to,next;
}indexx[N];
int head[N],cnt;
void init(int x,int y)
{
    indexx[++cnt].to=y;
    indexx[cnt].next=head[x];
    head[x]=cnt;
}
int st[N],top,belong[N],ff[N],f[N][30];
bool vis[N];
bool dfs1(int u,int fa)
{
    vis[u]=1;
    for(int i=head[u];i;i=indexx[i].next)
    {
        int v=indexx[i].to;
        if(v==fa) continue;
        if(vis[v])
        {
            for(int j=u;j!=v;j=ff[j])
            {
                st[++top]=j;
            }
            st[++top]=v;
            return 1;
        }
        ff[v]=u;
        if(dfs1(v,u)) return 1;
    }
    return 0;
}
int dep[N];
void dfs2(int u,int fa,int rt)
{
    belong[u]=rt;
    f[u][0]=fa;
    dep[u]=dep[fa]+1;
    for(int i=1;i<=20;i++)
    {
        f[u][i]=f[f[u][i-1]][i-1];
    }
    for(int i=head[u];i;i=indexx[i].next)
    {
        int v=indexx[i].to;
        if(v!=fa&&!vis[v])
        {
            dfs2(v,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<=20;i++)
    {
        if(dis&(1<<i)) x=f[x][i];
    }
    if(x==y) return x;
    for(int i=20;i>=0;i--)
    {
        if(f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }
    }
    return f[x][0];
}
double ans;
void solve()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(belong[i]==belong[j])
			{
				ans+=(double)1.000/(dep[i]+dep[j]-2*dep[lca(i,j)]+1);
			}
			else
			{
				double X=dep[i]+dep[j];
				double Y=abs(belong[i]-belong[j])-1;
				double Z=top-Y-2;
				ans+=(double)1.000/(X+Y)+(double)1.000/(X+Z)-(double)1.000/(X+Y+Z);
			}
		}
	}
	printf("%.15lf\n",ans);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        x++;
        y++;
        init(x,y);
        init(y,x);
    }
    dfs1(1,0);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=top;i++)
    {
        vis[st[i]]=1;
    }
    for(int i=1;i<=top;i++)
    {
        dfs2(st[i],0,i);
    }
    solve();
}


#include<bits/stdc++.h>
const int sz=3010;
int vi[sz],low[sz],t;
int sta[sz],top=0;
int con[sz],cir[sz];
std::vector<int>edge[sz],ed[sz];
void dfs(int x,int p){
    vi[x]=low[x]=++t;
    sta[top++]=x;
    for(int k=0;k<edge[x].size();k++){
        int y=edge[x][k];
        if(!vi[y]) dfs(y,x);
        if(y!=p) low[x]=std::min(low[x],low[y]);
    }
    if(vi[x]==low[x]){
        int y;
        do{
            y=sta[--top];
            con[y]=x;
        }while(x!=y);
    }
    return;
}
bool in[sz];
int fi[sz],d[sz],dd[sz],cd[sz],fa[sz];
void DFS(int x,int ff){
    vi[x]=1;
    fa[x]=ff;
    for(int k=0;k<edge[x].size();k++){
        int y=edge[x][k];
        if(in[y]||vi[y]) continue;
        vi[y]=1;
        d[y]=d[x]+1;
        DFS(y,ff);
    }
    return;
}
void cir_dfs(int x){
    vi[x]=1;
    for(int k=0;k<edge[x].size();k++){
        int y=edge[x][k];
        if((!in[y])||vi[y]) continue;
        cd[y]=cd[x]+1;
        cir_dfs(y);
    }
    return;
}
double ans;
void find_dfs(int x){
    vi[x]=1;
    ans+=1/(double)(dd[x]+1);
    for(int k=0;k<edge[x].size();k++){
        int y=edge[x][k];
        if(vi[y]||fa[x]!=fa[y]) continue;
        dd[y]=dd[x]+1;
        find_dfs(y);
    }
    return;
}
int main(){
    int n,k,a,b,num=0,cir,i;
    scanf("%d",&n);
    for(k=1;k<=n;k++){
        scanf("%d%d",&a,&b);
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    dfs(0,0);
    //for(k=0;k<n;k++) printf("%d %d\n",k,con[k]);
    for(k=0;k<n;k++) fi[con[k]]++;
    for(k=0;k<n;k++){
        if(fi[k]>1){
            cir=k;
            break;
        }
    }
    memset(vi,0,sizeof(vi));
    for(k=0;k<n;k++){
        if(con[k]==cir){
            in[k]=1;
            num++;
        }
    }
    cir_dfs(cir);
    for(k=0;k<n;k++){
        if(con[k]==cir){
            DFS(k,k);
        }
    }
    ans=0;
    for(k=0;k<n;k++){
        memset(vi,0,sizeof(vi));
        for(i=0;i<n;i++){
            if(fa[k]==fa[i]) continue;
            int c1,c2,d1,d2;
            d1=d[k]+1;d2=d[i]+1;
            c1=abs(cd[fa[k]]-cd[fa[i]])-1;
            c2=num-c1-2;
            int q=c1+c2+d1+d2;
            //printf("gg%d %d %d\n",q,c1,c2);
            ans+=1/(double)q+(double)c1/(double)q/(double)(q-c1)+(double)c2/(double)q/(double)(q-c2);
        }
        dd[k]=0;
        find_dfs(k);
    }
    printf("%.9f\n",ans);
}
// ntuj - k1dyb5y7txb0dprh66q2d


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> adj[3000];
bool visited[3000];
bool incycle[3000];
int find_cycle(int u, int p) {
    if(visited[u])
        return u;
    visited[u] = true;
    for(int c : adj[u])
        if(c != p) {
            int x = find_cycle(c, u);
            if(x != -1) {
                incycle[u] = true;
                return x == u ? -1 : x;
            }
        }
    return -1;
}
double compute(int a, int b, int nc) {
    if(b == 0)
        return 1.0 / (a + 1);
    int c = nc - b;
    return 1.0 / (a + b + c) +
            (double) (b - 1) / ((a + b + c) * (a + c + 1)) +
            (double) (c - 1) / ((a + b + c) * (a + b + 1));
}
double dfs(int x, int a, int b, int nc) {
    visited[x] = true;
    double ans = compute(a, b, nc);
    // fprintf(stderr, "dfs(%d, %d, %d, %d) %f\n", x, a, b, nc, ans);
    for(int c : adj[x])
        if(!visited[c]) {
            int aa = a, bb = b;
            (incycle[x] && incycle[c] ? bb : aa)++;
            ans += dfs(c, aa, bb, nc);
        }
    return ans;
}
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    find_cycle(0, -1);
    int nc = count(incycle, incycle + n, true);
    double ans = 0;
    for(int i = 0; i < n; i++) {
        fill_n(visited, n, false);
        ans += dfs(i, 0, 0, nc);
    }
    printf("%.15f\n", ans);
}

// ntuj - 31126qgqahp3va85lxugj