#include <bits/stdc++.h>   using namespace std;   const int Maxn = 6010;   vector<int> V;   vector<int> G[Maxn];   int a[Maxn];   int dp[Maxn][2];   int n, ans;   int getid(int x) { return lower_bound(V.begin(), V.end(), x) - V.begin() + 1; }   struct Node *null;   struct Node {     Node *ch[2];     int r, v[2];     int sz, u;     int val[2];     int cmp(int x) {       if (a[u] == x) return -1;       return a[u] < x;     }     void push_up() {       if (this == null) return;       sz = ch[0]->sz + ch[1]->sz + 1;       v[0] = max(ch[0]->v[0], ch[1]->v[0]);       v[0] = max(v[0], val[0]);       v[1] = max(ch[0]->v[1], ch[1]->v[1]);       v[1] = max(v[1], val[1]);     }   };   Node *create(int u, int w1, int w2) {     Node *ret = new Node();     ret->r = rand();     ret->ch[0] = ret->ch[1] = null;     ret->u = u;     ret->sz = 1;     ret->val[0] = ret->v[0] = w1;     ret->val[1] = ret->v[1] = w2;     return ret;   }   int getmax(Node *rt, int w, int ty) {     if (rt == null) return 0;     int ret = 0;     if (!ty) {       if (a[rt->u] >= w)         ret = max(ret, getmax(rt->ch[0], w, ty));       else {         ret = max(ret, rt->ch[0]->v[0]);         ret = max(ret, rt->val[0]);         ret = max(ret, getmax(rt->ch[1], w, ty));       }     } else {       if (a[rt->u] <= w)         ret = max(ret, getmax(rt->ch[1], w, ty));       else {         ret = max(ret, rt->ch[1]->v[1]);         ret = max(ret, rt->val[1]);         ret = max(ret, getmax(rt->ch[0], w, ty));       }     }     return ret;   }   void rotate(Node *&o, int d) {     Node *k = o->ch[d ^ 1];     o->ch[d ^ 1] = k->ch[d];     k->ch[d] = o;     o->push_up();     k->push_up();     o = k;   }   void insert(Node *&o, int u, int w1, int w2) {     if (o == null)       o = create(u, w1, w2);     else {       int d = o->cmp(a[u]);       insert(o->ch[d], u, w1, w2);       if (o->ch[d]->r > o->r) rotate(o, d ^ 1);       o->push_up();     }   }   bool find(Node *o, int u, int w1, int w2) {     if (o == null) return false;     int d = o->cmp(a[u]);     if (d == -1) {       o->val[0] = max(o->val[0], w1);       o->val[1] = max(o->val[1], w2);       o->push_up();       return true;     }     int t = find(o->ch[d], u, w1, w2);     if (t) o->push_up();     return t;   }   void merge(Node *rt, Node *&tar) {     if (rt == null) return;     if (!find(tar, rt->u, rt->val[0], rt->val[1]))       insert(tar, rt->u, rt->val[0], rt->val[1]);     if (rt->ch[0] != null) merge(rt->ch[0], tar);     if (rt->ch[1] != null) merge(rt->ch[1], tar);   }   Node *dfs1(int u, int pre) {     Node *ret = null;     pair<int, int> tp[2][2];     int p[2];     for (int i = 0; i < 2; i++)       for (int j = 0; j < 2; j++) tp[i][j] = pair<int, int>(0, 0);     for (int i = 0; i < G[u].size(); i++) {       int v = G[u][i];       if (v == pre) continue;       Node *t = dfs1(v, u);       p[0] = getmax(t, a[u], 0);       p[1] = getmax(t, a[u], 1);       if (p[0] > tp[0][0].first) {         tp[0][1] = tp[0][0];         tp[0][0] = pair<int, int>(p[0], i);       } else if (p[0] > tp[0][1].first)         tp[0][1] = pair<int, int>(p[0], i);       if (p[1] > tp[1][0].first) {         tp[1][1] = tp[1][0];         tp[1][0] = pair<int, int>(p[1], i);       } else if (p[1] > tp[1][1].first)         tp[1][1] = pair<int, int>(p[1], i);       if (ret->sz > t->sz)         merge(t, ret);       else {         merge(ret, t);         ret = t;       }     }     dp[u][0] = tp[0][0].first + 1;     dp[u][1] = tp[1][0].first + 1;     if (tp[0][0].second != tp[1][0].second)       ans = max(ans, tp[0][0].first + tp[1][0].first + 1);     else {       ans = max(ans, tp[0][0].first + tp[1][1].first + 1);       ans = max(ans, tp[0][1].first + tp[1][0].first + 1);     }     if (!find(ret, u, dp[u][0], dp[u][1])) insert(ret, u, dp[u][0], dp[u][1]);     return ret;   }   pair<int, int> tree[Maxn << 2];   void add(int tar, int w1, int w2, int l, int r, int x) {     if (l == r) {       tree[x].first = max(tree[x].first, w1);       tree[x].second = max(tree[x].second, w2);       return;     }     int mid = (l + r) >> 1;     if (tar <= mid)       add(tar, w1, w2, l, mid, x << 1);     else       add(tar, w1, w2, mid + 1, r, x << 1 | 1);     tree[x].first = max(tree[x << 1].first, tree[x << 1 | 1].first);     tree[x].second = max(tree[x << 1].second, tree[x << 1 | 1].second);   }   int query(int L, int R, int l, int r, int x, int ty) {     if (L > R) return 0;     if (L <= l && R >= r) {       return ty ? tree[x].second : tree[x].first;     }     int mid = (l + r) >> 1;     int ret = 0;     if (L <= mid) ret = max(ret, query(L, R, l, mid, x << 1, ty));     if (R > mid) ret = max(ret, query(L, R, mid + 1, r, x << 1 | 1, ty));     return ret;   }   void dfs2(int u, int p) {     ans = max(ans, dp[u][0] + query(a[u] + 1, n, 1, n, 1, 1));     ans = max(ans, dp[u][1] + query(1, a[u] - 1, 1, n, 1, 0));     for (int i = 0; i < G[u].size(); i++) {       int v = G[u][i];       if (v == p) continue;       dfs2(v, u);     }     add(a[u], dp[u][0], dp[u][1], 1, n, 1);   }   int main() {     null = new Node();     null->ch[0] = null->ch[1] = null;     null->sz = null->u = null->v[0] = null->v[1] = 0;     null->val[0] = null->val[1] = 0;     null->r = -1;     scanf( %d , &n);     for (int i = 1; i <= n; i++) {       scanf( %d , a + i);       V.push_back(a[i]);     }     sort(V.begin(), V.end());     V.erase(unique(V.begin(), V.end()), V.end());     for (int i = 1; i <= n; i++) a[i] = getid(a[i]);     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);     }     dfs1(1, 0);     dfs2(1, 0);     printf( %d n , ans);   }