#include <bits/stdc++.h>
using namespace std;
namespace FGF {
int n, m;
const int N = 1e5 + 5, M = N << 1;
long long a[N], b[N], K[N], B[N], cnt, ans[N], num;
vector<int> g[N];
struct tree {
  int l, r, id;
} t[M << 2];
int rt[N];
long long w(int pos, int x) { return K[x] * pos + B[x]; }
void updat(int &ro, int l, int r, int x) {
  if (!ro) ro = ++num;
  if (l == r) {
    if (w(l, x) < w(l, t[ro].id)) t[ro].id = x;
    return;
  }
  if (w((l + r) / 2, x) < w((l + r) / 2, t[ro].id)) swap(x, t[ro].id);
  if (w(l, x) < w(l, t[ro].id))
    updat(t[ro].l, l, (l + r) / 2, x);
  else if (w(r, x) < w(r, t[ro].id))
    updat(t[ro].r, (l + r) / 2 + 1, r, x);
}
int merge(int u, int v, int l, int r) {
  if (!u || !v) return u + v;
  updat(u, l, r, t[v].id);
  t[u].l = merge(t[u].l, t[v].l, l, (l + r) / 2);
  t[u].r = merge(t[u].r, t[v].r, (l + r) / 2 + 1, r);
  return u;
}
long long query(int ro, int l, int r, int x) {
  if (!ro) return 1e18;
  if (l == r) return w(x, t[ro].id);
  return min(w(x, t[ro].id), x <= (l + r) / 2
                                 ? query(t[ro].l, l, (l + r) / 2, x)
                                 : query(t[ro].r, (l + r) / 2 + 1, r, x));
}
void dfs(int u, int f) {
  for (auto v : g[u])
    if (v != f) dfs(v, u), rt[u] = merge(rt[u], rt[v], -N, N);
  ans[u] = query(rt[u], -N, N, a[u]);
  if (ans[u] == 1e18) ans[u] = 0;
  K[++cnt] = b[u], B[cnt] = ans[u];
  updat(rt[u], -N, N, cnt);
}
void work() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
  for (int i = 1; i <= n; i++) scanf("%lld", &b[i]);
  B[0] = 1e18;
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    g[u].push_back(v), g[v].push_back(u);
  }
  dfs(1, 0);
  for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
}
}  // namespace FGF
int main() {
  FGF::work();
  return 0;
}
