#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
//#include <ctime>
#include <map>
using namespace std;
// FFT on complex filed. (You can also use FFT on finite field.)
complex <double> x[1<<20];
complex <double> y[1<<20];
complex <double> r[1<<20];
namespace Fourier
{
// n must be 2^k
complex <double> t[1<<20];
void FFT(complex <double> *array, int n, double pi = M_PI)
{
for(int step = n>>1; step >= 1; step >>= 1)
{
complex <double> w(cos(2 * pi * step / n), sin(2 * pi * step / n));
for(int start = 0; start < step; start ++)
{
complex <double> factor(1, 0);
int z = 0;
for(int i = start; i < n; i += step << 1)
{
array[i+step] *= factor;
array[i] += array[i+step];
array[i+step] = array[i] - array[i+step] - array[i+step];
factor *= w;
t[z] = array[i];
t[z+n/step/2] = array[i+step];
z ++;
}
z = 0;
for(int i = start; i < n; i += step)
array[i] = t[z++];
}
}
for(int i = 0; i < n; i++)
array[i] *= complex <double> (1/sqrt(n), 0);
}
void IFFT(complex <double> *array, int n)
{
FFT(array, n, -M_PI);
}
void cyclic_convolution(complex <double> *A, complex <double> *B, complex <double> *result, int n)
{
FFT(A, n);
FFT(B, n);
for(int i = 0; i < n; i++)
result[i] = A[i] * B[i];
IFFT(result, n);
for(int i = 0; i < n; i++)
result[i] *= complex <double> (sqrt(n), 0);
}
}
int n;
const int MAXN = 200000;
const int MAXDEPTH = 20;
vector <int> e[MAXN];
int cntNodes[MAXN];
int minValue, center;
vector <int> cache[MAXDEPTH][4];
int cache_ans[MAXDEPTH][4][MAXN];
int ans[MAXN];
int temp1[MAXN];
int temp2[MAXN];
int temp3[MAXN];
int temp[MAXN];
int saveN[MAXDEPTH];
// find the minimal n such that 2**n > x
int minimalPow2(int x)
{
int ret = 0;
int t = 1;
while(t < x)
{
ret ++;
t = t + t;
}
return ret;
}
// use dfs to find the center of a tree
int dfs(int cur, int from, int d, int n, bool special = false, int depth = -1)
{
if(special)
cache_ans[depth][0][d] ++;
cntNodes[cur] = 1;
int maxSubTree = 0, cnt = 0;
for(int i = 0; i < e[cur].size(); i++)
if(e[cur][i] != from)
{
int t = dfs(e[cur][i], cur, d+1, n, special, depth);
cntNodes[cur] += cntNodes[e[cur][i]];
cnt += t;
maxSubTree = max(maxSubTree, t);
}
maxSubTree = max(maxSubTree, n-1-cnt);
if(n > 0 && maxSubTree < minValue)
{
center = cur;
minValue = maxSubTree;
}
return cnt + 1;
}
int totNodes;
int findCenter(int root, int depth)
{
int n = dfs(root, -1, 0, 0, true, depth);
minValue = 100000000;
totNodes = dfs(root, -1, 0, n, false, depth);
dfs(center, -1, 0, n, false, depth);
return center;
}
// A[i]: number of nodes have a distance i from subtree A
// B[i]: number of nodes have a distance i from subtree B
// Update all pathes between subtree A and subtree B
void calcPair(int *A, int *B, int N)
{
for(int i = 0; i < (1<<N); i++)
{
x[i] = complex <double> (A[i], 0);
y[i] = complex <double> (B[i], 0);
}
Fourier :: cyclic_convolution(x, y, r, 1<<N);
for(int i = 1; i < (1<<N); i++)
ans[i] += (long long)(r[i].real() + 0.5);
}
void solve(int root, int depth, int reqN)
{
for(int i = 0; i < (1<<reqN); i++)
{
cache_ans[depth][0][i] = 0;
cache_ans[depth][1][i] = 0;
cache_ans[depth][2][i] = 0;
cache_ans[depth][3][i] = 0;
}
int center = findCenter(root, depth);
int totalNodes = cntNodes[center];
cache_ans[depth][0][0] = 1;
if(totalNodes <= 2)
{
if(totalNodes == 2)
{
cache_ans[depth][0][1] = 1;
ans[1] ++;
}
return;
}
cache[depth][0] = e[center];
cache[depth][1].clear(), cache[depth][2].clear(), cache[depth][3].clear();
int cnt = 1;
// The subtree will be grouped into 3 parts, each one has a size no more than N/2.
for(int i = 0; i < e[center].size(); i++)
{
int before = cnt;
int after = cnt + cntNodes[e[center][i]];
cnt = after;
if(after <= totalNodes / 2)
cache[depth][1].push_back(e[center][i]);
else if(before <= totalNodes / 2)
cache[depth][2].push_back(e[center][i]);
else
cache[depth][3].push_back(e[center][i]);
}
int N = minimalPow2(totalNodes);
N = max(N, 2);
e[center] = cache[depth][1];
solve(center, depth + 1, N);
for(int i = 1; i < (1<<N); i++)
cache_ans[depth][1][i] = cache_ans[depth+1][0][i];
e[center] = cache[depth][2];
solve(center, depth + 1, N);
for(int i = 1; i < (1<<N); i++)
cache_ans[depth][2][i] = cache_ans[depth+1][0][i];
e[center] = cache[depth][3];
solve(center, depth + 1, N);
for(int i = 1; i < (1<<N); i++)
cache_ans[depth][3][i] = cache_ans[depth+1][0][i];
e[center] = cache[depth][0];
for(int i = 0; i < (1<<reqN); i++)
{
temp1[i] = cache_ans[depth][1][i];
temp2[i] = cache_ans[depth][2][i];
temp3[i] = cache_ans[depth][3][i];
}
calcPair(temp1, temp2, reqN);
calcPair(temp1, temp3, reqN);
calcPair(temp2, temp3, reqN);
}
bool isPrime[1000001];
int MAIN()
{
memset(isPrime, true, sizeof(isPrime));
isPrime[0] = isPrime[1] = false;
for(int i = 2; i <= 1000000; i++)
if(isPrime[i])
for(int j = i+i; j <= 1000000; j+=i)
isPrime[j] = false;
memset(ans, 0, sizeof(ans));
memset(cache_ans, 0, sizeof(cache_ans));
cin >> n;
for(int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
e[a].push_back(b);
e[b].push_back(a);
}
solve(1, 0, minimalPow2(n));
double total = 0, sum = 0;
for(int i = 1; i <= n; i++)
{
total += ans[i];
if(isPrime[i])
sum += ans[i];
}
cout << sum / total << endl;
return 0;
}
int main()
{
//srand((unsigned)time(NULL));
#ifdef LOCAL_TEST
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
ios :: sync_with_stdio(false);
cout << fixed << setprecision(16);
return MAIN();
}