#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef pair<ll, ll> PLL;
#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) \
  for (int i = static_cast<int>(a); i < static_cast<int>(b); ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, ) (__VA_ARGS__)  // NOLINT

// {{{ Lazy Segment Tree
const ll TYPE_MIN = 0;
const ll TYPE_MAX = 1;
const ll TYPE_SUM = 2;
struct LazySegmentTree {
  ll n, init;
  ll type;
  std::vector<ll> node;  // 値配列
  std::vector<ll> lazy;  // 遅延配列
  std::vector<bool> isOverride;  // 遅延配列の取り扱い（false:加算、true:更新）

  LazySegmentTree(ll N, ll init, ll type) : init(init), type(type) {
    std::vector<ll> v(N, init);
    n = 1;
    while (n < v.size())
      n *= 2;
    node.resize(2 * n - 1, init);
    lazy.resize(2 * n - 1, 0);
    isOverride.resize(2 * n - 1, false);
    for (ll i = 0; i < v.size(); i++)
      node[i + n - 1] = v[i];
    for (ll i = n - 2; i >= 0; i--) {
      switch (type) {
        case TYPE_MIN:
          node[i] = std::min(node[i * 2 + 1], node[i * 2 + 2]);
          break;
        case TYPE_MAX:
          node[i] = std::max(node[i * 2 + 1], node[i * 2 + 2]);
          break;
        case TYPE_SUM:
          node[i] = node[i * 2 + 1] + node[i * 2 + 2];
          break;
      }
    }
  }

  // k番目のノードを評価する (k=0から順に呼ぶ）
  void eval(ll k, ll l, ll r) {
    // - 自ノードの値配列に値を伝播
    if (isOverride[k]) {
      node[k] = lazy[k];  // 区間更新
    } else {
      node[k] += lazy[k];  // 区間加算
    }

    // - 子ノードに遅延配列を伝播
    if (r - l > 1) {
      if (isOverride[k]) {
        // 区間更新
        switch (type) {
          case TYPE_SUM:
            lazy[2 * k + 1] = lazy[k] / 2;
            lazy[2 * k + 2] = lazy[k] / 2;
            break;
          case TYPE_MIN:
          case TYPE_MAX:
            lazy[2 * k + 1] = lazy[k];
            lazy[2 * k + 2] = lazy[k];
            break;
        }
        isOverride[2 * k + 1] = true;
        isOverride[2 * k + 2] = true;
      } else {
        // 区間加算
        switch (type) {
          case TYPE_SUM:
            lazy[2 * k + 1] += lazy[k] / 2;
            lazy[2 * k + 2] += lazy[k] / 2;
            break;
          case TYPE_MIN:
          case TYPE_MAX:
            lazy[2 * k + 1] += lazy[k];
            lazy[2 * k + 2] += lazy[k];
            break;
        }
        isOverride[2 * k + 1] = false;
        isOverride[2 * k + 2] = false;
      }
    }

    // - 自ノードの遅延配列を空にする (0を足すという状態にしておく）
    lazy[k] = 0;
    isOverride[k] = false;
  }

  void add(ll a, ll b, ll x, ll k = 0, ll l = 0, ll r = -1) {
    if (r < 0)
      r = n;

    // 範囲外
    if (b <= l || r <= a) {
      eval(k, l, r);
      return;
    }

    // 完全に含む
    if (a <= l && r <= b) {
      // 最小値を計算する場合
      switch (type) {
        case TYPE_MIN:
        case TYPE_MAX:
          lazy[k] += x;
          break;
        case TYPE_SUM:
          lazy[k] += (r -l) * x;
          break;
      }
      isOverride[k] = false;
      eval(k, l, r);
      return;
    }

    // 子ノードに加算して、結果を自ノードに反映する
    eval(k, l, r);
    add(a, b, x, 2 * k + 1, l, (l + r) / 2);
    add(a, b, x, 2 * k + 2, (l + r) / 2, r);
    // node[k] = node[2*k+1] + node[2*k+2]; // 区間和なので+
    switch (type) {
        case TYPE_MIN:
          node[k] = std::min(node[k * 2 + 1], node[k * 2 + 2]);
          break;
        case TYPE_MAX:
          node[k] = std::max(node[k * 2 + 1], node[k * 2 + 2]);
          break;
        case TYPE_SUM:
          node[k] = node[k * 2 + 1] + node[k * 2 + 2];
          break;
    }
  }

  void update(ll a, ll b, ll x, ll k = 0, ll l = 0, ll r = -1) {
    if (r < 0)
      r = n;

    // 遅延評価
    eval(k, l, r);

    // 範囲外
    if (b <= l || r <= a)
      return;

    // 完全に含む
    if (a <= l && r <= b) {
      switch (type) {
        case TYPE_MIN:
        case TYPE_MAX:
          lazy[k] = x;
          break;
        case TYPE_SUM:
          lazy[k] = (r - l) * x;
          break;
      }
      isOverride[k] = true;
      eval(k, l, r);
      return;
    }

    // 子ノードに更新して、結果を自ノードに反映する
    update(a, b, x, 2 * k + 1, l, (l + r) / 2);
    update(a, b, x, 2 * k + 2, (l + r) / 2, r);
    switch (type) {
        case TYPE_MIN:
          node[k] = std::min(node[k*2+1], node[k*2+2]);
          break;
        case TYPE_MAX:
          node[k] = std::max(node[k*2+1], node[k*2+2]);
          break;
        case TYPE_SUM:
          node[k] = node[k*2+1] + node[k*2+2];
          break;
    }
  }

  ll query(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) {
    if (r < 0)
      r = n;
    if (b <= l || r <= a)
      return init;

    eval(k, l, r);
    if (a <= l && r <= b)
      return node[k];
    ll vl = query(a, b, 2*k+1, l, (l+r)/2);
    ll vr = query(a, b, 2*k+2, (l+r)/2, r);
    switch (type) {
      case TYPE_MIN: return std::min(vl, vr);
      case TYPE_MAX: return std::max(vl, vr);
      case TYPE_SUM: return vl + vr;
    }
    return -1;
  }

  static void test() {
    {
      LazySegmentTree st(5, 0, TYPE_SUM);
      rep(i, 0, 5)
        st.update(i, i+1, i+1);
      assert(st.query(0, 5) == 15);
      st.add(1, 4, 10);
      assert(st.query(0, 5) == 45);
      st.update(1, 3, 10);
      assert(st.query(0, 5) == 40);
    }
    {
      LazySegmentTree st(5, 0, TYPE_SUM);
      rep(i, 0, 5)
        st.update(i, i+1, i+1);
      assert(st.query(0, 5) == 15);
      st.update(1, 3, 10);
      assert(st.query(0, 5) == 30);
      st.add(1, 4, 10);
      assert(st.query(0, 5) == 60);
    }
    {
      LazySegmentTree st(5, 100000000, TYPE_MIN);
      rep(i, 0, 5)
        st.update(i, i+1, i+1);
      assert(st.query(0, 5) == 1);
      st.add(0, 1, 5);
      assert(st.query(0, 5) == 2);
      st.update(1, 3, 5);
      assert(st.query(0, 5) == 4);
    }
    {
      LazySegmentTree st(5, 100000000, TYPE_MIN);
      rep(i, 0, 5)
        st.update(i, i+1, i+1);
      assert(st.query(0, 5) == 1);
      st.update(0, 2, 5);
      assert(st.query(0, 5) == 3);
      st.add(2, 3, 5);
      assert(st.query(0, 5) == 4);
    }
  }
};
// }}}

ll N;
vector<ll> a, ans;
vector<vector<ll>> edges;
LazySegmentTree st(300000, 0, TYPE_MAX);
multiset<ll> se;

void dfs(ll cur, ll par) {
  // cur が最後となる場合
  ll x = st.query(0, a[cur]) + 1;
  // cur が最後とならない場合
  ll y = *(se.rbegin());
  ans[cur] = max(x, y);

  // update value
  ll t1 = st.query(a[cur], a[cur]+1);
  st.update(a[cur], a[cur]+1, max(t1, x));
  se.insert(ans[cur]);

  for (auto c : edges[cur]) {
    if (c == par)
      continue;
    dfs(c, cur);
  }

  // restore value
  st.update(a[cur], a[cur]+1, t1);
  auto it = se.find(ans[cur]);
  se.erase(it);
}

signed main() {
  cin >> N;
  se.insert(0);
  a.resize(N);
  ans.resize(N);
  edges.resize(N);
  rep(i, N)
    cin >> a[i];
  rep(i, N-1) {
    ll u, v;
    cin >> u >> v;
    u--; v--;
    edges[u].push_back(v);
    edges[v].push_back(u);
  }
  // a を座標圧縮
  {
    auto b = a;
    sort(begin(b), end(b));
    b.erase(unique(begin(b), end(b)), end(b));
    map<ll, ll> mp;
    ll i = 0;
    for (auto x : b) {
      mp[x] = i++;
    }
    for (auto &x : a) {
      x = mp[x];
    }
  }
  //cout << "a: ";
  //for (auto x : a) {
  //  cout << x << " ";
  //}
  //cout << endl;

  dfs(0, -1);
  for (auto x : ans) {
    cout << x << endl;
  }
  return 0;
}


Measured memory_bytes: 65424