#include <algorithm>
#include <chrono>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <ratio>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>

using namespace std;

const int MIN_A = 1;
const int MAX_A = 1e9;

int n;
vector<pair<int, int>> a;

pair<int, int> Combine(pair<int, int> lhs, pair<int, int> rhs)
{
    return make_pair(
        max(lhs.first, rhs.first),
        min(lhs.second, rhs.second));
}

pair<int, int> GetFromSets(
    const multiset<int>& lefts,
    const multiset<int>& rights)
{
    return make_pair(*lefts.rbegin(), *rights.begin());
}

void Solve()
{
    vector<int> b;
    for (auto [l, r] : a) {
        b.push_back(l);
        b.push_back(r);
    }
    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());
    unordered_map<int, int> indexByValue;
    for (int i = 0; i < (int) b.size(); ++i) {
        indexByValue[b[i]] = i;
    }
    const int m = b.size();
    vector<vector<int>> startedByIndex(m);
    vector<vector<int>> finishedByIndex(m);
    for (auto [l, r] : a) {
        startedByIndex[indexByValue[l]].push_back(r);
        finishedByIndex[indexByValue[r]].push_back(l);
    }
    int result = 0;
    {
        multiset<int> secondLefts;
        multiset<int> secondRights;
        for (int i = 0; i < n; ++i) {
            secondLefts.insert(a[i].first);
            secondRights.insert(a[i].second);
        }
        for (int i = 0, j = 0; i < m; ++i) {
            for (auto r : startedByIndex[i]) {
                secondLefts.erase(secondLefts.find(b[i]));
                secondRights.erase(secondRights.find(r));
            }

            if (j < i) {
                j = i;
            }
            while (j < m && finishedByIndex[j].empty()) {
                ++j;
            }
            assert(j < m);

            if (!secondLefts.empty()) {
                auto second = GetFromSets(secondLefts, secondRights);
                if (second.first <= second.second) {
                    result = max(result, b[j] - b[i] + 1 + second.second - second.first + 1);
                }
            }

            for (auto l : finishedByIndex[i]) {
                secondLefts.insert(l);
                secondRights.insert(b[i]);
            }
        }
    }
    {
        auto calculateMinMax = [] (const vector<pair<int, int>>& a) {
            vector<pair<int, int>> result(n);
            result[0] = a[0];
            for (int i = 1; i < n; ++i) {
                result[i] = Combine(result[i - 1], a[i]);
            }
            return result;
        };
        auto leftMinMax = calculateMinMax(a);
        reverse(a.begin(), a.end());
        auto rightMinMax = calculateMinMax(a);
        reverse(a.begin(), a.end());
        reverse(rightMinMax.begin(), rightMinMax.end());
        for (int i = 0; i < n; ++i) {
            pair<int, int> second{MIN_A, MAX_A};
            if (i > 0) {
                second = Combine(second, leftMinMax[i - 1]);
            }
            if (i + 1 < n) {
                second = Combine(second, rightMinMax[i + 1]);
            }
            result = max(result, a[i].second - a[i].first + 1 + max(second.second - second.first + 1, 0));
        }
    }
    cout << result << endl;
}

bool Read()
{
    if (!(cin >> n)) {
        return false;
    }
    a.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i].first >> a[i].second;
    }
    return true;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    while (Read()) {
        Solve();
    }

    return 0;
}


Measured memory_bytes: 37432