#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define int ll

#define REP(i,n) for(int i=0;i<n;++i)
#define ALL(name) name.begin(),name.end()
#define SORT(name) sort(name.begin(), name.end())
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
#if 0
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
const int MOD = 1000000007;
#define MAX_N 100010

ll N;
vector<ll> L, R;
vector< pair<ll, ll> > LR;

// 範囲 [l, r] のものを 1 問目、それ以外を 2 問目にした場合の
// 楽しさ
ll GetFun(ll l, ll r) {
    ll l_max[2] = { -LLINF, -LLINF };
    ll r_min[2] = { LLINF, LLINF };
    bool isValid[2] = {};

    for(auto& lr : LR) {
        if(l <= lr.first && lr.second <= r) {
            l_max[0] = max(l_max[0], lr.first);
            r_min[0] = min(r_min[0], lr.second);
            isValid[0] = true;
        }
        else {
            l_max[1] = max(l_max[1], lr.first);
            r_min[1] = min(r_min[1], lr.second);
            isValid[1] = true;
        }
    }

    ll ret1 = r_min[0] - l_max[0] + 1;
    if(!isValid[0] || ret1 < 0) { ret1 = 0; }
    ll ret2 = r_min[1] - l_max[1] + 1;
    if(!isValid[1] || ret2 < 0) { ret2 = 0; }

    return ret1 + ret2;
}

ll fromRight(ll l_min) {
    ll lb = 0, ub = R.size() - 1;
    while(ub - lb > 2000) {
#if 1
        // 1000 分探索
        ll sub = (ub - lb) / 1000;
        ll next_val = -LLINF;
        ll next_ind = -1;
        for(int i = lb; i <= ub; i += sub) {
            ll cand_val = GetFun(l_min, R[i]);
            if(next_val < cand_val) {
                next_val = cand_val;
                next_ind = i;
            }
        }
        lb = max(0LL, next_ind - sub);
        ub = min(static_cast<ll>(R.size()) - 1LL, next_ind + sub);
#else
        ll t1 = (2 * lb + ub) / 3;
        ll t2 = (lb + 2 * ub) / 3;
        ll cand1 = GetFun(l_min, R[t1]);
        ll cand2 = GetFun(l_min, R[t2]);
        if(cand1 < cand2) {
            if(lb == t1) { break; } // もう変化しないくらい範囲が狭くなった
            lb = t1;
        }
        else {
            if(ub == t2) { break; }
            ub = t2;
        }
#endif
    }

    ll ret = -LLINF;
    ll ret_ind = -1;
    for(ll i = lb; i <= ub; ++i) {
        ll cand = GetFun(l_min, R[i]);
        if(ret < cand) {
            ret = cand;
            ret_ind = i;
        }
    }

    // 次に左側を狭める
    lb = 0, ub = L.size() - 1;
    while(ub - lb > 2000) {
        // 1000 分探索
        ll sub = (ub - lb) / 1000;
        ll next_val = -LLINF;
        ll next_ind = -1;
        for(int i = lb; i <= ub; i += sub) {
            if(L[i] > R[ret_ind]) { break; }
            ll cand_val = GetFun(L[i], R[ret_ind]);
            if(next_val < cand_val) {
                next_val = cand_val;
                next_ind = i;
            }
        }
        lb = max(0LL, next_ind - sub);
        ub = min(static_cast<ll>(L.size()) - 1LL, next_ind + sub);
    }
    for(ll i = lb; i <= ub; ++i) {
        ret = max(ret, GetFun(L[i], R[ret_ind]));
    }

    return ret;
}


ll fromLeft(ll r_max) {
    ll lb = 0, ub = L.size() - 1;
    while(ub - lb > 2000) {
        // 1000 分探索
        ll sub = (ub - lb) / 1000;
        ll next_val = -LLINF;
        ll next_ind = -1;
        for(int i = lb; i <= ub; i += sub) {
            ll cand_val = GetFun(L[i], r_max);
            if(next_val < cand_val) {
                next_val = cand_val;
                next_ind = i;
            }
        }
        lb = max(0LL, next_ind - sub);
        ub = min(static_cast<ll>(L.size()) - 1LL, next_ind + sub);
    }

    ll ret = -LLINF;
    ll ret_ind = -1;
    for(ll i = lb; i <= ub; ++i) {
        ll cand = GetFun(L[i], r_max);
        if(ret < cand) {
            ret = cand;
            ret_ind = i;
        }
    }

    lb = 0, ub = R.size() - 1;
    while(ub - lb > 2000) {
        // 1000 分探索
        ll sub = (ub - lb) / 1000;
        ll next_val = -LLINF;
        ll next_ind = -1;
        for(int i = lb; i <= ub; i += sub) {
            if(L[ret_ind] > R[i]) { break; }
            ll cand_val = GetFun(L[ret_ind], R[i]);
            if(next_val < cand_val) {
                next_val = cand_val;
                next_ind = i;
            }
        }
        lb = max(0LL, next_ind - sub);
        ub = min(static_cast<ll>(R.size()) - 1LL, next_ind + sub);
    }
    for(ll i = lb; i <= ub; ++i) {
        ret = max(ret, GetFun(L[ret_ind], R[i]));
    }

    return ret;
}

signed main() {
    cin.tie(0); cout.tie(0);
    ios::sync_with_stdio(false);

    cin >> N;

    ll l_min = LLINF;   // L の中で最小のもの
    ll r_max = -LLINF;  // R の中で最大のもの

    ll ans = -LLINF;

    ll longest_ind = -1;
    ll longest_val = -LLINF;
    REP(i, N) {
        ll l, r;
        cin >> l >> r;
        L.push_back(l);
        R.push_back(r);
        LR.push_back(make_pair(l, r));

        l_min = min(l_min, l);
        r_max = max(r_max, r);

        ans = max(ans, r - l + 1);

        if(longest_val < ans) {
            longest_val = ans;
            longest_ind = i;
        }
    }

    // 1 番長いのとそれ以外のパターン
    ll cand = longest_val;
    ll l_max = -LLINF;
    ll r_min = LLINF;
    REP(i, N) {
        if(i == longest_ind) { continue; }
        l_max = max(l_max, LR[i].first);
        r_min = min(r_min, LR[i].second);
    }
    if(l_max <= r_min) {
        cand += r_min - l_max + 1;
        ans = max(ans, cand);
    }

    SORT(L);
    SORT(R);
    R.erase(unique(R.begin(), R.end()), R.end());
    L.erase(unique(L.begin(), L.end()), L.end());

    ans = max(ans, fromRight(l_min));
    ans = max(ans, fromLeft(r_max));

    printf("%lld\n", ans);

    return 0;
}


Measured memory_bytes: 3804