#include <bits/stdc++.h>
using namespace std;
int root[200050];
int vis[200050], dist[200050];
vector<int> g[200050];
vector<int> tree[200050];
void dfs(int v) {
  vis[v] = 1;
  for (int i = 0; i < tree[v].size(); i++) {
    int u = tree[v][i];
    if (!vis[u]) {
      dist[u] = dist[v] + 1;
      dfs(u);
    }
  }
}
void ds_init(int n) {
  for (int i = 0; i < n; i++) root[i] = i;
}
int ds_find(int u) {
  if (root[u] == u) return u;
  return root[u] = ds_find(root[u]);
}
void ds_union(int u, int v) {
  if (ds_find(u) == ds_find(v)) return;
  root[root[v]] = root[u];
}
int main(int argc, char const *argv[]) {
  int n, cor[200050];
  scanf("%d", &n);
  ds_init(n);
  for (int i = 0; i < n; i++) scanf("%d", &cor[i]);
  vector<pair<int, int> > edges(n - 1);
  for (int i = 0, u, v; i < n - 1; i++) {
    scanf("%d %d", &u, &v);
    u--;
    v--;
    edges[i] = {u, v};
    g[u].push_back(v);
    g[v].push_back(u);
    if (cor[u] == cor[v]) ds_union(u, v);
  }
  int cnt = 0;
  map<int, int> mapa;
  for (int i = 0; i < n; i++) {
    if (i == ds_find(i)) {
      mapa[i] = cnt++;
    }
  }
  for (auto edge : edges) {
    int u = edge.first, v = edge.second;
    if (cor[u] != cor[v]) {
      int x = mapa[ds_find(u)];
      int y = mapa[ds_find(v)];
      tree[x].push_back(y);
      tree[y].push_back(x);
    }
  }
  for (int i = 0; i < cnt; i++) vis[i] = 0;
  dist[0] = 0;
  dfs(0);
  int iMaior = 0;
  for (int i = 0; i < cnt; i++)
    if (dist[i] > dist[iMaior]) iMaior = i;
  for (int i = 0; i < cnt; i++) vis[i] = 0;
  dist[iMaior] = 0;
  dfs(iMaior);
  iMaior = 0;
  for (int i = 0; i < cnt; i++) {
    if (dist[i] > dist[iMaior]) iMaior = i;
  }
  printf("%d\n", (dist[iMaior] + 1) / 2);
  return 0;
}
