stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int>pii;

const int N = 1e5+5;

const ll p = 9901;

const ll mod = 1e9+7;

const double eps = 1e-8;

int n,m,k;

ll has[N];

vector<int>edg[N];

map<ll,ll>mp;

map<ll,ll>::iterator it;

void dfs(int u,int fa){

    has[u]=1;

    for(int v:edg[u]){

        dfs(v,u);

        has[u]=(has[u]+has[v]*p)%mod;

    }

    mp[has[u]]++;

}

int main()

{

    int u,v;

    scanf("%d",&n);

    for(int i=1;i<n;i++){

        scanf("%d%d",&u,&v);

        edg[u].push_back(v);

    }

    dfs(1,0);

    ll ans=0;

    for(it =mp.begin();it!=mp.end();it++){

        ans+=(it->second-1)*it->second/2;

    }

    printf("%lld\n",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.51525015482095x):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <map>



#define MAXN 100005



using namespace std;



struct edge

{

	int y,next;

};



edge v[2*MAXN];

int head[MAXN];

int tot = 0;

long long ans = 0;

map<unsigned long long,int> S;



void add(int x,int y)

{

	tot++;

	v[tot].y = y;

	v[tot].next = head[x];

	head[x] = tot;

}



unsigned long long dfs(int x,int fa)

{

	unsigned long long temp = 1;

	for (int i=head[x];i;i=v[i].next)

	{

		if (v[i].y == fa) continue;

		temp += 131*dfs(v[i].y,x);

	}

	ans += S[temp];

	S[temp]++;

	return temp;

}



int main()

{

	int x,y,n;

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		scanf("%d%d",&x,&y);

		add(x,y);

		add(y,x);

	}



	S.clear();

	ans = 0;

	dfs(1,0);



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ull unsigned long long

#define ll long long

ll ans;

map<ull,ll>m;

const int maxn=200005;

vector<int>g[maxn];

ull dp[maxn];

const ull b=1000000007;

void dfs(int u,int p)

{

	dp[u]=1;

	for(int i=0;i<g[u].size();i++)

	{

		int v=g[u][i];

		if(v==p)

		continue;

		dfs(v,u);

		dp[u]+=dp[v]*b;

	}

	ans+=m[dp[u]];

	m[dp[u]]++;

}

int main()

{

	int n;

	scanf("%d",&n);

	for(int i=1;i<n;i++)

	{

		int u,v;

		scanf("%d%d",&u,&v);

		g[u].push_back(v);

		g[v].push_back(u);

	}

	dfs(1,-1);

	printf("%lld\n",ans);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.441578142101081x):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <map>



#define MAXN 100005



using namespace std;



struct edge

{

	int y,next;

};



edge v[2*MAXN];

int head[MAXN];

int tot = 0;

long long ans = 0;

map<unsigned long long,int> S;



void add(int x,int y)

{

	tot++;

	v[tot].y = y;

	v[tot].next = head[x];

	head[x] = tot;

}



unsigned long long dfs(int x,int fa)

{

	unsigned long long temp = 1;

	for (int i=head[x];i;i=v[i].next)

	{

		if (v[i].y == fa) continue;

		temp += 131*dfs(v[i].y,x);

	}

	ans += S[temp];

	S[temp]++;

	return temp;

}



int main()

{

	int x,y,n;

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		scanf("%d%d",&x,&y);

		add(x,y);

		add(y,x);

	}



	S.clear();

	ans = 0;

	dfs(1,0);



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:


#include<algorithm>

#include<vector>

 #include<cstring>

#include<string>

#include<iomanip>

#include<cstdio>

#include<stack>

#include<iostream>

#include<map>

#include<queue>

#include<cmath>

using namespace std;

#define sf scanf

#define pf printf

#define mem(a,b) memset(a,b,sizeof(a));

#define rep(i,a,b) for(int i=(a);i<=(b);++i)

#define mod 998244353

#define N 100020

#define M 400020

#define ULL unsigned long long

#define LL long long

#define inf 0x3f3f3f3f

map<ULL,LL>mp;

vector<int>g[N];

ULL dp[N];

LL ans;int n;

const ULL b=1000000007;

void dfs(int u,int fa){

    dp[u]=1;

    for(int i=0;i<g[u].size();++i){

        int v=g[u][i];

        if(v==fa)continue;

        dfs(v,u);

        dp[u]+=dp[v]*b;

    }

    ans+=mp[dp[u]];

    mp[dp[u]]++;

}

int main(){

    sf("%d",&n);

        ans=0;

        rep(i,1,n-1){

            int u,v;sf("%d%d",&u,&v);

            g[u].push_back(v);g[v].push_back(u);

        }

        dfs(1,1);

        cout<<ans<<'\n';

}

// Faster C++ solution for the same problem (measured speedup: 3.5300443255762053x):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <map>



#define MAXN 100005



using namespace std;



struct edge

{

	int y,next;

};



edge v[2*MAXN];

int head[MAXN];

int tot = 0;

long long ans = 0;

map<unsigned long long,int> S;



void add(int x,int y)

{

	tot++;

	v[tot].y = y;

	v[tot].next = head[x];

	head[x] = tot;

}



unsigned long long dfs(int x,int fa)

{

	unsigned long long temp = 1;

	for (int i=head[x];i;i=v[i].next)

	{

		if (v[i].y == fa) continue;

		temp += 131*dfs(v[i].y,x);

	}

	ans += S[temp];

	S[temp]++;

	return temp;

}



int main()

{

	int x,y,n;

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		scanf("%d%d",&x,&y);

		add(x,y);

		add(y,x);

	}



	S.clear();

	ans = 0;

	dfs(1,0);



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include<algorithm>

#include<iostream>

#include<cstring>

#include<cstdlib>

#include<cstdio>

#include<bitset>

#include<vector>

#include<queue>

#include<stack>

#include<map>

#include<set>

#include<cmath>

#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

const ll base = 999983;

const int maxn = 1e5+5;

int n,ind[maxn];

vector<ll> htable;

vector<int> G[maxn];



ll dfs(int u)

{

    ll temp = 0;

    for(int i=0;i<G[u].size();++i){

        temp += dfs(G[u][i]);

    }

    htable.push_back(temp*base+G[u].size());

    return temp*base+G[u].size();

}



inline ll work(ll m)

{

    return m*(m-1)>>1;

}



int main()

{

    while(~scanf("%d",&n)){

        htable.clear();

        memset(ind,0,sizeof ind);

        for(int i=0;i<=n;++i) G[i].clear();

        for(int i=0;i<n-1;++i){

            int u,v; scanf("%d%d",&u,&v);

            G[u].push_back(v);

            ++ind[v];

        }

        int s = 0;

        for(int i=1;i<=n && !s;++i){

            if(ind[i] == 0) s = i;

        }

        dfs(s);

        sort(htable.begin(),htable.end());

        ll num = 1;

        ll ans = 0;

        for(int i=1;i<htable.size();++i){

            if(htable[i] != htable[i-1]){

                ans += work(num);

                num = 1;

            }

            else ++num;

        }

        if(htable.size() > 1 && htable[htable.size()-1] == htable[htable.size()-2]) ans += work(num);

        printf("%lld\n",ans);

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.9173402316847175x):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <map>



#define MAXN 100005



using namespace std;



struct edge

{

	int y,next;

};



edge v[2*MAXN];

int head[MAXN];

int tot = 0;

long long ans = 0;

map<unsigned long long,int> S;



void add(int x,int y)

{

	tot++;

	v[tot].y = y;

	v[tot].next = head[x];

	head[x] = tot;

}



unsigned long long dfs(int x,int fa)

{

	unsigned long long temp = 1;

	for (int i=head[x];i;i=v[i].next)

	{

		if (v[i].y == fa) continue;

		temp += 131*dfs(v[i].y,x);

	}

	ans += S[temp];

	S[temp]++;

	return temp;

}



int main()

{

	int x,y,n;

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		scanf("%d%d",&x,&y);

		add(x,y);

		add(y,x);

	}



	S.clear();

	ans = 0;

	dfs(1,0);



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

const int N=100005;

typedef long long int LL;





vector<int >ve[N];

map< LL , int >ma;

LL a[N];

LL b=10e2+7;

LL ans;

void dfs(int u)

{

    a[u]=1;

    for(int i=0;i<ve[u].size();i++)

    {

        int v=ve[u][i];

        dfs(v);

        a[u]+=a[v]*b;

    }

    ans+=ma[a[u]];

    ma[a[u]]++;

    return ;

}



int main()

{

    int n;

        cin>>n;

        int u,v;

        for(int i=0;i<n-1;i++)

        {

            cin>>u>>v;

            ve[u].push_back(v);

        }

        ans=0;

        dfs(1);

        cout<<ans<<endl;





    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.530650215698119x):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <map>



#define MAXN 100005



using namespace std;



struct edge

{

	int y,next;

};



edge v[2*MAXN];

int head[MAXN];

int tot = 0;

long long ans = 0;

map<unsigned long long,int> S;



void add(int x,int y)

{

	tot++;

	v[tot].y = y;

	v[tot].next = head[x];

	head[x] = tot;

}



unsigned long long dfs(int x,int fa)

{

	unsigned long long temp = 1;

	for (int i=head[x];i;i=v[i].next)

	{

		if (v[i].y == fa) continue;

		temp += 131*dfs(v[i].y,x);

	}

	ans += S[temp];

	S[temp]++;

	return temp;

}



int main()

{

	int x,y,n;

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		scanf("%d%d",&x,&y);

		add(x,y);

		add(y,x);

	}



	S.clear();

	ans = 0;

	dfs(1,0);



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

const int N=100005;

typedef long long int LL;





vector<int >ve[N];

map< LL , int >ma;

LL a[N];

LL b=17;

LL ans;

void dfs(int u)

{

    a[u]=1;

    for(int i=0;i<ve[u].size();i++)

    {

        int v=ve[u][i];

        dfs(v);

        a[u]+=a[v]*b;

    }

    ans+=ma[a[u]];

    ma[a[u]]++;

    return ;

}



int main()

{

    int n;

        cin>>n;

        int u,v;

        for(int i=0;i<n-1;i++)

        {

            cin>>u>>v;

            ve[u].push_back(v);

        }

        ans=0;

        dfs(1);

        cout<<ans<<endl;





    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.530650215698119x):
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <map>



#define MAXN 100005



using namespace std;



struct edge

{

	int y,next;

};



edge v[2*MAXN];

int head[MAXN];

int tot = 0;

long long ans = 0;

map<unsigned long long,int> S;



void add(int x,int y)

{

	tot++;

	v[tot].y = y;

	v[tot].next = head[x];

	head[x] = tot;

}



unsigned long long dfs(int x,int fa)

{

	unsigned long long temp = 1;

	for (int i=head[x];i;i=v[i].next)

	{

		if (v[i].y == fa) continue;

		temp += 131*dfs(v[i].y,x);

	}

	ans += S[temp];

	S[temp]++;

	return temp;

}



int main()

{

	int x,y,n;

	scanf("%d",&n);

	for (int i=1;i<n;i++)

	{

		scanf("%d%d",&x,&y);

		add(x,y);

		add(y,x);

	}



	S.clear();

	ans = 0;

	dfs(1,0);



	cout << ans << endl;

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



const int N = 1e5 + 10;

const unsigned X = 1234567;

const unsigned R = 7531;



int n;

unsigned h[N];

vector <int> g[N];

map <unsigned, int> f;



void dfs (int u, int p) {

	unsigned now = 0;

	for (int v : g[u]) if (v != p) {

		dfs(v, u); 

		now += h[v];

	}

	h[u] = now * X + R;

	++f[h[u]];  

}



int main (int argc, char const *argv[]) {

	scanf("%d", &n);

	for (int i = 1; i < n; ++i) {

		int u, v;

		scanf("%d %d", &u, &v);

		g[u].push_back(v);

		g[v].push_back(u);

	}



	dfs(1, 0);



	long long ans = 0;

	for (auto it : f) {

		long long cnt = (long long) it.second;

		ans += (cnt * (cnt - 1LL))/2LL;

	}



	printf("%lld\n", ans);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.527606241882606x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<cmath>

#include<set>

#include<map>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define fi first

#define se second

#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;

typedef vector<int> VI;

typedef long long ll;

typedef pair<double,int> PII;

const ll p=998244353;

const ll mod=1e9+7;

const int maxn=1e5+100;

map<ll,int> mp;



struct node

{

    int to,next;

}e[maxn*2];



int tol=0;

int head[maxn];

void add(int u,int v)

{

    e[++tol].to=v,e[tol].next=head[u],head[u]=tol;

}

ll dfs(int u,int f)

{

    ll ans=1;

    for(int i=head[u];i;i=e[i].next)

    {

        int v=e[i].to;

        if(v==f) continue;

        ans=(ans+dfs(v,u)*mod%p)%p;

    }

    mp[ans]++;

    return ans;

}





int main()

{

    int n;

    scanf("%d",&n);

    rep(i,1,n)

    {

        int u,v;

        scanf("%d%d",&u,&v);

        add(u,v),add(v,u);

    }

    mp.clear();

    dfs(1,0);

    ll ans=0;

    map<ll,int>::iterator it;

    for(it=mp.begin();it!=mp.end();it++) ans+=1ll*(it->se)*(it->se-1)/2;

    printf("%lld\n",ans);

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<int,int>pii;

const int N = 1e5+5;

const ll p = 9901;

const ll mod = 1e9+7;

const double eps = 1e-8;

int n,m,k;

ll has[N];

vector<int>edg[N];

map<ll,ll>mp;

map<ll,ll>::iterator it;

void dfs(int u,int fa){

    has[u]=1;

    for(int v:edg[u]){

        dfs(v,u);

        has[u]=(has[u]+has[v]*p)%mod;

    }

    mp[has[u]]++;

}

int main()

{

    int u,v;

    scanf("%d",&n);

    for(int i=1;i<n;i++){

        scanf("%d%d",&u,&v);

        edg[u].push_back(v);

    }

    dfs(1,0);

    ll ans=0;

    for(it =mp.begin();it!=mp.end();it++){

        ans+=(it->second-1)*it->second/2;

    }

    printf("%lld\n",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.5269095215373505x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<cmath>

#include<set>

#include<map>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define fi first

#define se second

#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;

typedef vector<int> VI;

typedef long long ll;

typedef pair<double,int> PII;

const ll p=998244353;

const ll mod=1e9+7;

const int maxn=1e5+100;

map<ll,int> mp;



struct node

{

    int to,next;

}e[maxn*2];



int tol=0;

int head[maxn];

void add(int u,int v)

{

    e[++tol].to=v,e[tol].next=head[u],head[u]=tol;

}

ll dfs(int u,int f)

{

    ll ans=1;

    for(int i=head[u];i;i=e[i].next)

    {

        int v=e[i].to;

        if(v==f) continue;

        ans=(ans+dfs(v,u)*mod%p)%p;

    }

    mp[ans]++;

    return ans;

}





int main()

{

    int n;

    scanf("%d",&n);

    rep(i,1,n)

    {

        int u,v;

        scanf("%d%d",&u,&v);

        add(u,v),add(v,u);

    }

    mp.clear();

    dfs(1,0);

    ll ans=0;

    map<ll,int>::iterator it;

    for(it=mp.begin();it!=mp.end();it++) ans+=1ll*(it->se)*(it->se-1)/2;

    printf("%lld\n",ans);

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ull unsigned long long

#define ll long long

ll ans;

map<ull,ll>m;

const int maxn=200005;

vector<int>g[maxn];

ull dp[maxn];

const ull b=1000000007;

void dfs(int u,int p)

{

	dp[u]=1;

	for(int i=0;i<g[u].size();i++)

	{

		int v=g[u][i];

		if(v==p)

		continue;

		dfs(v,u);

		dp[u]+=dp[v]*b;

	}

	ans+=m[dp[u]];

	m[dp[u]]++;

}

int main()

{

	int n;

	scanf("%d",&n);

	for(int i=1;i<n;i++)

	{

		int u,v;

		scanf("%d%d",&u,&v);

		g[u].push_back(v);

		g[v].push_back(u);

	}

	dfs(1,-1);

	printf("%lld\n",ans);

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.462943541001101x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<cmath>

#include<set>

#include<map>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define fi first

#define se second

#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;

typedef vector<int> VI;

typedef long long ll;

typedef pair<double,int> PII;

const ll p=998244353;

const ll mod=1e9+7;

const int maxn=1e5+100;

map<ll,int> mp;



struct node

{

    int to,next;

}e[maxn*2];



int tol=0;

int head[maxn];

void add(int u,int v)

{

    e[++tol].to=v,e[tol].next=head[u],head[u]=tol;

}

ll dfs(int u,int f)

{

    ll ans=1;

    for(int i=head[u];i;i=e[i].next)

    {

        int v=e[i].to;

        if(v==f) continue;

        ans=(ans+dfs(v,u)*mod%p)%p;

    }

    mp[ans]++;

    return ans;

}





int main()

{

    int n;

    scanf("%d",&n);

    rep(i,1,n)

    {

        int u,v;

        scanf("%d%d",&u,&v);

        add(u,v),add(v,u);

    }

    mp.clear();

    dfs(1,0);

    ll ans=0;

    map<ll,int>::iterator it;

    for(it=mp.begin();it!=mp.end();it++) ans+=1ll*(it->se)*(it->se-1)/2;

    printf("%lld\n",ans);

    return 0;

}
// Slower C++ solution:


#include<algorithm>

#include<vector>

 #include<cstring>

#include<string>

#include<iomanip>

#include<cstdio>

#include<stack>

#include<iostream>

#include<map>

#include<queue>

#include<cmath>

using namespace std;

#define sf scanf

#define pf printf

#define mem(a,b) memset(a,b,sizeof(a));

#define rep(i,a,b) for(int i=(a);i<=(b);++i)

#define mod 998244353

#define N 100020

#define M 400020

#define ULL unsigned long long

#define LL long long

#define inf 0x3f3f3f3f

map<ULL,LL>mp;

vector<int>g[N];

ULL dp[N];

LL ans;int n;

const ULL b=1000000007;

void dfs(int u,int fa){

    dp[u]=1;

    for(int i=0;i<g[u].size();++i){

        int v=g[u][i];

        if(v==fa)continue;

        dfs(v,u);

        dp[u]+=dp[v]*b;

    }

    ans+=mp[dp[u]];

    mp[dp[u]]++;

}

int main(){

    sf("%d",&n);

        ans=0;

        rep(i,1,n-1){

            int u,v;sf("%d%d",&u,&v);

            g[u].push_back(v);g[v].push_back(u);

        }

        dfs(1,1);

        cout<<ans<<'\n';

}

// Faster C++ solution for the same problem (measured speedup: 3.541752761535051x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<cmath>

#include<set>

#include<map>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define fi first

#define se second

#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;

typedef vector<int> VI;

typedef long long ll;

typedef pair<double,int> PII;

const ll p=998244353;

const ll mod=1e9+7;

const int maxn=1e5+100;

map<ll,int> mp;



struct node

{

    int to,next;

}e[maxn*2];



int tol=0;

int head[maxn];

void add(int u,int v)

{

    e[++tol].to=v,e[tol].next=head[u],head[u]=tol;

}

ll dfs(int u,int f)

{

    ll ans=1;

    for(int i=head[u];i;i=e[i].next)

    {

        int v=e[i].to;

        if(v==f) continue;

        ans=(ans+dfs(v,u)*mod%p)%p;

    }

    mp[ans]++;

    return ans;

}





int main()

{

    int n;

    scanf("%d",&n);

    rep(i,1,n)

    {

        int u,v;

        scanf("%d%d",&u,&v);

        add(u,v),add(v,u);

    }

    mp.clear();

    dfs(1,0);

    ll ans=0;

    map<ll,int>::iterator it;

    for(it=mp.begin();it!=mp.end();it++) ans+=1ll*(it->se)*(it->se-1)/2;

    printf("%lld\n",ans);

    return 0;

}
// Slower C++ solution:
#include<algorithm>

#include<iostream>

#include<cstring>

#include<cstdlib>

#include<cstdio>

#include<bitset>

#include<vector>

#include<queue>

#include<stack>

#include<map>

#include<set>

#include<cmath>

#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

const ll base = 999983;

const int maxn = 1e5+5;

int n,ind[maxn];

vector<ll> htable;

vector<int> G[maxn];



ll dfs(int u)

{

    ll temp = 0;

    for(int i=0;i<G[u].size();++i){

        temp += dfs(G[u][i]);

    }

    htable.push_back(temp*base+G[u].size());

    return temp*base+G[u].size();

}



inline ll work(ll m)

{

    return m*(m-1)>>1;

}



int main()

{

    while(~scanf("%d",&n)){

        htable.clear();

        memset(ind,0,sizeof ind);

        for(int i=0;i<=n;++i) G[i].clear();

        for(int i=0;i<n-1;++i){

            int u,v; scanf("%d%d",&u,&v);

            G[u].push_back(v);

            ++ind[v];

        }

        int s = 0;

        for(int i=1;i<=n && !s;++i){

            if(ind[i] == 0) s = i;

        }

        dfs(s);

        sort(htable.begin(),htable.end());

        ll num = 1;

        ll ans = 0;

        for(int i=1;i<htable.size();++i){

            if(htable[i] != htable[i-1]){

                ans += work(num);

                num = 1;

            }

            else ++num;

        }

        if(htable.size() > 1 && htable[htable.size()-1] == htable[htable.size()-2]) ans += work(num);

        printf("%lld\n",ans);

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.930333249052623x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<cmath>

#include<set>

#include<map>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define fi first

#define se second

#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;

typedef vector<int> VI;

typedef long long ll;

typedef pair<double,int> PII;

const ll p=998244353;

const ll mod=1e9+7;

const int maxn=1e5+100;

map<ll,int> mp;



struct node

{

    int to,next;

}e[maxn*2];



int tol=0;

int head[maxn];

void add(int u,int v)

{

    e[++tol].to=v,e[tol].next=head[u],head[u]=tol;

}

ll dfs(int u,int f)

{

    ll ans=1;

    for(int i=head[u];i;i=e[i].next)

    {

        int v=e[i].to;

        if(v==f) continue;

        ans=(ans+dfs(v,u)*mod%p)%p;

    }

    mp[ans]++;

    return ans;

}





int main()

{

    int n;

    scanf("%d",&n);

    rep(i,1,n)

    {

        int u,v;

        scanf("%d%d",&u,&v);

        add(u,v),add(v,u);

    }

    mp.clear();

    dfs(1,0);

    ll ans=0;

    map<ll,int>::iterator it;

    for(it=mp.begin();it!=mp.end();it++) ans+=1ll*(it->se)*(it->se-1)/2;

    printf("%lld\n",ans);

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

const int N=100005;

typedef long long int LL;





vector<int >ve[N];

map< LL , int >ma;

LL a[N];

LL b=10e2+7;

LL ans;

void dfs(int u)

{

    a[u]=1;

    for(int i=0;i<ve[u].size();i++)

    {

        int v=ve[u][i];

        dfs(v);

        a[u]+=a[v]*b;

    }

    ans+=ma[a[u]];

    ma[a[u]]++;

    return ;

}



int main()

{

    int n;

        cin>>n;

        int u,v;

        for(int i=0;i<n-1;i++)

        {

            cin>>u>>v;

            ve[u].push_back(v);

        }

        ans=0;

        dfs(1);

        cout<<ans<<endl;





    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.5423606612707355x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<cmath>

#include<set>

#include<map>

using namespace std;

#define rep(i,a,n) for (int i=a;i<n;i++)

#define per(i,a,n) for (int i=n-1;i>=a;i--)

#define pb push_back

#define fi first

#define se second

#define dbg(...) cerr<<"["<<#__VA_ARGS__":"<<(__VA_ARGS__)<<"]"<<endl;

typedef vector<int> VI;

typedef long long ll;

typedef pair<double,int> PII;

const ll p=998244353;

const ll mod=1e9+7;

const int maxn=1e5+100;

map<ll,int> mp;



struct node

{

    int to,next;

}e[maxn*2];



int tol=0;

int head[maxn];

void add(int u,int v)

{

    e[++tol].to=v,e[tol].next=head[u],head[u]=tol;

}

ll dfs(int u,int f)

{

    ll ans=1;

    for(int i=head[u];i;i=e[i].next)

    {

        int v=e[i].to;

        if(v==f) continue;

        ans=(ans+dfs(v,u)*mod%p)%p;

    }

    mp[ans]++;

    return ans;

}





int main()

{

    int n;

    scanf("%d",&n);

    rep(i,1,n)

    {

        int u,v;

        scanf("%d%d",&u,&v);

        add(u,v),add(v,u);

    }

    mp.clear();

    dfs(1,0);

    ll ans=0;

    map<ll,int>::iterator it;

    for(it=mp.begin();it!=mp.end();it++) ans+=1ll*(it->se)*(it->se-1)/2;

    printf("%lld\n",ans);

    return 0;

}