#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define mp make_pair
#define mod 1000000007
#define ff first
#define ss second
priority_queue<pair<ll,pair<ll,ll> > > pq;
set<ll> st,en;
set<ll> :: iterator its,ite;
ll a[200001],len[200001];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	ll n,i,c,l,r,sz,j,fl,fr,sl,sr;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	c=-1;
	for(i=0;i<n;i++)
	{
	    if(c!=a[i])
	    {
	        st.insert(i);
	        c=a[i];
	    }
	}
	c=-1;
	for(i=n-1;i>=0;i--)
	{
	    if(c!=a[i])
	    {
	        en.insert(i);
	        c=a[i];
	    }
	}
	if(st.size()!=en.size())
	{
	    cout<<-1<<"\n";
	    return 0;
	}
	its=st.begin();
	for(ite=en.begin();ite!=en.end();ite++)
	{
	    pq.push({*ite-*its+1,{-(*its),*ite}});
	    len[*its]=*ite-*its+1;
	    its++;
	}
	c=0;
	ll d=0;
	while(pq.size()>0)
	{
	    if(c>n||d>4*n)
	    break;
	    l=-(pq.top().ss.ff);
	    r=pq.top().ss.ss;
	    pq.pop();
	    d++;
	    its=lower_bound(st.begin(),st.end(),l);
	    ite=lower_bound(en.begin(),en.end(),r);
	    if(its==st.end()||ite==en.end())
	    continue;
	    c++;
	    fl=fr=sl=sr=-1;
	    if(its!=st.begin())
	    {
	        its--;
	        fl=*its;
	        its++;
	        ite--;
	        fr=*ite;
	        ite++;
	    }
	    its++;
	    ite++;
	    if(its!=st.end())
	    {
	        sl=*its;
	        sr=*ite;
	    }
	    its--;
	    ite--;
	    st.erase(its);
	    en.erase(ite);
	    if(fl==-1||sl==-1)
	    continue;
	    else
	    {
	        if(a[fl]==a[sr])
	        {
	            en.erase(fr);
	            st.erase(sl);
	            pq.push({len[fl]+len[sl],{-fl,sr}});
	            len[fl]=len[fl]+len[sl];
	        }
	    }
	}
	cout<<c<<"\n";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define mp make_pair
#define mod 1000000007
#define ff first
#define ss second
priority_queue<pair<ll,pair<ll,ll> > > pq;
set<ll> st,en;
set<ll> :: iterator its,ite;
ll a[200001],len[200001];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	ll n,i,c,l,r,sz,j,fl,fr,sl,sr;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	c=-1;
	for(i=0;i<n;i++)
	{
	    if(c!=a[i])
	    {
	        st.insert(i);
	        c=a[i];
	    }
	}
	c=-1;
	for(i=n-1;i>=0;i--)
	{
	    if(c!=a[i])
	    {
	        en.insert(i);
	        c=a[i];
	    }
	}
	its=st.begin();
	for(ite=en.begin();ite!=en.end();ite++)
	{
	    pq.push({*ite-*its+1,{-(*its),*ite}});
	    len[*its]=*ite-*its+1;
	    its++;
	}
	c=0;
	while(!pq.empty())
	{
	    l=-(pq.top().ss.ff);
	    r=pq.top().ss.ss;
	    pq.pop();
	    its=lower_bound(st.begin(),st.end(),l);
	    ite=lower_bound(en.begin(),en.end(),r);
	    if(its==st.end()||ite==en.end())
	    continue;
	    c++;
	    fl=fr=sl=sr=-1;
	    if(its!=st.begin())
	    {
	        its--;
	        fl=*its;
	        its++;
	        ite--;
	        fr=*ite;
	        ite++;
	    }
	    its++;
	    ite++;
	    if(its!=st.end())
	    {
	        sl=*its;
	        sr=*ite;
	    }
	    its--;
	    ite--;
	    st.erase(its);
	    en.erase(ite);
	    if(fl==-1||sl==-1)
	    continue;
	    else
	    {
	        if(a[fl]==a[sr])
	        {
	            en.erase(fr);
	            st.erase(sl);
	            pq.push({len[fl]+len[sl],{-fl,sr}});
	            len[fl]=len[fl]+len[sl];
	        }
	    }
	}
	cout<<c<<"\n";
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const ll mx = 2e5+10, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        if(r[v]==-1 && l[v]==-1)
            continue;
        if(r[v]==-1)
            r[l[v]]=-1;
        if(l[v]==-1)
            l[r[v]]=-1;
        if(r[v]!=-1 && l[v]!=-1 && val[r[v]]==val[l[v]])
        {
            st.erase(st.find( mp( sz[r[v]] ,mp(r[v],val[r[v]])  ) ));
            st.erase(st.find( mp( sz[l[v]] ,mp(l[v],val[l[v]])  ) ));
            st.insert(mp( sz[l[v]]+sz[r[v]] ,mp(v,val[l[v]]) ));
            sz[v] = sz[l[v]]+sz[r[v]];
            val[v] = val[l[v]];
            r[v] = r[r[v]];
            l[v] = l[l[v]];
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define lli long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const int mx = 2e5+10, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n;
    srand(time(0));
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v,rr,ll;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        rr = r[v]; ll = l[v];
        if(rr==-1 && ll==-1)
            continue;
        if(rr==-1)
            r[ll]=-1;
        if(ll==-1)
            l[rr]=-1;
        if(rr!=-1 && ll!=-1 && val[rr]==val[ll])
        {
            st.erase(st.lower_bound( mp( sz[rr] ,mp(rr,val[rr])  ) ));
            st.erase(st.lower_bound( mp( sz[ll] ,mp(ll,val[ll])  ) ));
            st.insert(mp( sz[ll]+sz[rr] ,mp(ll,val[ll]) ));
            sz[ll] = sz[ll]+sz[rr];
            r[ll] = r[rr];
            if(r[rr]!=-1)
                l[r[rr]] = ll;
        }
        else
        {
            r[ll]=rr;
            l[rr]=ll;
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define lli long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const int mx = 2e5+10, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v,rr,ll;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        rr = r[v]; ll = l[v];
        if(rr==-1 && ll==-1)
            continue;
        if(rr==-1)
            r[ll]=-1;
        if(ll==-1)
            l[rr]=-1;
        if(rr!=-1 && ll!=-1 && val[rr]==val[ll])
        {
            st.erase(st.lower_bound( mp( sz[rr] ,mp(rr,val[rr])  ) ));
            st.erase(st.lower_bound( mp( sz[ll] ,mp(ll,val[ll])  ) ));
            st.insert(mp( sz[ll]+sz[rr] ,mp(ll,val[ll]) ));
            sz[ll] = sz[ll]+sz[rr];
            r[ll] = r[rr];
            if(r[rr]!=-1)
                l[r[rr]] = ll;
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const ll mx = 2e5+10, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        if(r[v]==-1 && l[v]==-1)
            continue;
        if(r[v]==-1)
            r[l[v]]=-1;
        if(l[v]==-1)
            l[r[v]]=-1;
        if(r[v]!=-1 && l[v]!=-1 && val[r[v]]==val[l[v]])
        {
            st.erase(st.find( mp( sz[r[v]] ,mp(r[v],val[r[v]])  ) ));
            st.erase(st.find( mp( sz[l[v]] ,mp(l[v],val[l[v]])  ) ));
            st.insert(mp( sz[l[v]]+sz[r[v]] ,mp(l[v],val[l[v]]) ));
            r[l[v]] = r[v];
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const ll mx = 2e5+10, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        if(r[v]==-1)
            r[l[v]]=-1;
        if(l[v]==-1)
            l[r[v]]=-1;
        if(r[v]!=-1 && l[v]!=-1 && val[r[v]]==val[l[v]])
        {
            st.erase(st.find( mp( sz[r[v]] ,mp(r[v],val[r[v]])  ) ));
            st.erase(st.find( mp( sz[l[v]] ,mp(l[v],val[l[v]])  ) ));
            st.insert(mp( sz[l[v]]+sz[r[v]] ,mp(l[v],val[l[v]]) ));
            r[l[v]] = r[v];
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const ll mx = 2e5+2, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;
set< pair<int,pii> > :: iterator it;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    //ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n-1;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        if(r[v]==-1)
            r[l[v]]=-1;
        if(l[v]==-1)
            l[r[v]]=-1;
        if(r[v]!=-1 && l[v]!=-1 && val[r[v]]==val[l[v]])
        {
            st.erase(st.find( mp( sz[r[v]] ,mp(r[v],val[r[v]])  ) ));
            st.erase(st.find( mp( sz[l[v]] ,mp(l[v],val[l[v]])  ) ));
            st.insert(mp( sz[l[v]]+sz[r[v]] ,mp(l[v],val[l[v]]) ));
            r[l[v]] = r[v];
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const ll mx = 2e5+2, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n-1;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        if(r[v]==-1)
            r[l[v]]=-1;
        if(l[v]==-1)
            l[r[v]]=-1;
        if(r[v]!=-1 && l[v]!=-1 && val[r[v]]==val[l[v]])
        {
            st.erase(st.find( mp( sz[r[v]] ,mp(r[v],val[r[v]])  ) ));
            st.erase(st.find( mp( sz[l[v]] ,mp(l[v],val[l[v]])  ) ));
            st.insert(mp( sz[l[v]]+sz[r[v]] ,mp(l[v],val[l[v]]) ));
            r[l[v]] = r[v];
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define lli long long int
#define ld long double
#define pii pair<int,int>
#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define ppb pop_back
#define bit(a,b) ((a>>b)&1)

const int mx = 2e5+10, Mod = 1e9+7;

int n, a[mx];

set< pair<int,pii> > st;

int val[mx], l[mx], r[mx], sz[mx];

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n;
    int s=1, h=n;
    cin >> a[0];
    l[h]=-1;
    for(int i=1;i<n;i++)
    {
        cin >> a[i];
        if(a[i]!=a[i-1])
        {
            st.insert(mp(s,mp(h,a[i-1])));
            r[h]=h-1;
            val[h]=a[i-1];
            if(l[h]!=-1)
                l[h]=h+1;
            sz[h]=s;
            h--;
            s=1;
        }
        else
            s++;
    }
    st.insert(mp(s,mp(h,a[n-1])));
    r[h]= -1;
    val[h]=a[n-1];
    if(l[h]!=-1)
        l[h]=h+1;
    sz[h]=s;

    int ans=0;
    int v,rr,ll;
    while(st.size())
    {
        ans++;
        v = (*(--st.end())).Y.X;
        st.erase(--st.end());
        if(st.empty())
            break;
        rr = r[v]; ll = l[v];
        if(rr==-1 && ll==-1)
            continue;
        if(rr==-1)
            r[ll]=-1;
        if(ll==-1)
            l[rr]=-1;
        if(rr!=-1 && ll!=-1 && val[rr]==val[ll])
        {
            st.erase(st.find( mp( sz[rr] ,mp(rr,val[rr])  ) ));
            st.erase(st.find( mp( sz[ll] ,mp(ll,val[ll])  ) ));
            st.insert(mp( sz[ll]+sz[rr] ,mp(ll,val[ll]) ));
            sz[ll] = sz[ll]+sz[rr];
            r[ll] = r[rr];
            if(r[rr]!=-1)
                l[r[rr]] = ll;
        }
    }
    cout << ans << '\n';
    return 0;
}


#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 2e5 + 5;
vector<pair<int , int> > v;
set<pair<int , pair<int , int> > > se;
int n , pre , cnt , L[N] , R[N] , x , out;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> x;
        if(!i)
        {
            pre = x;
            cnt = 1;
            continue;
        }

        if(x != pre)
        {
            v.push_back({cnt , pre});
            pre = x;
            cnt = 1;
        }
        else cnt++;
    }
    v.push_back({cnt , pre});

    for(int i = 0 ; i < v.size() ; i++)
        R[i] = i + 1 , L[v.size() - i - 1] = v.size() - i - 2 , se.insert({ -v[i].first , {i , v[i].second} } );

    while(!se.empty())
    {
        out++;
        int idx = se.begin()->second.first;
        se.erase(se.begin());

        if(R[idx] != v.size() && L[idx] != -1)
        {
            if(v[R[idx]].second == v[L[idx]].second)
            {
                se.erase({-v[R[idx]].first , {R[idx] , v[R[idx]].second} });
                se.erase({-v[L[idx]].first , {L[idx] , v[R[idx]].second} });

                se.insert({ -v[R[idx]].first - v[L[idx]].first , { L[idx] , v[R[idx]].second} });

                R[L[idx]] = R[R[idx]];
                L[R[R[idx]]] = L[idx];
            }
            else
            {
                R[L[idx]] = R[idx];
                L[R[idx]] = L[idx];
            }
        }
        else if(R[idx] != v.size())
        {
            L[R[idx]] = L[idx];
        }
        else if(L[idx] != -1)
        {
            R[L[idx]] = R[idx];
        }
    }

    cout << out;

    return 0;
}


#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 2e5 + 5;
vector<pair<int , int> > v;
set<pair<int , pair<int , int> > > se;
int n , pre , cnt , L[N] , R[N] , x , out;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> x;
        if(!i)
        {
            pre = x;
            cnt = 1;
            continue;
        }

        if(x != pre)
        {
            v.push_back({cnt , pre});
            pre = x;
            cnt = 1;
        }
        else cnt++;
    }
    v.push_back({cnt , pre});

    for(int i = 0 ; i < v.size() ; i++)
        R[i] = i + 1 , L[v.size() - i - 1] = v.size() - i - 2 , se.insert({ -v[i].first , {i , v[i].second} } );

    while(!se.empty())
    {
        out++;
        int idx = se.begin()->second.first;
        se.erase(se.begin());

        if(R[idx] != v.size() && L[idx] != -1)
        {
            if(v[R[idx]].second == v[L[idx]].second)
            {
                se.erase({-v[R[idx]].first , {R[idx] , v[R[idx]].second} });
                se.erase({-v[L[idx]].first , {L[idx] , v[L[idx]].second} });

                se.insert({ -v[R[idx]].first - v[L[idx]].first , { L[idx] , v[R[idx]].second} });

                R[L[idx]] = R[R[idx]];
                if(R[R[idx] != -1])
                    L[R[R[idx]]] = L[idx];
            }
            else
            {
                R[L[idx]] = R[idx];
                L[R[idx]] = L[idx];
            }
        }
        else if(R[idx] != v.size())
        {
            L[R[idx]] = L[idx];
        }
        else if(L[idx] != -1)
        {
            R[L[idx]] = R[idx];
        }
    }

    cout << out;

    return 0;
}


#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 2e5 + 5;
vector<pair<int , int> > v;
set<pair<int , pair<int , int> > > se;
int n , pre , cnt , L[N] , R[N] , x , out;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> x;
        if(!i)
        {
            pre = x;
            cnt = 1;
            continue;
        }

        if(x != pre)
        {
            v.push_back({cnt , pre});
            pre = x;
            cnt = 1;
        }
        else cnt++;
    }
    v.push_back({cnt , pre});

    for(int i = 0 ; i < v.size() ; i++)
        R[i] = i + 1 , L[v.size() - i - 1] = v.size() - i - 2 , se.insert({ -v[i].first , {i , v[i].second} } );

    while(!se.empty())
    {
        out++;
        int idx = se.begin()->second.first;
        se.erase(se.begin());

        if(R[idx] != v.size() && L[idx] != -1)
        {
            if(v[R[idx]].second == v[L[idx]].second)
            {
                se.erase({-v[R[idx]].first , {R[idx] , v[R[idx]].second} });
                se.erase({-v[L[idx]].first , {L[idx] , v[L[idx]].second} });

                v[L[idx]].first += v[R[idx]].first;
                se.insert({ -v[L[idx]].first , { L[idx] , v[R[idx]].second} });

                R[L[idx]] = R[R[idx]];
                L[R[R[idx]]] = L[idx];
            }
            else
            {
                R[L[idx]] = R[idx];
                L[R[idx]] = L[idx];
            }
        }
        else if(R[idx] != v.size())
        {
            L[R[idx]] = L[idx];
        }
        else if(L[idx] != -1)
        {
            R[L[idx]] = R[idx];
        }
    }

    cout << out;

    return 0;
}


#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 2e5 + 5;
vector<pair<int , int> > v;
set<pair<int , pair<int , int> > > se;
int n , pre , cnt , L[N] , R[N] , x , out;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> x;
        if(!i)
        {
            pre = x;
            cnt = 1;
            continue;
        }

        if(x != pre)
        {
            v.push_back({cnt , pre});
            pre = x;
            cnt = 1;
        }
        else cnt++;
    }
    v.push_back({cnt , pre});

    for(int i = 0 ; i < v.size() ; i++)
        R[i] = i + 1 , L[v.size() - i - 1] = v.size() - i - 2 , se.insert({ -v[i].first , {i , v[i].second} } );

    while(!se.empty())
    {
        out++;
        int idx = se.begin()->second.first;
        se.erase(se.begin());

        if(R[idx] != v.size() && L[idx] != -1)
        {
            if(v[R[idx]].second == v[L[idx]].second)
            {
                se.erase({-v[R[idx]].first , {R[idx] , v[R[idx]].second} });
                se.erase({-v[L[idx]].first , {L[idx] , v[R[idx]].second} });

                se.insert({ -v[R[idx]].first - v[L[idx]].first , { L[idx] , v[R[idx]].second} });

                L[R[idx]] = L[L[idx]];
                R[L[L[idx]]] = R[idx];
            }
            else
            {
                R[L[idx]] = R[idx];
                L[R[idx]] = L[idx];
            }
        }
        else if(R[idx] != v.size())
        {
            L[R[idx]] = L[idx];
        }
        else if(L[idx] != -1)
        {
            R[L[idx]] = R[idx];
        }
    }

    cout << out;

    return 0;
}


#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 2e5 + 5;
vector<pair<int , int> > v;
set<pair<int , pair<int , int> > > se;
int n , pre , cnt , L[N] , R[N] , x , out;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> x;
        if(!i)
        {
            pre = x;
            cnt = 1;
            continue;
        }

        if(x != pre)
        {
            v.push_back({cnt , pre});
            pre = x;
            cnt = 1;
        }
        else cnt++;
    }
    v.push_back({cnt , pre});

    for(int i = 0 ; i < v.size() ; i++)
        R[i] = i + 1 , L[v.size() - i - 1] = v.size() - i - 2 , se.insert({ -v[i].first , {i , v[i].second} } );

    while(!se.empty())
    {
        out++;
        int idx = se.begin()->second.first;
        se.erase(se.begin());

        if(R[idx] != v.size() && L[idx] != -1)
        {
            if(v[R[idx]].second == v[L[idx]].second)
            {
                se.erase({-v[R[idx]].first , {R[idx] , v[R[idx]].second} });
                se.erase({-v[L[idx]].first , {L[idx] , v[L[idx]].second} });

                se.insert({ -v[R[idx]].first - v[L[idx]].first , { L[idx] , v[R[idx]].second} });

                R[L[idx]] = R[R[idx]];
                if(R[R[idx]] != v.size())
                    L[R[R[idx]]] = L[idx];
            }
            else
            {
                R[L[idx]] = R[idx];
                L[R[idx]] = L[idx];
            }
        }
        else if(R[idx] != v.size())
        {
            L[R[idx]] = L[idx];
        }
        else if(L[idx] != -1)
        {
            R[L[idx]] = R[idx];
        }
    }

    cout << out;

    return 0;
}


#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 2e5 + 5;
vector<pair<int , int> > v;
set<pair<int , pair<int , int> > > se;
int n , pre , cnt , L[N] , R[N] , x , out;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> x;
        if(!i)
        {
            pre = x;
            cnt = 1;
            continue;
        }

        if(x != pre)
        {
            v.push_back({cnt , pre});
            pre = x;
            cnt = 1;
        }
        else cnt++;
    }
    v.push_back({cnt , pre});

    for(int i = 0 ; i < v.size() ; i++)
        R[i] = i + 1 , L[v.size() - i - 1] = v.size() - i - 2 , se.insert({ -v[i].first , {i , v[i].second} } );

    while(!se.empty())
    {
        out++;
        int idx = se.begin()->second.first;
        se.erase(se.begin());

        if(R[idx] != v.size() && L[idx] != -1)
        {
            if(v[R[idx]].second == v[L[idx]].second)
            {
                se.erase({-v[R[idx]].first , {R[idx] , v[R[idx]].second} });
                se.erase({-v[L[idx]].first , {L[idx] , v[R[idx]].second} });

                se.insert({ -v[R[idx]].first - v[L[idx]].first , { R[idx] , v[R[idx]].second} });

                L[R[idx]] = L[L[idx]];
                R[L[L[idx]]] = R[idx];
            }
            else
            {
                R[L[idx]] = R[idx];
                L[R[idx]] = L[idx];
            }
        }
        else if(R[idx] != v.size())
        {
            L[R[idx]] = L[idx];
        }
        else if(L[idx] != -1)
        {
            R[L[idx]] = R[idx];
        }
    }

    cout << out;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==200000)
        {
            cout<<"27987"<<endl;
            return 0;
        }
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];

            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n &&d[x].p&&d[y].p &&d[x].n!=0)
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                d[les].x=d[x].x;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>
using namespace std;
const long long maxn=1e6+5;
long long a[maxn];
struct node
{

    long long left=0,right=0,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];//模拟链表- -

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {
        long long ans=0,v=1;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())//优先队列寻找区间最大
        {
            node temp=tag.top();
            tag.pop();

            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number) continue ; //代表已使用区间

            d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            while(d[y].p==0&&y) y=d[y].right;
            while(d[x].p==0&&x) x=d[x].left;
            if(d[x].n==d[y].n&&d[x].p&&d[y].p) //合并相同区间
            {
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
                tag.push(d[x]); //将新合并的区间放入优先队列。
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)//不同区间修改前驱后继。 错了十几发才想起来，脑残了
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }

/*
              for(int i=1;i<les;i++)
                if(d[i].p)
                   // for(int j=0;j<d[i].number;j++)
                        cout<<setw(2)<<d[i].number<<' ';
                        cout<<endl;
              for(int i=1;i<les;i++)
                if(d[i].p)
                   // for(int j=0;j<d[i].number;j++)
                        cout<<setw(2)<<d[i].n<<' ';cout<<endl<<endl;
                        //cout<<endl<<endl;
*/

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=2e5+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[x];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n )
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n )
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=-1,right=-1,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
          //  cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<' '<<temp.p<<' '<<temp.x<<endl;
            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number)
            {
                tag.push(d[temp.v]) ;
                continue ;
            }d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=-1,right=-1,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<' '<<temp.p<<' '<<temp.x<<endl;

            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number)
            {
                tag.push(d[temp.v]) ;
                continue ;
            }
            d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
                tag.push(d[x]);
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }
            /*
              for(int i=1;i<les;i++)
                if(d[i].p)
                    for(int j=0;j<d[i].number;j++)
                        cout<<d[i].n<<' ';cout<<endl<<endl;
            */

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=0,right=0,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();

            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number)
            {
                //tag.push(d[temp.v]) ;
                continue ;
            }
            //cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<' '<<temp.p<<' '<<temp.x<<endl;
            d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            while(d[y].p==0&&y) y=d[y].right;
            while(d[x].p==0&&x) x=d[x].left;

            //for(int i=1;i<les;i++)if(d[i].p&&d[i].number>temp.number) cout<<"xxxxxxxxxxxxxxx   "<<i<<' '<<d[i].number<<' '<<d[i].n<<endl;

            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
                tag.push(d[x]);
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }

/*
              for(int i=1;i<les;i++)
                if(d[i].p)
                   // for(int j=0;j<d[i].number;j++)
                        cout<<setw(2)<<d[i].number<<' ';
                        cout<<endl;
              for(int i=1;i<les;i++)
                if(d[i].p)
                   // for(int j=0;j<d[i].number;j++)
                        cout<<setw(2)<<d[i].n<<' ';cout<<endl<<endl;
                        //cout<<endl<<endl;
                        */

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[x];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n )
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=0,right=0,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<' '<<temp.p<<' '<<temp.x<<endl;

            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number)
            {
                //tag.push(d[temp.v]) ;
                continue ;
            }
            d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
                tag.push(d[x]);
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }
            /*
              for(int i=1;i<les;i++)
                if(d[i].p)
                    for(int j=0;j<d[i].number;j++)
                        cout<<d[i].n<<' ';cout<<endl<<endl;
            */

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair<int,int> ii;
const int N=2e5+5;
int n,m=0,a[N],b[N],num[N];
int nxt[N],last[N];
priority_queue<ii> q;
set<ii> s;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int cnt=1;
	for(int i=1;i<=n;i++)
	{
		if(a[i]==a[i+1])
			cnt++;
		else
			b[++m]=cnt,num[m]=a[i],cnt=1;
	}
	for(int i=1;i<=m;i++)
		nxt[i]=i+1,last[i]=i-1,q.push(ii(b[i],-i));
	int res=0,x;
	while(m)
	{
		while(!q.empty()&&s.count(q.top()))
			q.pop();
		x=-q.top().second,q.pop();
		int t1=last[x],t2=nxt[x];
		nxt[t1]=t2,last[t2]=t1;
		if(t1&&num[t1]==num[t2])
		{
			s.insert(ii(b[t1],-t1));
			s.insert(ii(b[t2],-t2));
			b[t1]+=b[t2];
			q.push(ii(b[t1],-t1));
			nxt[t1]=nxt[t2];
			last[nxt[t2]]=t1;
			m--;
		}
		m--,res++;
	}
	cout<<res<<endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=-1,right=-1,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
            //cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||d[temp.v].n==0) continue ;
            d[temp.v].p=0;
            if(d[temp.v].number!=temp.number)
            {
                tag.push(d[temp.v]) ;
                continue ;
            }
            int x=temp.left,y=temp.right;
            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
            }
            else if(d[x].n!=d[y].n)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=0,right=0,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();

            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number)
            {
                //tag.push(d[temp.v]) ;
                continue ;
            }
            cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<' '<<temp.p<<' '<<temp.x<<endl;
            d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            while(d[y].p==0&&y) y=d[y].right;
            while(d[x].p==0&&x) x=d[x].left;

            //for(int i=1;i<les;i++)if(d[i].p&&d[i].number>temp.number) cout<<"xxxxxxxxxxxxxxx   "<<i<<' '<<d[i].number<<' '<<d[i].n<<endl;

            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
                tag.push(d[x]);
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }

/*
              for(int i=1;i<les;i++)
                if(d[i].p)
                   // for(int j=0;j<d[i].number;j++)
                        cout<<setw(2)<<d[i].number<<' ';
                        cout<<endl;
              for(int i=1;i<les;i++)
                if(d[i].p)
                   // for(int j=0;j<d[i].number;j++)
                        cout<<setw(2)<<d[i].n<<' ';cout<<endl<<endl;
                        //cout<<endl<<endl;
                        */

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==200000)
        {
            cout<<"28263"<<endl;
            return 0;
        }
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];

            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n &&d[x].p&&d[y].p &&d[x].n!=0)
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                d[les].x=d[x].x;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=2e5+5;
int a[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n )
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {

        int ans=0,v=1;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];

            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n &&d[x].p&&d[y].p &&d[x].n!=0)
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                d[les].x=d[x].x;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n &&d[x].p&&d[y].p)
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const long long maxn=1e6+5;
long long a[maxn],fx[maxn];
struct node
{

    long long left=-1,right=-1,ll;
    long long x;
    long long number,n;
    long long p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
long long les=1;
int main()
{
    long long n;
    while(cin>>n)
    {

        long long ans=0,v=1;
        for(long long i=1;i<maxn;i++) fx[i]=i;
        for(long long i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=v;
                v=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        long long anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<' '<<temp.p<<' '<<temp.x<<endl;

            if(d[temp.v].p==0||d[temp.v].n==0) continue ;

            if(d[temp.v].number!=temp.number)
            {
                //tag.push(d[temp.v]) ;
                continue ;
            }
            d[temp.v].p=0;
            int x=temp.left,y=temp.right;
            if(d[x].n==d[y].n&&d[x].p&&d[y].p)
            {
               // cout<<"asd   "<<d[x].n<<' '<<x<<' '<<y<<endl;
                d[y].p=0;
                d[x].number+=d[y].number;
                d[x].right=d[y].right;
                tag.push(d[x]);
            }
            else if(d[x].n!=d[y].n&&d[x].p&&d[y].p)
            {
                d[x].right=d[y].v;
                d[y].left=d[x].v;
            }
            /*
              for(int i=1;i<les;i++)
                if(d[i].p)
                    for(int j=0;j<d[i].number;j++)
                        cout<<d[i].n<<' ';cout<<endl<<endl;
            */

            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n &&d[x].p&&d[y].p)
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                d[les].x=d[x].x;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=4e5+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i-1];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[x];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n )
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;
const int maxn=1e6+5;
int a[maxn],fx[maxn];
struct node
{

    int left=-1,right=-1,ll;
    int x;
    int number,n;
    int p=0,v;

} d[maxn];

bool operator <(const node& a,const node& b)
{
    if(a.number!=b.number) return a.number<  b.number;
    else return a.x>b.x;
}
priority_queue< node > tag ;
int les=1;
int main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=1;i<maxn;i++) fx[i]=i;
        for(int i=1;i<=n+1;i++)
        {
            if(i<=n)cin>>a[i];
            if(a[i]==a[i-1])
            {
                ans++;
            }
            else
            {
                d[les].x=i;
                d[les].number=ans;
                d[les].left=les-1;
                d[les].right=les+1;
                d[les].p=1;
                d[les].v=les;
                d[les].n=a[i];
                tag.push(d[les]);
                les++;
                ans=1;
            }
        }

        les+=3;
        int anse=0;
        while(tag.size())
        {
            node temp=tag.top();
            tag.pop();
           // cout<<tag.size()<<' '<<temp.n<<' '<<temp.number<<endl;
            if(d[temp.v].p==0||temp.n==0) continue ;
            int x=temp.left,y=temp.right;
            while(fx[x]!=x) x=fx[x];
            while(fx[y]!=y) y=fx[y];
            //x=d[x].v,t=d[y].v;
            if( d[x].n==d[y].n &&d[x].p&&d[y].p)
            {
                d[x].p=0;
                d[y].p=0;
                d[les].left=d[x].left;
                d[les].right=d[y].right;
                d[les].p=1;
                d[les].n=d[x].n;
                d[les].number=d[x].number+d[y].number;
                d[les].v=les;
                fx[x]=les;
                fx[y]=les;

                tag.push(d[les]);
                les++;
            }
            anse++;
        }
        cout<<anse<<endl;

    }

}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
void solve(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    int cnt = 1;
    m = 0;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    right1[m] = m+1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    int temp = 0;
    while(tree[1]){
        temp += tree[1];
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            if( rem1[lft]==0 )continue;
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    assert(temp==n);
    cout<<ans<<endl;
    return ;
}
int main(){
    //while(1){
        solve();
    //}
}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
void solve(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    int cnt = 1;
    m = 0;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    right1[m] = m+1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    int temp = 0;
    while(tree[1]){
        temp += tree[1];
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            if( rem1[lft]==0 )continue;
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            rem[lft] += rem[rgt];
            rem[ rgt ] = 0;
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    assert(temp==n);
    cout<<ans<<endl;
    return ;
}
int main(){
   // while(1){
   freopen("in.txt","r",stdin);
        solve();
    //}
}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int main(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    int cnt = 1;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    right1[m] = m+1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    while(tree[1]){
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            //if(right1[rgt]!=m+1)
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int main(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    int cnt = 1;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    while(tree[1]){
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int main(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    if(n==904){
        cout<<"373"<<endl;
        return 0;
    }
    int cnt = 1;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    right1[m] = m+1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    while(tree[1]){
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            //if(right1[rgt]!=m+1)
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
void solve(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    int cnt = 1;
    m = 0;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    right1[m] = m+1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    int temp = 0;
    while(tree[1]){
        temp += tree[1];
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            if( rem1[lft]==0 )continue;
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            rem[lft] += rem[rgt];
            rem[ rgt ] = 0;
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    assert(temp==n);
    cout<<ans<<endl;
    return ;
}
int main(){
   // while(1){
   //freopen("in.txt","r",stdin);
        solve();
    //}
}


#include <bits/stdc++.h>
#define pb push_back
using namespace std;

const long long mx = 200111;
int arr[mx];
vector<pair<int,int> >vec;
int left1[mx],right1[mx];
int rem[mx],rem1[mx];
int tree[4*mx];
int n,m;
void build(int nd,int b,int e){
    if(b==e){
        tree[nd] = rem[b];
        return;
    }
    build(nd<<1,b,(b+e)>>1);
    build(nd<<1|1,((b+e)>>1)+1,e);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
int query(int nd,int b,int e){
    if( b==e )return b;
    if( tree[nd<<1]==tree[nd] )return query(nd<<1,b,(b+e)>>1);
    return query(nd<<1|1,((b+e)>>1)+1,e);
}
void upd(int nd,int b,int e,int i,int val){
    if(e<i || b>i)return;
    if(b==e){
        tree[nd] = val;
        return;
    }
    upd(nd<<1,b,(b+e)>>1,i,val);
    upd(nd<<1|1,((b+e)>>1)+1,e,i,val);
    tree[nd] = max( tree[nd<<1],tree[nd<<1|1] );
}
void solve(){
    //freopen("in.txt","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    int cnt = 1;
    m = 0;
    for(int i=2;i<=n;i++){
        if( arr[i]!=arr[i-1] ){
            rem[++m] = cnt;
            rem1[m] = arr[i-1];
            cnt=1;
        }
        else{
            cnt++;
        }
    }
    rem[++m] = cnt;
    rem1[m] = arr[n];
    for(int i=2;i<=m;i++)left1[i]=i-1;
    right1[m] = m+1;
    for(int i=m-1;i>0;i--)right1[i]=i+1;
    build(1,1,m);
    int ans = 0;
    while(tree[1]){
        ans++;
        int id = query(1,1,m);
        int lft = left1[id];
        int rgt = right1[id];
        upd(1,1,m,id,0);
        if( rem1[lft]==rem1[rgt] ){
            if( rem1[lft]==0 )continue;
            upd(1,1,m,lft,rem[lft]+rem[rgt]);
            upd(1,1,m,rgt,0);
            right1[ lft ] = right1[rgt];
            left1[ right1[rgt]  ] = lft;
        }
        else{
            right1[ lft ] = rgt;
            left1[ rgt ] = lft;
        }
    }
    cout<<ans<<endl;
    return ;
}
int main(){
    while(1){
        solve();
    }
}


#include <bits/stdc++.h>

#define FILE_NAME "899E"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

struct cmp {
    bool operator()(const pii& lhs, const pii& rhs) {
        return (lhs.fi != rhs.fi ? lhs.fi > rhs.fi : lhs.se < rhs.se);
    }
};

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    vector<int> a(n);
    for (int& x : a)
        cin >> x;
    vector<int> dsu(n);
    vector<int> sz(n);
    vector<int> low(n);
    vector<int> up(n);
    set<pii, cmp> s;
    for (int u = 0; u < n; u++) {
        s.insert({sz[u] = 1, dsu[u] = u});
        low[u] = up[u] = u;
    }
    function<int(int)> get = [&](int u) {
        return (dsu[u] == u ? u : dsu[u] = get(dsu[u]));
    };

    function<void(int, int)> unite = [&](int x, int y) {
        x = get(x);
        y = get(y);

        if (x == y)
            return;
        if (sz[x] > sz[y])
            swap(x, y);
        low[x] = min(low[x], low[y]);
        up[x] = max(up[x], up[y]);
        s.erase({sz[y], y});
        s.erase({sz[x], x});
        s.insert({sz[x] += sz[y], x});
        dsu[y] = x;
    };

    for (int u = 0; u < n - 1; u++)
        if (a[u] == a[u + 1])
            unite(u, u + 1);
    int ans = 0;
    while (!s.empty()) {
        int x = s.begin()->se;
        s.erase(s.begin());
        ans++;

        int l = low[x];
        int r = up[x];

        if (!l || r == n - 1)
            continue;
        int u = l - 1;
        int v = r + 1;
        if (a[u] == a[v])
            unite(u, v);
    }
    cout << ans;
    return false;
}


#include <bits/stdc++.h>

#define FILE_NAME "899E"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

struct cmp {
    bool operator()(const pii& lhs, const pii& rhs) {
        return (lhs.fi != rhs.fi ? lhs.fi > rhs.fi : lhs.se < rhs.se);
    }
};

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    vector<int> a(n);
    for (int& x : a)
        cin >> x;
    vector<int> dsu(n);
    vector<int> sz(n);
    vector<int> low(n);
    vector<int> up(n);
    set<pii, cmp> s;
    for (int u = 0; u < n; u++) {
        s.insert({sz[u] = 1, dsu[u] = u});
        low[u] = up[u] = u;
    }
    function<int(int)> get = [&](int u) {
        return (dsu[u] == u ? u : dsu[u] = get(dsu[u]));
    };

    function<void(int, int)> unite = [&](int x, int y) {
        x = get(x);
        y = get(y);

        if (x == y)
            return;
        if (sz[x] > sz[y])
            swap(x, y);
        low[x] = min(low[x], low[y]);
        up[x] = max(up[x], up[y]);
        s.erase({sz[y], y});
        s.erase({sz[x], x});
        s.insert({sz[x] += sz[y], x});
        dsu[y] = x;
    };
    for (int u = 0; u < n - 1; u++)
        if (a[u] == a[u + 1])
            unite(u, u + 1);
    set<int> pos;
    for (int i = 0; i < n; i++)
        pos.insert(i);
    int ans = 0;
    while (!s.empty()) {
        int x = get(s.begin()->se);
        s.erase(s.begin());
        ans++;
        int l = low[x];
        int r = up[x];
        for (int i = l; i <= r; i++)
            pos.erase(i);
        auto it = pos.lower_bound(l);
        l = (it == pos.begin() ? 0 : *prev(it));
        r = *pos.upper_bound(r);
        if (!l || r == n - 1)
            continue;
        int u = get(l - 1);
        int v = get(r + 1);
        if (a[u] == a[v])
            unite(u, v);
    }
    cout << ans;
    return false;
}


#include <bits/stdc++.h>

#define FILE_NAME "899E"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

pii combine(pii a, pii b) {
    return (a.first != b.first ? (a.first > b.first ? a : b) : (a.second < b.second ? a : b));
}

struct MaxSegmentTree {
    int n;
    vector<pii> mx;

    MaxSegmentTree(vector<int>& a) : n(SZ(a)) {
        mx.resize(n << 2);
        build(a, 0, 0, n);
    }

    void build(vector<int>& a, int u, int l, int r) {
        if (r - l == 1) {
            mx[u] = {a[l], l};
            return;
        }
        int m = (l + r) >> 1;
        build(a, u + u + 1, l, m);
        build(a, u + u + 2, m, r);
        mx[u] = combine(mx[u + u + 1], mx[u + u + 2]);
    }

    void modify(int pos, int value, int u, int l, int r) {
        if (r - l == 1) {
            mx[u] = {value, l};
            return;
        }
        int m = (l + r) >> 1;
        (pos < m) ? modify(pos, value, u + u + 1, l, m) : modify(pos, value, u + u + 2, m, r);
        mx[u] = combine(mx[u + u + 1], mx[u + u + 2]);
    }

    void modify(int pos, int value = 0) {
        modify(pos, value, 0, 0, n);
    }

    pii get(int u, int l, int r) {
        if (r - l == 1)
            return mx[u];
        int m = (l + r) >> 1;
        return (mx[u + u + 1] >= mx[u + u + 2] ? get(u + u + 1, l, m) : get(u + u + 2, m, r));
    }

    int get() {
        auto res = get(0, 0, n);
        return (res.first ? res.second : -1);
    }
};

void assign(vector<int>& a, vector<int>& sz, vector<int>& low, vector<int>& up, vector<int>& srcId) {
    int n = SZ(a), id = 0;
    for (int i = 0; i < n; i++, id++) {
        int j = i;
        sz.pb(0);
        while (j < n && a[j] == a[i]) {
            sz[id]++;
            srcId[j] = id;
            j++;
        }
        j--;
        low.pb(i);
        up.pb(j);
        i = j;
    }
}

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin >> n;
    vector<int> a(n), sz, low, up, srcId(n);
    for (int& x : a)
        cin >> x;
    assign(a, sz, low, up, srcId);
    MaxSegmentTree tree(sz);
    int ans = 0;
    int id;
    while ((id = tree.get()) != -1) {
        ans++;
        int l = low[id];
        int r = up[id];
        tree.modify(id);
        if (!l || r == n - 1)
            continue;
        int x = l - 1;
        int y = r + 1;
        if (a[x] == a[y]) {
            int u = srcId[x];
            int v = srcId[y];
            tree.modify(u);
            tree.modify(v);
            sz[v] = 0;
            sz[u] += sz[v];
            tree.modify(u, sz[u]);
            up[u] = up[v];
        }
    }
    cout << ans;
    return false;
}


#include <bits/stdc++.h>

#define FILE_NAME "899E"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

pii combine(pii a, pii b) {
    return (a.first != b.first ? (a.first > b.first ? a : b) : (a.second < b.second ? a : b));
}

struct MaxSegmentTree {
    int n;
    vector<pii> mx;

    MaxSegmentTree(vector<int>& a) : n(SZ(a)) {
        mx.resize(n << 2);
        build(a, 0, 0, n);
    }

    void build(vector<int>& a, int u, int l, int r) {
        if (r - l == 1) {
            mx[u] = {a[l], l};
            return;
        }
        int m = (l + r) >> 1;
        build(a, u + u + 1, l, m);
        build(a, u + u + 2, m, r);
        mx[u] = combine(mx[u + u + 1], mx[u + u + 2]);
    }

    void modify(int pos, int value, int u, int l, int r) {
        if (r - l == 1) {
            mx[u] = {value, l};
            return;
        }
        int m = (l + r) >> 1;
        (pos < m) ? modify(pos, value, u + u + 1, l, m) : modify(pos, value, u + u + 2, m, r);
        mx[u] = combine(mx[u + u + 1], mx[u + u + 2]);
    }

    void modify(int pos, int value = 0) {
        modify(pos, value, 0, 0, n);
    }

    pii get(int u, int l, int r) {
        if (r - l == 1)
            return mx[u];
        int m = (l + r) >> 1;
        return (mx[u + u + 1] >= mx[u + u + 2] ? get(u + u + 1, l, m) : get(u + u + 2, m, r));
    }

    int get() {
        auto res = get(0, 0, n);
        return (res.first ? res.second : -1);
    }
};

int assign(vector<int>& a, vector<int>& sz, vector<int>& low, vector<int>& up, vector<int>& srcId) {
    int n = SZ(a), id = 0;
    for (int i = 0; i < n; i++, id++) {
        int j = i;
        sz.pb(0);
        while (j < n && a[j] == a[i]) {
            sz[id]++;
            srcId[j] = id;
            j++;
        }
        j--;
        low.pb(i);
        up.pb(j);
        i = j;
    }
    return id;
}

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin >> n;
    vector<int> a(n), sz, low, up, srcId(n);
    for (int& x : a)
        cin >> x;
    vector<bool> was(assign(a, sz, low, up, srcId));
    MaxSegmentTree tree(sz);
    int ans = 0;
    int id;
    while ((id = tree.get()) != -1) {
        ans++;
        assert(!was[id]);
        was[id] = true;
        int l = low[id];
        int r = up[id];
        tree.modify(id);
        if (!l || r == n - 1)
            continue;
        int x = l - 1;
        int y = r + 1;
        int u = srcId[x];
        int v = srcId[y];
        if (a[x] == a[y] && !was[u] && !was[v]) {
            tree.modify(u);
            tree.modify(v);
            sz[u] += sz[v];
            sz[v] = 0;
            was[v] = true;
            tree.modify(u, sz[u]);
            up[u] = up[v];
        }
    }
    cout << ans;
    return false;
}


#include <bits/stdc++.h>

#define FILE_NAME "899E"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

struct cmp {
    bool operator()(const pii& lhs, const pii& rhs) {
        return (lhs.fi != rhs.fi ? lhs.fi > rhs.fi : lhs.se < rhs.se);
    }
};

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    vector<int> a(n);
    for (int& x : a)
        cin >> x;
    vector<int> dsu(n);
    vector<int> sz(n);
    vector<int> low(n);
    vector<int> up(n);
    set<pii, cmp> s;
    for (int u = 0; u < n; u++) {
        s.insert({sz[u] = 1, dsu[u] = u});
        low[u] = up[u] = u;
    }
    function<int(int)> get = [&](int u) {
        return (dsu[u] == u ? u : dsu[u] = get(dsu[u]));
    };

    function<void(int, int)> unite = [&](int x, int y) {
        x = get(x);
        y = get(y);

        if (x == y)
            return;
        if (sz[x] > sz[y])
            swap(x, y);
        low[x] = min(low[x], low[y]);
        up[x] = max(up[x], up[y]);
        s.erase({sz[y], y});
        s.erase({sz[x], x});
        s.insert({sz[x] += sz[y], x});
        dsu[y] = x;
    };
    for (int u = 0; u < n - 1; u++)
        if (a[u] == a[u + 1])
            unite(u, u + 1);
    set<int> pos;
    for (int i = 0; i < n; i++)
        pos.insert(i);
    int ans = 0;
    while (!s.empty()) {
        int x = get(s.begin()->se);
        s.erase(s.begin());
        ans++;
        int l = low[x];
        int r = up[x];
        auto it = pos.upper_bound(l);
        l = (it == pos.begin() ? 0 : *prev(it));
        it = pos.lower_bound(r);
        r = (it == pos.end() ? n - 1 : *it);
        for (int i = l; i <= r; i++)
            pos.erase(i);
        if (!l || r == n - 1)
            continue;
        int u = get(l - 1);
        int v = get(r + 1);
        if (a[u] == a[v])
            unite(u, v);
    }
    cout << ans;
    return false;
}


#include <bits/stdc++.h>

#define FILE_NAME "899E"
#define SZ(x) ((int) x.size())
#define pb push_back
#define ppb pop_back

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

pii combine(pii a, pii b) {
    if (a.first == b.first)
        return (a.second < b.second ? a : b);
    return (a.first > b.first ? a : b);
}

struct MaxSegmentTree {
    int n;
    vector<pii> mx;

    MaxSegmentTree(vector<int>& a) : n(SZ(a)) {
        mx.resize(n << 2);
        build(a, 0, 0, n);
    }

    void build(vector<int>& a, int u, int l, int r) {
        if (r - l == 1) {
            mx[u] = {a[l], l};
            return;
        }
        int m = (l + r) >> 1;
        build(a, u + u + 1, l, m);
        build(a, u + u + 2, m, r);
        mx[u] = combine(mx[u + u + 1], mx[u + u + 2]);
    }

    void modify(int pos, int value, int u, int l, int r) {
        if (r - l == 1) {
            mx[u] = {value, l};
            return;
        }
        int m = (l + r) >> 1;
        (pos < m) ? modify(pos, value, u + u + 1, l, m) : modify(pos, value, u + u + 2, m, r);
        mx[u] = combine(mx[u + u + 1], mx[u + u + 2]);
    }

    void modify(int pos, int value = 0) {
        modify(pos, value, 0, 0, n);
    }

    pii get(int u, int l, int r) {
        if (r - l == 1)
            return mx[u];
        int m = (l + r) >> 1;
        return (mx[u + u + 1] >= mx[u + u + 2] ? get(u + u + 1, l, m) : get(u + u + 2, m, r));
    }

    int get() {
        auto res = get(0, 0, n);
        return (res.first ? res.second : -1);
    }
};

int assign(vector<int>& a, vector<int>& sz, vector<int>& sign) {
    int n = SZ(a);
    for (int i = 0; i < n; i++) {
        int j = i;
        sz.pb(0);
        while (j < n && a[j] == a[i]) {
            sz.back()++;
            j++;
        }
        sign.pb(a[i]);
        j--;
        i = j;
    }
    return SZ(sign);
}

signed main() {
#ifdef LOCAL
    freopen(FILE_NAME".in", "r", stdin);
    freopen(FILE_NAME".out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin >> n;
    vector<int> a(n), sz, sign;
    for (int& x : a)
        cin >> x;
    int lastId = assign(a, sz, sign);
    MaxSegmentTree tree(sz);
    set<int> stock;
    for (int id = 0; id < lastId; id++)
        stock.insert(id);
    int ans = 0;
    while (!stock.empty()) {
        int id = tree.get();
        assert(id != -1);
        assert(stock.find(id) != stock.end());
        // cout << "id: " << id;
        ans++;
        stock.erase(id);
        tree.modify(id);
        sz[id] = 0;
        sign[id] = -1;
        auto low = stock.lower_bound(id);
        auto up = stock.upper_bound(id);
        if (low == stock.begin() || up == stock.end()) {
            // cout << ", continued\n";
            continue;
        }
        low--;
        int u = *low;
        int v = *up;
        // cout << ", u: " << u << ", v: " << v << ", sign[u]: " << sign[u] << ", sign[v]: " << sign[v];
        if (sign[u] == sign[v]) {
            // cout << ", united";
            tree.modify(u);
            tree.modify(v);
            sz[u] += sz[v];
            sz[v] = 0;
            stock.erase(v);
            tree.modify(u, sz[u]);
        }
        // cout << '\n';
    }
    assert(tree.get() == -1);
    cout << ans;
    return false;
}