// Arup Guha
// 4/19/2016

// My original solution to 2016 NAIPC Problem I: Tourists - I think it's fast enough, but Kattis said no.
// This is designed better (in my opinion) than the solution I got to pass with parallel arrays and no
// node object.

import java.util.*;
import java.io.*;

public class i2 {

	public static int n;
	public static node[] tree;

	public static void main(String[] args) throws Exception {

		// Read in original input as a graph.
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(stdin.readLine().trim());
		tree = new node[n];
		for (int i=0; i<n; i++)
			tree[i] = new node();
		for (int i=1; i<n; i++) {
			StringTokenizer tok = new StringTokenizer(stdin.readLine());
			int v1 = Integer.parseInt(tok.nextToken())-1;
			int v2 = Integer.parseInt(tok.nextToken())-1;
			tree[v1].kids.add(v2);
			tree[v2].kids.add(v1);
		}

		// Form our tree.
		makeTree(0, -1, 0);
		long res = 0;

		// Now, just loop through all paths, add up and print.
		for (int i=1; i<=n; i++)
			for (int j=2*i; j<=n; j+=i)
				res = res + pathLength(i-1, j-1) + 1;
		System.out.println(res);
	}

	// Returns the length between v1 and v2.
	public static int pathLength(int v1, int v2) {
		int lcaDepth = tree[lca(v1, v2)].depth;
		return tree[v1].depth - lcaDepth + tree[v2].depth - lcaDepth;
	}

	// Returns the lowest common ancestor of v1 and v2 in the tree.
	public static int lca(int v1, int v2) {

		// Make v1 further down than v2.
		if (tree[v1].depth < tree[v2].depth) {
			int tmp = v1;
			v1 = v2;
			v2 = tmp;
		}

		// Move v1 to same level as v2.
		if (tree[v1].depth != tree[v2].depth) v1 = hopUp(v1, tree[v1].depth-tree[v2].depth);

		// Return the LCA of v1, v2 (which are on the same level.
		return lcsrec(v1, v2, tree[v1].ancestors.size()-1);
	}

	public static int lcsrec(int v1, int v2, int shift) {

		// Base case.
		if (v1 == v2) return v1;

		// Go up as far as you can.
		shift = Math.min(shift, tree[v1].ancestors.size()-1);
		while (shift > 0 && tree[v1].ancestors.get(shift) == tree[v2].ancestors.get(shift)) shift--;

		// Solve recursively.
		return lcsrec(tree[v1].ancestors.get(shift), tree[v2].ancestors.get(shift), shift);
	}

	public static int hopUp(int node, int levels) {

		// Find smallest hop by bit.
		int shift = 0;
		int cur = node;

		// Hop until we get to the right place.
		while (levels > 0) {

			while (((1<<shift) & levels) == 0) shift++;

			// Hop up by 2^shift.
			cur = tree[cur].ancestors.get(shift);
			levels -= (1<<shift);
			shift++;
		}

		// Ta da!
		return cur;
	}

	public static void makeTree(int root, int parent, int curDepth) {

		// Set up BFS.
		ArrayDeque<Integer> q = new ArrayDeque<Integer>();
		q.offer(root);
		int[] par = new int[n];
		par[0] = -1;
		tree[root].depth = curDepth;

		// Run BFS.
		while (q.size() > 0) {

			root = q.poll();

			// Handle root - put in depth and fill in binary lifting array.
			if (par[root] != -1) {
				tree[root].ancestors.add(par[root]);
				int ancestor = par[root], i = 1;
				while (i-1 < tree[ancestor].ancestors.size()) {
					tree[root].ancestors.add(tree[ancestor].ancestors.get(i-1));
					ancestor = tree[ancestor].ancestors.get(i-1);
					i++;
				}
			}

			// Remove the parent from the kid list.
			tree[root].kids.remove( (Integer)par[root] );

			// Enqueue the kids.
			for (int i=0; i<tree[root].kids.size(); i++) {
				int next = tree[root].kids.get(i);
				q.offer(next);
				par[next] = root;
				tree[next].depth = tree[root].depth+1;
			}
		}
	}
}

class node {

	public ArrayList<Integer> kids;
	public int depth;
	public ArrayList<Integer> ancestors;

	public node() {
		kids = new ArrayList<Integer>();
		depth = 0;
		ancestors = new ArrayList<Integer>();
	}
}