#include <bits/stdc++.h>

using namespace std;

#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
 
typedef tree <
   int, // Key Type
   null_type, // Mapped type
   less<int>, // Compare functor
   rb_tree_tag, // Tree tag: [rb_tree_tag|splay_tree_tag|ov_tree_tag]
   tree_order_statistics_node_update // Update policy
> ordered_set;

// Extra functions: find_by_order() and order_of_key()

ordered_set C[200000];
int Set[200000];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n;
	cin >> n;

	vector<pair<int, int>> Edges;
	for(int i = 2; i <= n; ++i) {
		int a, b;
		cin >> a >> b;
		Edges.emplace_back(a, b);
	}

	for(int i = 1; i <= n; ++i) {
		C[i].insert(i);
		Set[i] = i;
	}

	sort(Edges.begin(), Edges.end(), [](pair<int, int> a, pair<int, int> b) {
		return a.first + a.second < b.first + b.second;
	});



	long long m = (n * (n - 1)) / 2;
	for(auto x : Edges) {
		if(C[x.first].size() > C[x.second].size()) 
			swap(x.first, x.second);
		
		// cerr << "Edge: " << x.first << " " << x.second << endl;
		int now = x.first + x.second;
		// cerr << now << endl;

		for(auto node : C[Set[x.first]]) {
			// cerr << "Vars: " << node << endl;
			// Count less
			int cnt = C[Set[x.second]].order_of_key(now - node);
			// cerr << "- " << cnt << endl;
			m -= cnt;
		}

		for(auto node : C[Set[x.first]]) {
			C[Set[x.second]].insert(node);
		}
		C[Set[x.first]].clear();
		Set[x.first] = Set[x.second];
	}

	cout << m << endl;

	return 0;
}