#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using ll = long long;
#define NMAX 100010

struct treap
{
	int val, sz, pri;
	treap *l, *r;

	treap(int _val = 0) { val = _val; sz = 1; pri = rand(); l = r = nullptr; }
};
using Treap = treap*;

int fth[NMAX];
vector<pii> edges;
Treap tr[NMAX];

int size(Treap root)
{
	if(!root) return 0;
	return root->sz;
}

void upd(Treap root)
{
	root->sz = 1 + size(root->l) + size(root->r);
}

void split(Treap root, int val, Treap &l, Treap &r)
{
	if(!root) { l = r = nullptr; return; }

	if(root->val < val) split(root->r, val, root->r, r), l = root;
	else split(root->l, val, l, root->l), r = root;
}

int query(Treap root, int val)
{
	// how many nodes in root are >= val
	if(!root) return 0;

	if(root->val < val) return query(root->r, val);
	else if(root->val == val) return 1 + size(root->r);
	else return query(root->l, val) + 1 + size(root->r);
}

void insert(Treap &root, Treap item)
{
	if(!root) { root = item; return; }

	if(item->pri > root->pri) split(root, item->val, item->l, item->r), root = item;
	else insert(root->val < item->val ? root->r : root->l, item);

	upd(root);
}

int getFth(int a)
{
	if(!fth[a]) return a;
	return fth[a] = getFth(fth[a]);
}

bool cmp(const pii &p1, const pii &p2)
{
	return p1.first + p1.second < p2.first + p2.second;
}

ll queryNewEdges(Treap a, Treap b, int cost)
{
	if(!a) return 0;

	ll ret = query(b, cost - a->val);
	ret += queryNewEdges(a->l, b, cost);
	ret += queryNewEdges(a->r, b, cost);

	return ret;
}

void joinTreaps(Treap a, Treap b)
{
	if(!a) return;

	joinTreaps(a->l, b);
	joinTreaps(a->r, b);

	insert(b, a);
}

ll join(int a, int b)
{
	Treap t1 = tr[getFth(a)], t2 = tr[getFth(b)];

	if(size(t1) > size(t2)) swap(a, b), swap(t1, t2);

	fth[a] = b;

	//cerr << "join " << a << ' ' << b << '\n';

	ll ret = queryNewEdges(t1, t2, a + b);
	joinTreaps(t1, t2);

	//cerr << "a.size = " << size(t1) << '\n';
	//cerr << "b.size = " << size(t2) << '\n';

	return ret;
}

int main()
{
	#ifndef ONLINE_JUDGE
	freopen("data.in", "r", stdin);
	freopen("data.out", "w", stdout);
	#endif

	srand(time(nullptr));

	int i, n, x, y;
	ll nr;
	
	cin >> n;
	for(i = 1; i < n; ++i)
	{
		cin >> x >> y;
		edges.emplace_back(x, y);
	}

	sort(edges.begin(), edges.end(), cmp);

	for(i = 1; i <= n; ++i) tr[i] = new treap(i);

	for(nr = 0, i = 0; i < edges.size(); ++i)
		nr += join(edges[i].first, edges[i].second);

	cout << nr << '\n';

	return 0;
}