#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <iterator>
#include <cmath>
#include <set>
#include <deque> 
#include <string>


using namespace std;

struct Range
{
	long long l, r;
	int lRank;
	int rRank;
	int pos;
};

Range ranges[100010];
int n;

struct Rank
{
	bool isUsed;
	int rankPos;
	long long val;
};

Rank isUsedRRank[100010];
Rank isUsedLRank[100010];

bool compare(const Range &a, const Range &b)
{
	if (a.l == b.l)
		return a.r > b.r;
	else
		return a.l < b.l;
}

bool compareL(const Range &a, const Range &b)
{
//	if (a.l == b.l)
//		return a.r < b.r;
//	else
		return a.l > b.l;
}

bool compareR(const Range &a, const Range &b)
{
//	if (a.r == b.r)
//		return a.l < b.l;
//	else
		return a.r < b.r;
}

bool comparePos(const Range &a, const Range &b)
{
	return a.pos < b.pos;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0 ; i < n ; i++)
	{
		scanf("%lld%lld", &(ranges[i].l), &(ranges[i].r));		
		ranges[i].pos = i;
	}
		
	sort(ranges, ranges + n, compareL);
	for (int i = 0 ; i < n ; i++)
	{
		isUsedLRank[i].isUsed = false;
		isUsedLRank[i].rankPos = ranges[i].pos;
		isUsedLRank[i].val = ranges[i].l;
		ranges[i].lRank = i;
	}
	
	sort(ranges, ranges + n, compareR);
	for (int i = 0 ; i < n ; i++)
	{
		isUsedRRank[i].isUsed = false;
		isUsedRRank[i].rankPos = ranges[i].pos;
		isUsedRRank[i].val = ranges[i].r;
		ranges[i].rRank = i;
	}
	
//	sort(ranges, ranges + n, comparePos);
		
	sort(ranges, ranges + n, compare);
	
	Range left, right;
	left.l = ranges[0].l;
	left.r = ranges[0].r;
	
	isUsedLRank[ranges[0].lRank].isUsed = true;
	isUsedRRank[ranges[0].rRank].isUsed = true;
	
	int pLRank = 0;
	while ((pLRank < n) && (isUsedLRank[pLRank].isUsed == true))
		pLRank++;
	int pRRank = 0;
	while ((pRRank < n) && (isUsedRRank[pRRank].isUsed == true))
		pRRank++;
		
	right.l = isUsedLRank[pLRank].val;
	right.r = isUsedRRank[pRRank].val;
	
	long long maxCount = 0;
	maxCount = left.r - left.l + 1;
	if (right.r >= right.l)
		maxCount = maxCount + right.r - right.l + 1;
		
	for (int i = 1 ; i <= n - 2 ; i++)
	{
		long long curCount = 0;
		if (left.l < ranges[i].l)
			left.l = ranges[i].l;
		if (left.r > ranges[i].r)
			left.r = ranges[i].r;
		if (left.r >= left.l)
			curCount = curCount + left.r - left.l + 1;
			
		isUsedLRank[ranges[i].lRank].isUsed = true;
		isUsedRRank[ranges[i].rRank].isUsed = true;
		while ((pLRank < n) && (isUsedLRank[pLRank].isUsed == true))
			pLRank++;
		while ((pRRank < n) && (isUsedRRank[pRRank].isUsed == true))
			pRRank++;
		
		right.l = isUsedLRank[pLRank].val;
		right.r = isUsedRRank[pRRank].val;
		if (right.r >= right.l)
			curCount = curCount + right.r - right.l + 1;
			
		if (maxCount < curCount)
			maxCount = curCount;
	}
	
	for (int i = 0 ; i < n ; i++)
	{
		isUsedLRank[i].isUsed = false;
		isUsedRRank[i].isUsed = false;
	}
	
	
	for (int i = 0 ; i < n ; i++)
	{
		long long curCount = ranges[i].r - ranges[i].l + 1;
		
		isUsedLRank[ranges[i].lRank].isUsed = true;
		isUsedRRank[ranges[i].rRank].isUsed = true;
		pLRank = 0;
		while ((pLRank < n) && (isUsedLRank[pLRank].isUsed == true))
			pLRank++;
		pRRank = 0;
		while ((pRRank < n) && (isUsedRRank[pRRank].isUsed == true))
			pRRank++;
			
		right.l = isUsedLRank[pLRank].val;
		right.r = isUsedRRank[pRRank].val;
		if (right.r >= right.l)
			curCount = curCount + right.r - right.l + 1;
		
		isUsedLRank[ranges[i].lRank].isUsed = false;
		isUsedRRank[ranges[i].rRank].isUsed = false;			

			
		if (maxCount < curCount)
			maxCount = curCount;
	}
	
	
	printf("%lld\n", maxCount);
	
	return 0;
}


Measured memory_bytes: 6400