#include <bits/stdc++.h>   using namespace std;   template <typename T>   T gcd(T a, T b) {     return !b ? a : gcd(b, a % b);   }   template <typename T>   T lcm(T a, T b) {     return a * (b / gcd(a, b));   }   template <typename T>   T sqr(T a) {     return a * a;   }   template <typename T>   T cube(T a) {     return a * a * a;   }   template <typename T>   inline void smin(T &a, T b) {     a = a < b ? a : b;   }   template <typename T>   inline void smax(T &a, T b) {     a = a > b ? a : b;   }   template <typename T>   void fill(T a[], T n, T b) {     for (int i = 0; i <= n; i++) a[i] = b;   }   int in() {     int n;     scanf( %d , &n);     return n;   }   long long Lin() {     long long n;     scanf( %lld , &n);     return n;   }   double Din() {     double n;     scanf( %lf , &n);     return n;   }   const long long inf = (long long)1e17;   const long long mod = (long long)1e9 + 7;   const int N = 2e5 + 5;   int n, q, a[N];   set<pair<int, pair<int, int> > > s;   int tree[4 * N], prop[4 * N];   void propagate(int pos, int left, int right) {     int mid = (left + right) >> 1;     prop[pos] = 0;     tree[pos * 2] = mid - left + 1;     tree[pos * 2 + 1] = right - mid;     prop[pos * 2] = 1;     prop[pos * 2 + 1] = 1;   }   void update(int pos, int left, int right, int x, int y) {     if (left > y || right < x) return;     if (left >= x && right <= y) {       tree[pos] = right - left + 1;       prop[pos] = 1;       return;     }     if (prop[pos] > 0) propagate(pos, left, right);     int mid = (left + right) >> 1;     update(pos * 2, left, mid, x, y);     update(pos * 2 + 1, mid + 1, right, x, y);     tree[pos] = tree[pos * 2] + tree[pos * 2 + 1];   }   int query(int pos, int left, int right, int x, int y) {     if (left > y || right < x) return 0;     if (left >= x && right <= y) return tree[pos];     if (prop[pos] > 0) propagate(pos, left, right);     int mid = (left + right) >> 1;     int n = query(pos * 2, left, mid, x, y);     int m = query(pos * 2 + 1, mid + 1, right, x, y);     return m + n;   }   int root[N], Rank[N], lp[N], rp[N];   void init(int n) {     for (int i = 1; i <= n; i++) {       root[i] = i, Rank[i] = 1, lp[i] = i, rp[i] = i;     }   }   int Find(int u) { return root[u] == u ? u : root[u] = Find(root[u]); }   void Union(int u, int v) {     u = Find(u), v = Find(v);     if (u != v) {       root[v] = u;       Rank[u] += Rank[v];       rp[u] = rp[v];     }   }   int bs1(int l, int r) {     int ans = -1;     while (l <= r) {       int m = (l + r) >> 1;       if (query(1, 1, n, m, r) != (r - m + 1))         ans = m, l = m + 1;       else         r = m - 1;     }     return ans;   }   int bs2(int l, int r) {     int ans = n + 1;     while (l <= r) {       int m = (l + r) >> 1;       if (query(1, 1, n, l, m) != (m - l + 1))         ans = m, r = m - 1;       else         l = m + 1;     }     return ans;   }   int solve() {     n = in();     for (int i = 1; i <= n; i++) {       a[i] = in();     }     init(n);     int l = 1, cur = 1;     for (int i = 2; i <= n; i++) {       if (a[i] != a[i - 1]) {         s.insert({-cur, {l, i - 1}});         cur = 1, l = i;       } else {         Union(i - 1, i);         cur++;       }     }     s.insert({-cur, {l, n}});     int ans = 0;     while (!s.empty()) {       auto it = s.begin();       int u = (*it).second.first, v = (*it).second.second;       s.erase(it);       if (query(1, 1, n, u, v) != (v - u + 1)) {         ans++;         update(1, 1, n, u, v);         int x = bs1(1, u - 1);         int y = bs2(u + 1, n);         if (x >= 1 && y <= n && a[x] == a[y]) {           Union(x, y);           int par = Find(x);           s.insert({-Rank[par], {lp[par], rp[par]}});         }       }     }     cout << ans <<   n ;     return 0;   }   int main() {     int test = 1, tc = 0;     while (test--) {       solve();     }     return 0;   }