#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
inline int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}
int Ans = 0, n;
struct node {
  int ls, rs, maxx1, maxx2;
} tree[N * 20];
int tot = 0, root[N];
inline void update(int k) {
  tree[k].maxx1 = max(tree[tree[k].ls].maxx1, tree[tree[k].rs].maxx1);
  tree[k].maxx2 = max(tree[tree[k].ls].maxx2, tree[tree[k].rs].maxx2);
}
inline void update_add(int lef, int rig, int &k, int place, int c, int flag) {
  if (!k) k = (++tot);
  if (lef == rig) {
    if (!flag)
      tree[k].maxx1 = max(tree[k].maxx1, c);
    else
      tree[k].maxx2 = max(tree[k].maxx2, c);
    return;
  }
  int mid = (lef + rig) >> 1;
  if (place <= mid)
    update_add(lef, mid, tree[k].ls, place, c, flag);
  else
    update_add(mid + 1, rig, tree[k].rs, place, c, flag);
  update(k);
}
inline int ask1(int lef, int rig, int l, int r, int k) {
  if (l > r) return 0;
  if (l <= lef && r >= rig) return tree[k].maxx1;
  int ans = 0;
  int mid = (lef + rig) >> 1;
  if (l <= mid) ans = max(ans, ask1(lef, mid, l, r, tree[k].ls));
  if (r > mid) ans = max(ans, ask1(mid + 1, rig, l, r, tree[k].rs));
  return ans;
}
inline int ask2(int lef, int rig, int l, int r, int k) {
  if (l > r) return 0;
  if (l <= lef && r >= rig) return tree[k].maxx2;
  int ans = 0;
  int mid = (lef + rig) >> 1;
  if (l <= mid) ans = max(ans, ask2(lef, mid, l, r, tree[k].ls));
  if (r > mid) ans = max(ans, ask2(mid + 1, rig, l, r, tree[k].rs));
  return ans;
}
inline int Merge(int lef, int rig, int k1, int k2) {
  if (!k1) return k2;
  if (!k2) return k1;
  if (lef == rig) {
    tree[k1].maxx1 = max(tree[k1].maxx1, tree[k2].maxx1);
    tree[k1].maxx2 = max(tree[k1].maxx2, tree[k2].maxx2);
    return k1;
  }
  int mid = (lef + rig) >> 1;
  Ans = max(Ans, tree[tree[k1].ls].maxx1 + tree[tree[k2].rs].maxx2);
  Ans = max(Ans, tree[tree[k2].ls].maxx1 + tree[tree[k1].rs].maxx2);
  tree[k1].ls = Merge(lef, mid, tree[k1].ls, tree[k2].ls);
  tree[k1].rs = Merge(mid + 1, rig, tree[k1].rs, tree[k2].rs);
  update(k1);
  return k1;
}
int a[N], b[N], re[N], len = 0;
inline int ask(int x) { return lower_bound(re + 1, re + len + 1, x) - re; }
struct vode {
  int to, last;
} edge[N * 2];
int s = 0, head[N];
inline void add(int from, int to) {
  edge[++s].to = to;
  edge[s].last = head[from];
  head[from] = s;
}
inline void dfs1(int from, int to) {
  for (int i = head[to]; i; i = edge[i].last) {
    int k = edge[i].to;
    if (k == from) continue;
    dfs1(to, k);
  }
  for (int i = head[to]; i; i = edge[i].last) {
    int k = edge[i].to;
    if (k == from) continue;
    Ans = max(Ans, ask1(1, len, 1, a[to] - 1, root[to]) +
                       ask2(1, len, a[to] + 1, len, root[k]) + 1);
    Ans = max(Ans, ask1(1, len, 1, a[to] - 1, root[k]) +
                       ask2(1, len, a[to] + 1, len, root[to]) + 1);
    root[to] = Merge(1, len, root[to], root[k]);
  }
  int maxx1 = ask1(1, len, 1, a[to] - 1, root[to]) + 1;
  int maxx2 = ask2(1, len, a[to] + 1, len, root[to]) + 1;
  update_add(1, len, root[to], a[to], maxx1, 0);
  update_add(1, len, root[to], a[to], maxx2, 1);
}
int main() {
  n = read();
  for (int i = 1; i <= n; i++) b[i] = a[i] = read();
  sort(b + 1, b + n + 1);
  b[0] = -1;
  for (int i = 1; i <= n; i++)
    if (b[i] != b[i - 1]) re[++len] = b[i];
  for (int i = 1; i <= n; i++) a[i] = ask(a[i]);
  int u, v;
  for (int i = 1; i <= n - 1; i++) {
    u = read();
    v = read();
    add(u, v);
    add(v, u);
  }
  dfs1(0, 1);
  printf("%d\n", Ans);
  return 0;
}
