#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 1;
bool vis[N];
int n, a, b;
int root;
pair<int, int> eg[N];
struct graph {
  bool vis[N];
  vector<int> adj[N];
} graph;
struct Dsu {
  int par[N];
  int cnt[N];
  int col[N];
} dsu;
int findset(int u) {
  return (dsu.par[u] == u ? u : dsu.par[u] = findset(dsu.par[u]));
}
void unite(int u, int v) {
  u = findset(u);
  v = findset(v);
  if (u == v) {
    return;
  }
  if (dsu.cnt[u] < dsu.cnt[v]) {
    swap(u, v);
  }
  dsu.cnt[u] += dsu.cnt[v];
  dsu.par[v] = u;
}
void input() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> dsu.col[i];
    dsu.cnt[i] = 1;
    dsu.par[i] = i;
  }
  for (int i = 1; i < n; ++i) {
    int u;
    cin >> u;
    int v;
    cin >> v;
    eg[i].first = u;
    eg[i].second = v;
    if (dsu.col[u] == dsu.col[v]) {
      unite(u, v);
    }
  }
}
pair<int, int> dfs(int u, int h) {
  pair<int, int> res = {h, u};
  graph.vis[u] = 1;
  for (int v : graph.adj[u]) {
    if (!graph.vis[v]) {
      res = max(res, dfs(v, h + 1));
    }
  }
  return res;
}
int diameter() {
  pair<int, int> a = dfs(root, 0);
  memset(graph.vis, 0, sizeof graph.vis);
  pair<int, int> b = dfs(a.second, 0);
  return b.first;
}
void solve() {
  for (int i = 1; i < n; ++i) {
    int setu = findset(eg[i].first);
    int setv = findset(eg[i].second);
    graph.adj[setu].push_back(setv);
    graph.adj[setv].push_back(setu);
    root = setu;
  }
  cout << (diameter() + 1 >> 1) << "\n";
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  input();
  solve();
}
