#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define ordered_set <int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
#define ordered_multiset <int, null_type, less_equal <int>, rb_tree_tag, tree_order_statistics_node_update>
#define int long long
#define double long double
#define pii pair <int, int>
#define tiii tuple <int, int, int>
#define tiiii tuple <int, int, int, int>
#define emb emplace_back
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define iShowSpeed cin.tie(NULL)->sync_with_stdio(false)
#define matrix vector <vector <int>>
#define mat(n, m) vector <vector <int>> (n, vector <int> (m));
const int mod = 1e9 + 7;
const int inf = 1e18;
const matrix II = {{1, 0}, {0, 1}};
const int N = 1e5 + 5;
int n, dis[N], depth[N], prep[N], velo[N], dp[N];
vector <pii> adj[N];
void dfs1(int u, int p){
depth[u] = depth[p] + 1;
for (auto [w, v] : adj[u]) {
if (v == p) continue;
dis[v] = dis[u] + w;
dfs1(v, u);
}
}
struct convexhull {
struct line {
int m, c, idx;
line(int m = 0, int c = 0, int idx = 0) : m(m), c(c), idx(idx) {}
int cal(int x){
return m * x + c;
}
double intersect(line cur){
return (double)((double)(c - cur.c) / (double)(cur.m - m));
}
};
// deque <line> dq;
line hull[N];
int sz = 0;
tuple <int, int, line> update(line cur){
// while (dq.size() >= 2 && cur.intersect(dq[dq.size() - 1]) < cur.intersect(dq[dq.size() - 2])) dq.pop_back();
// dq.emb(cur);
int l = 1, r = sz - 1;
int idx = sz;
while (l <= r) {
int mid = (l + r) / 2;
if (cur.intersect(hull[mid]) <= cur.intersect(hull[mid - 1])) idx = mid, r = mid - 1;
else l = mid + 1;
}
int prevsz = sz;
line prevline = hull[idx];
hull[idx] = cur;
sz = idx + 1;
return make_tuple(idx, prevsz, prevline);
}
int query(int x){
// while (dq.size() >= 2 && dq[0].cal(x) > dq[1].cal(x)) dq.pop_front();
// return dq[0].cal(x);
int l = 0, r = sz - 2;
int idx = sz - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (hull[mid].intersect(hull[mid + 1]) >= x) idx = mid, r = mid - 1;
else l = mid + 1;
}
return hull[idx].cal(x);
}
void remove(int u){
// while (depth[dq.back().idx] > depth[u]) dq.pop_back();
}
void rollback(int idx, int prevsz, line prevline){
hull[idx] = prevline;
sz = prevsz;
}
} cht;
void dfs2(int u, int p){
if (u > 1) dp[u] = dis[u] * velo[u] + prep[u] + cht.query(velo[u]);
auto [idx, prevsz, prevline] = cht.update(convexhull::line(-dis[u], dp[u], u));
for (auto [w, v] : adj[u]) {
if (v == p) continue;
dfs2(v, u);
// cht.remove(u);
}
cht.rollback(idx, prevsz, prevline);
}
void solve(){
cin >> n;
for (int i = 1; i < n; i++) {
int u, v, w; cin >> u >> v >> w;
adj[u].emb(w, v);
adj[v].emb(w, u);
}
for (int i = 2; i <= n; i++) cin >> prep[i] >> velo[i];
dfs1(1, 1);
dfs2(1, 1);
for (int i = 2; i <= n; i++) cout << dp[i] << " ";
}
int32_t main(){
iShowSpeed;
// int q; cin >> q; while (q--)
solve();
}