#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

#define ALL(a) (a).begin(),(a).end()

using namespace std;

int main() {
    int N;
    cin >> N;
    vector<long long> L(N), R(N);
    for (int i=0; i<N; i++) cin >> L[i] >> R[i];

    //vector<long long> comp(2*N);
    //for (int i=0; i<N; i++) {
    //    comp[i*2] = L[i];
    //    comp[i*2+1] = R[i];
    //}
    //sort(comp.begin(), comp.end());

    // vector<int> Ridx(N);
    // iota(ALL(Ridx), 0);
    // sort(ALL(Ridx), [&](int i1, int i2){
    //     return R[i1] < R[i2];
    // });
    vector<int> Lidx(N);
    iota(ALL(Lidx), 0);
    sort(ALL(Lidx), [&](int i1, int i2){
        return L[i1] > L[i2];
    });

    // corner: N=2
    if (N == 2) {
        cout << max(0LL, R[0]-L[0]+1) + max(0LL, R[1]-L[1]+1) << endl;
        return 0;
    }

    // Rminをfirstに入れる -> first's maxは変わらない
    // Lで大きい順にみる。ひとたびfirstに入れたら残りは全部firstに入れてよい 
    // いつfirstに入れるか？
    int RminIdx = min_element(ALL(R)) - R.begin();
    long long firstL = L[RminIdx];
    long long firstR = R[RminIdx];

    // corner: Lmaxをfirstに入れる
    long long score1first = -1;
    long long LRmax = -1;
    for (int i=0; i<N; i++) {
        if (Lidx[i] == RminIdx) continue;
        long long Li = L[Lidx[i]];
        long long Ri = R[Lidx[i]];
        if (score1first == -1){
            long long firstMax = firstR;
            long long firstMin = max(firstL, Li);
            score1first = max(0LL, (firstMax-firstMin + 1));
        }
        else {
            long long lr = max(0LL, (Ri - Li + 1));
            LRmax = max(LRmax, lr);
        }
    }
    long long score1 = score1first + LRmax;
    cerr << "#" << score1 << endl;

    // Lmaxをsecondに入れる -> second's minは変わらない
    long long firstMin = firstL;
    long long firstMax = firstR;
    long long secondMin = -1;
    long long secondMax = -1;
    vector<long long> firstScore;
    vector<long long> secondScore;
    bool isFirst = true;
    for (int i=0; i<N; i++) {
        if (Lidx[i] == RminIdx) continue;
        long long Li = L[Lidx[i]];
        long long Ri = R[Lidx[i]];
        if (secondMin == -1) {
            secondMin = Li;
            secondMax = Ri;
        }
        else {
            // firstのminが増える損失 vs secondのmaxが減る損失
            // firstに入れた最大のL vs secondに入れた最小のR

            if (isFirst) {
                // secondに1こも入れない
                long long ss = max(0LL, (secondMax - secondMin) + 1);
                secondScore.push_back(ss);
            }
            isFirst = false;

            secondMax = min(secondMax, Ri);
            // i 個目以降全部入れる
            long long fs = max(0LL, (firstMax - max(firstMin, Li))+1);
            firstScore.push_back(fs);
            // secondにi個目までいれる
            long long ss = max(0LL, (secondMax - secondMin) + 1);
            secondScore.push_back(ss);
        }
    }
    // firstに1個もいれない
    {
    long long fs = max(0LL, (firstMax - firstMin)+1);
    firstScore.push_back(fs);
    }
    long long sss = 0;
    for (int i=0; i<firstScore.size(); i++) {
        sss = max(sss, firstScore[i] + secondScore[i]);
    }
    long long score2 = sss;
    
    cerr << "#" << score2 << endl;
    cout << max(score1,score2) << endl;
    return 0;
}



Measured memory_bytes: 3956