点分治
#include <cstdio>
#include <vector>
#include <stack>
#include <algorithm>
const int MAXN = 100005;
struct Node;
struct Edge;
struct Node {
    Edge *e;
    bool solved;
    int size, max;
} N[MAXN];
struct Edge {
    Node *u, *v;
    Edge *next;
    Edge() {}
    Edge(Node *u, Node *v) : u(u), v(v), next(u->e) {}
} _pool[MAXN << 1], *_curr = _pool;
void addEdge(int u, int v) {
    N[u].e = new (_curr++) Edge(&N[u], &N[v]);
    N[v].e = new (_curr++) Edge(&N[v], &N[u]);
}
void dfs(Node *u, Node *fa, std::vector<Node *> &vec) {
    u->size = 1;
    u->max = 0;
    vec.push_back(u);
    for (Edge *e = u->e; e; e = e->next) if (!e->v->solved && e->v != fa) {
        dfs(e->v, u, vec);
        u->size += e->v->size;
        u->max = std::max(u->max, e->v->size);
    }
}
Node *center(Node *s) {
    static std::vector<Node *> vec;
    dfs(s, NULL, vec);
    Node *res = NULL;
    for (int i = 0; i < vec.size(); i++) {
        vec[i]->max = std::max(vec[i]->max, s->size - vec[i]->size);
        if (!res || res->max > vec[i]->max) res = vec[i];
    }
    return res;
}
int calc(Node *u, Node *fa = NULL) {
    int res = 0;
    for (Edge *e = u->e; e; e = e->next) if (e->v != fa && !e->v->solved) {
        res += calc(e->v, u);
        
    }
    
    return res;
}
int solve() {
    static std::stack<Node *> s;
    s.push(&N[1]);
    int ans = 0;
    while (!s.empty()) {
        Node *u = s.top();
        s.pop();
        Node *root = center(u);
        root->solved = true;
        ans += calc(root);
        for (Edge *e = root->e; e; e = e->next) if (!e->v->solved) s.push(e->v);
    }
    return ans;
}
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1, u, v; i < n; i++) {
        scanf("%d %d", &u, &v);
        addEdge(u, v);
    }
    int ans = solve();
    printf("%d\n", ans);
}