#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <functional>
#include <utility>
#include <tuple>
#include <cctype>
#include <bitset>
#include <complex>
#include <cmath>
#include <array>
#include <numeric>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3fLL
//#define mod 998244353
#define MOD 1000000007
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pint;
typedef pair<ll,ll> pll;
typedef tuple<int,int,int> tint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<pint> vpint;
typedef vector<tint> vtint;
int dx[8]={0,0,-1,1,1,1,-1,-1};
int dy[8]={-1,1,0,0,1,-1,1,-1};
const int SIZE=100050;
//↑templete
struct SegmentTreeMin {
	private:
		int n;
		vector<int> node;

	public:
    SegmentTreeMin(vector<int> v) {
        int sz = v.size();
        n = 1; while(n < sz) n *= 2;
        node.resize(2*n-1, INF);
        for(int i=0; i<sz; i++) node[i+n-1] = v[i];
        for(int i=n-2; i>=0; i--) node[i] = min(node[2*i+1], node[2*i+2]);
    }
	void update(int x, int val) {
		x += (n - 1);
		node[x] = val;
		while(x > 0) {
			x = (x - 1) / 2;
			node[x] = min(node[2*x+1], node[2*x+2]);
		}
	}
	int getmin(int a, int b, int k=0, int l=0, int r=-1) {
		if(r < 0) r = n;
		if(r <= a || b <= l) return INF;
		if(a <= l && r <= b) return node[k];
		int vl = getmin(a, b, 2*k+1, l, (l+r)/2);
		int vr = getmin(a, b, 2*k+2, (l+r)/2, r);
		return min(vl, vr);
	}
};
struct SegmentTreeMax {
	private:
		int n;
		vector<int> node;

	public:
    SegmentTreeMax(vector<int> v) {
        int sz = v.size();
        n = 1; while(n < sz) n *= 2;
        node.resize(2*n-1, 0);
        for(int i=0; i<sz; i++) node[i+n-1] = v[i];
        for(int i=n-2; i>=0; i--) node[i] = max(node[2*i+1], node[2*i+2]);
    }
	void update(int x, int val) {
		x += (n - 1);
		node[x] = val;
		while(x > 0) {
			x = (x - 1) / 2;
			node[x] = max(node[2*x+1], node[2*x+2]);
		}
	}
	int getmax(int a, int b, int k=0, int l=0, int r=-1) {
		if(r < 0) r = n;
		if(r <= a || b <= l) return 0;
		if(a <= l && r <= b) return node[k];
		int vl = getmax(a, b, 2*k+1, l, (l+r)/2);
		int vr = getmax(a, b, 2*k+2, (l+r)/2, r);
		return max(vl, vr);
	}
};
int main() {
	int N;
	cin>>N;
	vpint A;

	for(int i=0;i<N;i++){
		int l, r;
		cin>>l>>r;
		r++;
		A.eb(l, -r);
	}
	sort(A.begin(), A.end());

	vint L, R;
	for(pint p:A){
		L.pb(p.first);
		R.pb(-1*p.second);
	}
	
	SegmentTreeMax left(L);
	SegmentTreeMin right(R);

	int ans=0;
	//1つだけ取り出す
	for(int i=0;i<N;i++){
		ans=max(ans, (R[i]-L[i])+max(0, min( (i==0 ? INF : right.getmin(0, i) ), ( i==N-1 ? INF : right.getmin(i+1, N) ) ) - max( (i==0 ? 0 : left.getmax(0, i)) , (i==N-1 ? 0 : left.getmax(i+1, N)) ) ));
	}

	//ある区間まで
	for(int i=1;i<N-1;i++){
		int temp= max(0, right.getmin(0, i) - left.getmax(0, i) + right.getmin(i, N) - left.getmax(i, N) );
		ans=max(ans, temp);
	}
	cout<<ans<<endl;
	return 0;
}

Measured memory_bytes: 4724