#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = (int)1e5 + 1;
const int M = (int)1e9 + 1;
const ll inf = (ll)1e18;
ll dp[N], s[N], vv[N], dep[N];
vector<pair<int, int>> adj[N];
struct LiChaoTree {
struct Line {
ll m, c;
ll y(ll x) { return m * x + c; }
Line() : m(0), c(inf) {}
Line(ll m, ll c) : m(m), c(c) {}
};
struct Node {
Line L;
Node *l = nullptr, *r = nullptr;
Node() {}
Node(Node *u) { L = u->L, l = u->l, r = u->r; }
};
void insert(Line L, Node *u, int l, int r) {
int mid = l + (r - l) / 2;
bool c1 = L.y(l) < u->L.y(l);
bool c2 = L.y(mid) < u->L.y(mid);
if (c2) swap(L, u->L);
if (l == r) return;
if (c1 != c2) {
if (u->l) u->l = new Node(u->l);
else u->l = new Node;
insert(L, u->l, l, mid);
} else {
if (u->r) u->r = new Node(u->r);
else u->r = new Node;
insert(L, u->r, mid+1, r);
}
}
ll query(Node *u, int l, int r, ll x) {
if (l == r) return u->L.y(x);
int mid = l + (r - l) / 2;
ll ans = u->L.y(x);
if (x <= mid && u->l != nullptr) ans = min(ans, query(u->l, l, mid, x));
if (x > mid && u->r != nullptr) ans = min(ans, query(u->r, mid+1, r, x));
return ans;
}
void insert(ll m, ll c, Node *u) { insert(Line(m, c), u, 0, M); }
ll query(ll x, Node *u) { return min(0LL, query(u, 0, M, x)); }
} T;
vector<LiChaoTree::Node*> root;
void dfs(int u, int p) {
dp[u] = dep[u] * vv[u] + s[u] + T.query(vv[u], root[p]);
root[u] = new LiChaoTree::Node(root[p]);
T.insert(-dep[u], dp[u], root[u]);
for (auto &[w, v] : adj[u]) {
if (v == p) continue;
dep[v] = dep[u] + w;
dfs(v, u);
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int n; cin >> n;
root.resize(n+1);
for (int i = 1; i < n; i++) {
int u, v, w;
cin >> u >> v >> w;
adj[u].emplace_back(w, v), adj[v].emplace_back(w, u);
}
for (int i = 2; i <= n; i++) cin >> s[i] >> vv[i];
root[0] = new LiChaoTree::Node;
dfs(1, 0);
for (int i = 2; i <= n; i++) cout << dp[i] << ' ';
}