/*******************************************************
2) Intuit OA — Count Y-Shaped Triplets in a Tree
Problem:
- Count unordered triplets {a,b,c} in a tree such that their minimal connecting
structure is a "Y" with a junction node.
Idea:
- Fix junction node x.
- Remove x -> tree splits into components of sizes s1, s2, ...
- Triplet is valid iff picks 1 node from 3 different components.
Count at x = sum_{i<j<k} si*sj*sk
- Sum over all x
Time: O(n)
*******************************************************/
#include <bits/stdc++.h> // standard CP header
using namespace std; // use std names directly
int main() { // entry point
ios::sync_with_stdio(false); // fast I/O
cin.tie(nullptr); // fast I/O
int n; // number of nodes
cin >> n; // read n
vector<vector<int>> g(n + 1); // adjacency list (1-indexed)
for (int i = 0; i < n - 1; i++) { // read n-1 edges
int u, v; // endpoints
cin >> u >> v; // input edge
g[u].push_back(v); // add v to u
g[v].push_back(u); // add u to v (tree is undirected)
}
vector<int> parent(n + 1, 0); // parent[u] in rooted tree
vector<int> sub(n + 1, 0); // sub[u] = subtree size of u
parent[1] = -1; // root has no parent
vector<int> order; // to store DFS order
order.reserve(n); // reserve memory to avoid reallocations
stack<int> st; // stack for iterative DFS
st.push(1); // start DFS from node 1
while (!st.empty()) { // while nodes to process exist
int u = st.top(); // take top
st.pop(); // remove it
order.push_back(u); // store visit order
for (int v : g[u]) { // scan neighbors
if (v == parent[u]) continue;// ignore edge back to parent
parent[v] = u; // set parent
st.push(v); // push child
}
}
for (int i = (int)order.size() - 1; i >= 0; i--) { // process in reverse order (postorder)
int u = order[i]; // current node
int sz = 1; // count self
for (int v : g[u]) { // scan neighbors
if (v == parent[u]) continue;// skip parent
sz += sub[v]; // add child subtree size
}
sub[u] = sz; // store subtree size
}
long long total = 0; // final answer
for (int x = 1; x <= n; x++) { // try each node as junction
vector<long long> comps; // component sizes after removing x
comps.reserve(g[x].size()); // reserve approximately degree(x)
for (int v : g[x]) { // for each neighbor of x
if (v == parent[x]) { // neighbor is parent side
comps.push_back((long long)n - sub[x]); // size of "everything outside x's subtree"
} else { // neighbor is child side
comps.push_back(sub[v]); // size of child's subtree
}
}
long long sum1 = 0; // sum of sizes processed so far
long long sum2 = 0; // sum of pair-products so far
long long ans_x = 0; // triplets contributed by junction x
for (long long s : comps) { // for each component size
ans_x += s * sum2; // add triples ending with this component
sum2 += s * sum1; // update pair sums
sum1 += s; // update size sum
}
total += ans_x; // add contribution for x
}
cout << total << "\n"; // print answer
return 0; // done
}