#include <bits/stdc++.h>
using namespace std;
ostream& operator<<(std::ostream& ss, tuple<int, int, int>& a) {
  cout << "(" << get<0>(a) << ' ' << get<1>(a) << ' ' << get<2>(a) << ")";
  return ss;
}
const int maxn = 2 * 1e5 + 20;
int a[maxn];
list<tuple<int, int, int> > cont;
int sz = 0;
tuple<int, int, int> tree[maxn];
vector<list<tuple<int, int, int> >::iterator> arr;
tuple<int, int, int> merge(tuple<int, int, int> a, tuple<int, int, int> b) {
  if (get<1>(a) > get<1>(b)) return a;
  if (get<1>(b) > get<1>(a)) return b;
  if (get<2>(a) < get<2>(b)) return a;
  return b;
}
void build(int i, int l, int r) {
  if (l == r) {
    tree[i] = (*arr[l]);
    return;
  }
  build(i * 2, l, (l + r) / 2);
  build(i * 2 + 1, (l + r) / 2 + 1, r);
  tree[i] = merge(tree[i * 2], tree[i * 2 + 1]);
}
void modify(int i, int l, int r, int target, tuple<int, int, int>* content) {
  if (l > r || target < l || target > r) return;
  if (l == r) {
    tree[i] = *content;
    return;
  }
  modify(i * 2, l, (l + r) / 2, target, content);
  modify(i * 2 + 1, (l + r) / 2 + 1, r, target, content);
  tree[i] = merge(tree[i * 2], tree[i * 2 + 1]);
}
struct cmp {
  bool operator()(tuple<int, int, int> a, tuple<int, int, int> b) {
    if (get<1>(a) != get<1>(b)) {
      return get<1>(a) < get<1>(b);
    }
    return get<2>(a) > get<2>(b);
  }
};
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", &a[i]);
  int streak = 1;
  priority_queue<tuple<int, int, int>, vector<tuple<int, int, int> >, cmp> Q;
  for (int i = 0; i < n; i++) {
    if (i != n - 1 && a[i] == a[i + 1]) {
      streak++;
    } else {
      Q.push(tuple<int, int, int>(a[i], streak, sz));
      cont.push_back(tuple<int, int, int>(a[i], streak, sz++));
      arr.push_back(prev(cont.end()));
      streak = 1;
    }
  }
  int sol = 0;
  vector<bool> invalid = vector<bool>(sz, 0);
  while (Q.size() > 0) {
    tuple<int, int, int> current = Q.top();
    Q.pop();
    if (invalid[get<2>(current)]) continue;
    sol++;
    list<tuple<int, int, int> >::iterator it = arr[get<2>(current)];
    bool merged = 0;
    if (it != cont.begin() && next(it) != cont.end()) {
      auto prv = prev(it);
      auto nxt = next(it);
      if (get<0>(*prv) == get<0>(*nxt)) {
        *it = tuple<int, int, int>(get<0>(*prv), get<1>(*prv) + get<1>(*nxt),
                                   get<2>(current));
        invalid[get<2>(*prv)] = 1;
        invalid[get<2>(*nxt)] = 1;
        cont.erase(prv);
        cont.erase(nxt);
        Q.push(*it);
        merged = 1;
      }
    }
    if (!merged) {
      invalid[get<2>(current)] = 1;
      cont.erase(it);
    }
  }
  cout << sol << '\n';
  return 0;
}
