Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Similarity of Subtrees

Define the depth of a node in a rooted tree by applying the following rules recursively:

The depth of a root node is 0.

The depths of child nodes whose parents are with depth $d$ are $d + 1$.

Let $S(T, d)$ be the number of nodes of $T$ with depth $d$. Two rooted trees $T$ and $T'$ are similar if and only if $S(T, d)$ equals $S(T', d)$ for all non-negative integer $d$.

You are given a rooted tree $T$ with $N$ nodes. The nodes of $T$ are numbered from 1 to $N$. Node 1 is the root node of $T$. Let $T_i$ be the rooted subtree of $T$ whose root is node $i$. Your task is to write a program which calculates the number of pairs $(i, j)$ such that $T_i$ and $T_j$ are similar and $i < j$.

Input

The input consists of a single test case.

$N$

$a_1$ $b_1$

$a_2$ $b_2$

...

$a_{N-1}$ $b_{N-1}$

The first line contains an integer $N$ ($1 \leq N \leq 100,000$), which is the number of nodes in a tree. The following $N -1$ lines give information of branches: the $i$-th line of them contains $a_i$ and $b_i$, which indicates that a node $a_i$ is a parent of a node $b_i$. ($1 \leq a_i, b_i \leq N, a_i \ne b_i$) The root node is numbered by 1. It is guaranteed that a given graph is a rooted tree, i.e. there is exactly one parent for each node except the node 1, and the graph is connected.

Output

Print the number of the pairs $(x, y)$ of the nodes such that the subtree with the root $x$ and the subtree with the root $y$ are similar and $x < y$.

Sample Input 1

5
1 2
1 3
1 4
1 5

Output for the Sample Input 1

6

Sample Input 2

6
1 2
2 3
3 4
1 5
5 6

Output for the Sample Input 2

2

Sample Input 3

13
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
6 10
7 11
8 12
11 13

Output for the Sample Input 3

14

Solution in C++ (judge verdict: Accepted)

#include <bits/stdc++.h>

#ifndef ONLINE_JUDGE
    #define gc getchar
    #define pc putchar
#else
    #define gc getchar_unlocked
    #define pc putchar_unlocked
#endif

using namespace std;

#define vi vector<int>
#define vll vector<i64>
#define si set<int>
#define vs vector<string>
#define pii pair<int,int>
#define vpi vector<pii>
#define pri priority_queue<int>
#define rev_pri priority_queue<int,vector<int>,greater<int> >
#define mpi map<int,int>
#define i64 long long int
#define endl '\n'
#define pi acos(-1)
#define all(v) v.begin(),v.end()
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define For(i,n) for(int i=0;i<n;i++)
#define Fre(i,a,b) for(int i = a; i < b; i++)
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pfn(n) printf("%d\n", n)
#define pfs(n) printf("%d ", n)
#define eps 1e-8
#define ff first
#define ss second
#define mem(a,b) memset(a,b,sizeof(a))
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define READ freopen("in.txt", "r", stdin)
#define WRITE freopen("out.txt", "w", stdout)
#define sz size()
#define dbg(i) printf("yo %d\n", i)
#define foreach(i,c) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define sqr(a) (a) * (a)
#define clr clear()
#define CASE(a) printf("Case %d: ",a)

//int dx[] = {0,1,0,-1,1,1,-1,-1};
//int dy[] = {1,0,-1,0,1,-1,-1,1};
//i64 dp[60][60];


//functions

//i64 gcd(i64 a,i64 b){if(!b)return a;return gcd(b,a%b);}

//inline void fastRead(int *a){register char c=0;while(c<33)c=gc();*a=0;while(c>33){*a=*a*10+c-'0';c=gc();}}

//inline void fastWrite(int a){char snum[20];int i=0;do{snum[i++]=a%10+48;a=a/10;}while(a!=0);i=i-1;while(i>=0)pc(snum[i--]);pc('\n');}

//i64 bigmod(i64 num,i64 n){if(n==0)return 1;i64 x=bigmod(num,n/2);x=x*x%mod;if(n%2==1)x=x*num%mod;return x;}

//i64 modinverse(i64 num){return bigmod(num,mod-2)%mod;}

//void combination(int pos,int last){if(pos==k+1){for(int i=1;i<=k;i++)cout << tem[i];cout << endl;return;}
//for(int i=last+1;i<=n-k+pos;i++){tem[pos] = num[i-1];combination(pos+1,i);}}

//i64 po(i64 a,i64 b){i64 ans=1;while(b--)ans *= a;return ans;}

//i64 ncr(i64 n,i64 r){if(n==r)return 1;if(r==1)return n;if(dp[n][r]!=-1)return dp[n][r];return dp[n][r]=ncr(n-1,r)+ncr(n-1,r-1);}

//int popcount(i64 num){bitset<70> tem(num);return tem.count();}

//matrix rot(matrix a){matrix res;res.row = a.col;res.col = a.row;For(i,a.row)For(j,a.col)res.mat[j][a.row-i-1] = a.mat[i][j];return res;}

#define bs 141
vi v[100005];
i64 hs[100005];

void dfs(int s)
{
        hs[s] = 1;

        For(i,v[s].sz)
        {
                int w = v[s][i];
                dfs(w);
                hs[s] += (bs * hs[w]) % mod;
                hs[s] %= mod;
        }
}


int main()
{

        //ios_base::sync_with_stdio(false);cin.tie(0);
        int n,x,y;
        sf(n);
        For(i,n-1)
        {
                sff(x,y);
                v[x].pb(y);
        }

        dfs(1);

        map<i64,i64> m;
        i64 ans = 0;

        Fre(i,1,n+1)
                m[hs[i]]++;

        foreach(i,m)
                ans += (i->ss * (i->ss - 1) )/ 2;

        cout << ans << endl;





        return 0;
}