#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MASK(x) (1LL << (x))
#define BIT(x, i) (((x) >> (i)) & 1)
#define SZ(x) ((int) (x).size())
#define ALL(a) (a).begin(), (a).end()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(x) cerr << "[" << #x << " = " << (x) << "]" << endl
#define left    __left
#define right   __right
#define prev    __prev
#define fi      first
#define se      second
template <class X, class Y>
    bool maximize(X &x, Y y) {
        if (x < y) return x = y, true;
        else return false;
    }
template <class X, class Y>
    bool minimize(X &x, Y y) {
        if (x > y) return x = y, true;
        else return false;
    }
int numNode;
int timeHLD = 0;
#define MAX_EDGE 200'200
struct Edge {
    int u, v, uniCost, multiCost;
    void input() {
        cin >> u >> v >> uniCost >> multiCost;
    }
} edges[MAX_EDGE + 2];
#define MAX_NODE 200'200
vector <int> adj[MAX_NODE + 2];
int par[MAX_NODE + 2], sz[MAX_NODE + 2], high[MAX_NODE + 2];
int head[MAX_NODE + 2], pos[MAX_NODE + 2];
void dfs(int u) {
    sz[u] = 1;
    for (int v : adj[u]) {
        if (v == par[u]) continue;
        par[v] = u;
        high[v] = high[u] + 1;
        dfs(v);
        sz[u] += sz[v];
    }
}
void hld(int u, int root) {
    head[u] = root;
    pos[u] = ++timeHLD;
//    if (u == 4) {
//            debug("herh");
//    debug(pos[u]);
//        exit(0);
//    }
    int nxt = 0;
    for (int v : adj[u]) {
        if (v == par[u]) continue;
        if (nxt == 0 || sz[v] > sz[nxt]) nxt = v;
    }
    if (!nxt) return;
    hld(nxt, root);
    for (int v : adj[u]) {
        if (v == par[u] || v == nxt) continue;
        hld(v, v);
    }
}
struct FenwickTree {
    int bit[MAX_NODE + 2];
    void update(int x, int v) {
        for (; x <= numNode; x += x & (-x))
            bit[x] += v;
    }
    void updateRange(int l, int r, int v) {
        update(l, v);
        update(r + 1, -v);
    }
    int get(int x) {
        int ans = 0;
        for (; x > 0; x -= x & (-x)) ans += bit[x];
        return ans;
    }
    int cal(int l, int r) {
        if (l > r) return 0;
        return get(r) - get(l - 1);
    }
} fen;
void updatePath(int u, int v) {
    while (head[u] != head[v]) {
        if (high[head[u]] < high[head[v]]) swap(u, v);
        fen.updateRange(pos[head[u]], pos[u], 1);
        u = par[head[u]];
    }
    if (pos[u] > pos[v]) swap(u, v);
    if (pos[u] + 1 <= pos[v]) fen.updateRange(pos[u] + 1, pos[v], 1);
}
int main() {
    ios_base::sync_with_stdio(false);cin.tie(nullptr);
    cin >> numNode;
    FOR(i, 1, numNode - 1) {
        edges[i].input();
        int u = edges[i].u, v = edges[i].v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    timeHLD = 0;
    dfs(1);
    hld(1, 1);
    FOR(u, 1, numNode - 1) updatePath(u, u + 1);
    ll ans = 0;
    FOR(i, 1, numNode - 1) {
        int u = edges[i].u, v = edges[i].v, uni = edges[i].uniCost, multi = edges[i].multiCost;
        if (u != par[v]) swap(u, v);
        // now v is child of u;
        ans += min(1LL * multi, 1LL * uni * fen.get(pos[v]));
    }
    cout << ans;
    return 0;
}
/* Discipline - Calm */
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |