#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18;
const int MAXN = 1e5 + 5;
struct Line {
  long long k, m;
  Line() {}
  Line(long long k, long long m) : k(k), m(m) {}
  long double gety(long double x) {
    long double res = x * (long double)k;
    res += m;
    return res;
  }
};
long double intersect(Line a, Line b) {
  long double res = a.m - b.m;
  res /= (long double)(b.k - a.k);
  return res;
}
struct convex_hull {
  vector<Line> lines;
  vector<long double> points;
  long long get(long long x) {
    int l = 0, r = lines.size();
    while (r - l > 1) {
      int tm = (l + r) / 2;
      if (points[tm] <= x)
        l = tm;
      else
        r = tm;
    }
    return lines[l].gety(x);
  }
  void addline(Line newline) {
    while (lines.size() &&
           newline.gety(points.back()) < lines.back().gety(points.back())) {
      lines.pop_back();
      points.pop_back();
    }
    long double coord;
    if (lines.empty())
      coord = -INF;
    else
      coord = intersect(newline, lines.back());
    points.push_back(coord);
    lines.push_back(newline);
  }
};
int n;
vector<long long> a, b;
vector<int> g[MAXN];
vector<int> euler;
vector<int> fipos, spos;
vector<convex_hull> tree;
vector<vector<pair<int, int>>> mergesortTree;
vector<int> topsort;
vector<long long> dp;
int k;
void dfs(int v, int par) {
  euler.push_back(v);
  fipos[v] = euler.size() - 1;
  for (auto to : g[v]) {
    if (to == par) continue;
    dfs(to, v);
  }
  euler.push_back(v);
  spos[v] = euler.size() - 1;
  topsort.push_back(v);
}
int lson(int v) { return 2 * v + 1; }
int rson(int v) { return 2 * v + 2; }
void build(int v = 0, int tl = 0, int tr = k - 1) {
  if (tl == tr) {
    int vert = euler[tl];
    mergesortTree[v].push_back({b[vert], vert});
    if (g[vert].size() == 1 && vert != 0) {
      tree[v].addline(Line(b[vert], 0));
    }
    return;
  }
  int tm = (tl + tr) / 2;
  build(lson(v), tl, tm);
  build(rson(v), tm + 1, tr);
  merge(mergesortTree[lson(v)].begin(), mergesortTree[lson(v)].end(),
        mergesortTree[rson(v)].begin(), mergesortTree[rson(v)].end(),
        back_inserter(mergesortTree[v]));
}
long long query(int l, int r, long long x, int v = 0, int tl = 0,
                int tr = k - 1) {
  if (tl > r || tr < l) return INF;
  if (tl >= l && tr <= r) {
    if (tree[v].lines.size() == 0) {
      int i = mergesortTree[v].size() - 1;
      int ptr = i;
      while (i >= 0) {
        while (ptr >= 0 &&
               mergesortTree[v][ptr].first == mergesortTree[v][i].first)
          --ptr;
        long long k = mergesortTree[v][i].first;
        long long m = dp[mergesortTree[v][i].second];
        for (int j = i; j > ptr; --j) {
          m = min(m, dp[mergesortTree[v][j].second]);
        }
        tree[v].addline(Line(k, m));
        i = ptr;
      }
    }
    long long curans = tree[v].get(x);
    return curans;
    return 0;
  }
  int tm = (tl + tr) / 2;
  return min(query(l, r, x, lson(v), tl, tm),
             query(l, r, x, rson(v), tm + 1, tr));
}
int main() {
  cin >> n;
  a.resize(n);
  b.resize(n);
  fipos.resize(n);
  spos.resize(n);
  dp.resize(n, INF);
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = 0; i < n; i++) cin >> b[i];
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(0, -1);
  k = euler.size();
  tree.resize(4 * k);
  mergesortTree.resize(4 * k);
  build();
  for (int i = 0; i < n; i++) {
    int vert = topsort[i];
    if (g[vert].size() == 1 && i != n - 1) {
      dp[vert] = 0;
      continue;
    }
    int l = fipos[vert], r = spos[vert];
    long long curans = query(l + 1, r - 1, a[vert]);
    dp[vert] = curans;
  }
  for (int i = 0; i < n; i++) cout << dp[i] << ' ';
  return 0;
}
