#include <bits/stdc++.h>
using namespace std;
int mod = 10000007;
long long pwr(long long a, long long b, long long mod) {
  if (b == 0) return 1;
  long long temp = pwr(a, b / 2, mod);
  temp = (temp * temp) % mod;
  if (b & 1) temp = (temp * a) % mod;
  return temp;
}
long long pwr(long long a, long long b) {
  if (b == 0) return 1;
  long long temp = pwr(a, b / 2);
  temp = (temp * temp);
  if (b & 1) temp = (temp * a);
  return temp;
}
bool *isPrime;
void generatePrimeSieve(const int lim) {
  isPrime = (bool *)malloc(lim + 1);
  memset(isPrime, true, lim + 1);
  isPrime[0] = false;
  isPrime[1] = false;
  for (int i = 2; i <= lim; ++i)
    if (isPrime[i])
      for (int j = i + i; j <= lim; j += i) isPrime[j] = false;
}
vector<vector<int> > identityMatrix;
vector<vector<int> > mul(const vector<vector<int> > &a,
                         const vector<vector<int> > &b) {
  int n = a.size();
  vector<vector<int> > ans(n, vector<int>(n));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      for (int k = 0; k < n; ++k) {
        ans[i][j] += ((long long)a[i][k] * b[k][j]) % mod;
        ans[i][j] %= mod;
      }
    }
  }
  return ans;
}
vector<vector<int> > pwr(const vector<vector<int> > &a, long long n) {
  if (n == 0) {
    assert(false);
    return identityMatrix;
  }
  if (n == 1) return a;
  vector<vector<int> > tmp = pwr(a, n / 2);
  tmp = mul(tmp, tmp);
  if (n & 1) tmp = mul(a, tmp);
  return tmp;
}
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long lcm(long long a, long long b) { return (a / gcd(a, b)) * b; }
long long modularInverse(long long a, long long m) { return pwr(a, m - 2, m); }
int n, best = -1;
vector<vector<int> > G(10000);
int tailtable[10000];
int pop[10000];
int sz = 0;
void dfs(int x, int par) {
  int sztemp = sz;
  int indextt, popVal;
  if (sz == 0) {
    indextt = sz;
    popVal = tailtable[sz];
    tailtable[sz++] = pop[x];
  } else if (pop[x] <= tailtable[0]) {
    indextt = 0;
    popVal = tailtable[0];
    tailtable[0] = pop[x];
  } else if (pop[x] > tailtable[sz - 1]) {
    indextt = sz;
    popVal = tailtable[sz];
    tailtable[sz] = pop[x];
    ++sz;
  } else {
    int ub = upper_bound(tailtable, tailtable + sz, pop[x]) - tailtable;
    indextt = ub;
    popVal = tailtable[ub];
    tailtable[ub] = pop[x];
  }
  best = max(best, sz);
  for (int i = 0; i < G[x].size(); ++i) {
    int u = G[x][i];
    if (u == par) continue;
    dfs(u, x);
  }
  sz = sztemp;
  tailtable[indextt] = popVal;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &pop[i]);
  }
  int x, y;
  for (int i = 0; i < n - 1; ++i) {
    scanf("%d %d", &x, &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }
  for (int i = 1; i <= n; ++i) {
    tailtable[0] = -1;
    sz = 0;
    dfs(i, 0);
  }
  cout << best;
}
