#pragma GCC optimize ("O3")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define ll long long
#define ld long double
#define all(a) a.begin(),a.end()
#define ull unsigned long long
#define endl '\n'
#define y1 yaumru
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define iter set< pair<int,int> >::iterator
#define int long long
using namespace std;
using namespace __gnu_pbds;

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

template<class T>
using ordered_multiset=tree<T,null_type,less_equal<T>,rb_tree_tag,tree_order_statistics_node_update>;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rnd1(chrono::steady_clock::now().time_since_epoch().count());

//find_by_order
//order_of_key

const int N=5e5+7;
const int inf=1e18+5;
const int mod=998244353;
const ld eps=1e-9;

pair<int,int>a[N];
set< pair<int,int> >setik1;
set< pair<int,int> >setik2;

int find_ans(vector< pair<int,int> >c,int x2,int y2)
{
    c.pb({inf,inf});
    sort(all(c));
    int n=c.size();
    reverse(all(c));
    c.pb({0,0});
    reverse(all(c));
    int pref[n+2];
    int suf[n+2];
    for (int i=0;i<=n+1;++i){
        pref[i]=inf;
        suf[i]=inf;
    }
    for (int i=1;i<=n;++i){
        pref[i]=min(pref[i-1],c[i].ss);
    }
    for (int i=n;i>=1;--i){
        suf[i]=min(suf[i+1],c[i].ff);
    }
    int ans=max(x2,y2);
    for (int i=n+1;i>=1;--i){
        int f=min(x2,suf[i])+min(pref[i-1],y2);
        ans=max(ans,f);
    }
    return ans;
}

void upd(int& l,int& r,int l1,int r1)
{
    l=max(l,l1);
    r=min(r,r1);
}

int cost(int l,int r)
{
    if (l<=r)return r-l+1;
    return 0;
}

int per(int l,int r,int l1,int r1)
{
    l=max(l,l1);
    r=min(r,r1);
    return cost(l,r);
}

pair<int,int>pref[N];
pair<int,int>suf[N];
int l1=1,r1=inf;
int l2=1,r2=inf;

bool update()
{
    bool cc=false;
    while(true){
        bool f=false;
        iter it=setik1.lower_bound({r1+1,0});
        if (it!=setik1.end()){
            pair<int,int>a=*it;
            setik1.erase({a.ff,a.ss});
            setik2.erase({a.ss,a.ff});
            upd(l2,r2,a.ff,a.ss);
            cc=true;
            f=true;
        }
        if (!f)break;
    }
    while(true){
        bool f=false;
        iter it=setik2.lower_bound({l1,0});
        if (it!=setik2.begin()){
            --it;
            pair<int,int>a=*it;
            swap(a.ff,a.ss);
            setik2.erase({a.ss,a.ff});
            setik1.erase({a.ff,a.ss});
            upd(l2,r2,a.ff,a.ss);
            cc=true;
            f=true;
        }
        if (!f)break;
    }
    while(true){
        bool f=false;
        iter it=setik1.lower_bound({r2+1,0});
        if (it!=setik1.end()){
            pair<int,int>a=*it;
            setik1.erase({a.ff,a.ss});
            setik2.erase({a.ss,a.ff});
            upd(l1,r1,a.ff,a.ss);
            cc=true;
            f=true;
        }
        if (!f)break;
    }
    while(true){
        bool f=false;
        iter it=setik2.lower_bound({l2,0});
        if (it!=setik2.begin()){
            --it;
            pair<int,int>a=*it;
            swap(a.ff,a.ss);
            setik2.erase({a.ss,a.ff});
            setik1.erase({a.ff,a.ss});
            upd(l1,r1,a.ff,a.ss);
            cc=true;
            f=true;
        }
        if (!f)break;
    }
    return cc;
}

main ()
{
    ios;
    int n;
    cin>>n;
    int ans=0;
    for (int i=1;i<=n;++i){
        cin>>a[i].ff>>a[i].ss;
        ans=max(ans,a[i].ss-a[i].ff+1);
    }
    sort(a+1,a+n+1);
    for (int i=1;i<=n;++i){
        setik1.insert({a[i].ff,a[i].ss});
        setik2.insert({a[i].ss,a[i].ff});
    }
    pref[1]={1,inf};
    pref[1]={a[1].ff,a[1].ss};
    suf[n]={a[n].ff,a[n].ss};
    suf[n+1]={1,inf};
    for (int i=2;i<=n;++i){
        pref[i]=pref[i-1];
        upd(pref[i].ff,pref[i].ss,a[i].ff,a[i].ss);
    }
    for (int i=n-1;i>=1;--i){
        suf[i]=suf[i+1];
        upd(suf[i].ff,suf[i].ss,a[i].ff,a[i].ss);
    }
    for (int i=1;i<=n;++i){
       if (i!=n) ans=max(ans,cost(pref[i].ff,pref[i].ss)+cost(suf[i+1].ff,suf[i+1].ss));
    }
    for (int i=1;i<=n;++i){
        int l=pref[i-1].ff;
        int r=pref[i-1].ss;
        upd(l,r,suf[i+1].ff,suf[i+1].ss);
        ans=max(ans,cost(a[i].ff,a[i].ss)+cost(l,r));
    }
    l1=a[1].ff;
    r1=a[1].ss;
    while(update()){
        continue;
    }
    if (r1!=inf && r2!=inf){
        int x=cost(l1,r1);
        int y=cost(l2,r2);
        vector< pair<int,int> >c;
        while(setik1.size()>0){
            pair<int,int>a=(*setik1.begin());
            setik1.erase(setik1.begin());
            c.pb({per(l1,r1,a.ff,a.ss),per(l2,r2,a.ff,a.ss)});
        }
        ans=max(ans,find_ans(c,x,y));
    }
    cout<<ans<<endl;
}

//50 50
//5
//57 17
//64 57
//57 8
//38 86
//4 88


Measured memory_bytes: 26476