#include <iostream>
#include <vector>
#include <array>
#include <list>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <string>
#include <sstream>
#include <algorithm>
#include <random>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>

#define FOR_LT(i, beg, end) for (int i = beg; i < end; i++)
#define FOR_LE(i, beg, end) for (int i = beg; i <= end; i++)
#define FOR_DW(i, beg, end) for (int i = beg; end <= i; i--)

using namespace std;

struct Seg {
	int start;
	int last;
};

void update(vector<Seg>& stree, int i, int m, Seg& val)
{
	stree[i] = val;
	int idx  = i;
	int idx2 = m + (i / 2);
	int d    = m / 2;
	int d2   = 4;
	int m2 = m + d;
	while (d != 0) {
		int idx3 = (idx & ~1) + (1 - (idx & 1));
		//cout << idx2 << " " << idx3 << " " << idx << " " << endl;
		Seg& s1 = stree[idx];
		Seg& s2 = stree[idx3];
		stree[idx2] = { max(s1.start, s2.start), min(s1.last, s2.last) };
		idx   = idx2;
		idx2  = m2 + (i / d2);
		d /= 2;
		m2 += d;
		d2 *= 2;
	}
}

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

	int n; cin >> n;
	vector<Seg> segs(n);

	for (auto& seg : segs) {
		cin >> seg.start >> seg.last;
	}
	vector<Seg> segs2 = segs;

	int ans = 0;
	{
		sort(segs.begin(), segs.end(), [](const auto & lhs, const auto & rhs) {
			if (lhs.start != rhs.start) return (lhs.start < rhs.start);
			return lhs.last < rhs.last;
		});

		vector<int> fh(n);
		{
			Seg cs = segs[0];
			FOR_LT(i, 0, n) {
				cs.start = max(segs[i].start, cs.start);
				cs.last = min(segs[i].last, cs.last);
				fh[i] = max(0, cs.last - cs.start + 1);
			}
		}
		vector<int> fb(n);
		{
			Seg cs = segs[n - 1];
			FOR_DW(i, n - 1, 0) {
				cs.start = max(segs[i].start, cs.start);
				cs.last = min(segs[i].last, cs.last);
				fb[i] = max(0, cs.last - cs.start + 1);
			}
		}

		FOR_LT(i, 0, n - 1) {
			ans = max(ans, fh[i] + fb[i + 1]);
			//cout << ans << " " << i << " " << fh[i] << " " << fb[i + 1] << endl;
		}
	}

	{
		sort(segs2.begin(), segs2.end(), [](const auto & lhs, const auto & rhs) {
			if (lhs.last != rhs.last) return lhs.last > rhs.last;
			return lhs.start > rhs.start;
			});

		vector<int> fh(n);
		{
			Seg cs = segs2[0];
			FOR_LT(i, 0, n) {
				cs.start = max(segs2[i].start, cs.start);
				cs.last = min(segs2[i].last, cs.last);
				fh[i] = max(0, cs.last - cs.start + 1);
			}
		}
		vector<int> fb(n);
		{
			Seg cs = segs2[n - 1];
			FOR_DW(i, n - 1, 0) {
				cs.start = max(segs2[i].start, cs.start);
				cs.last = min(segs2[i].last, cs.last);
				fb[i] = max(0, cs.last - cs.start + 1);
			}
		}

		FOR_LT(i, 0, n - 1) {
			ans = max(ans, fh[i] + fb[i + 1]);
		}
	}

	{
		// seg tree
		int m = 1;
		while (m < n) m *= 2;
		vector<Seg> stree(2 * m);
		{
			FOR_LT(i, 0, n) {
				stree[i] = segs[i];
			}
			FOR_LT(i, n, m) {
				stree[i] = { 1, 1000000000 };
			}

			int d    = m / 2;
			int idx  = m;
			int idx2 = 0;
			while (d != 0) {
				//cout << d << " " << idx << " " << idx2 << endl;
				FOR_LT(j, 0, d) {
					Seg& s1 = stree[idx2];
					idx2++;
					Seg& s2 = stree[idx2];
					idx2++;
					stree[idx] = { max(s1.start, s2.start), min(s1.last, s2.last) };
					idx++;
				}
				d /= 2;
			}
			//cout << "OK" << endl;
		}

		FOR_LT(i, 0, n) {
			static Seg maxseg = { 1, 1000000000 };
			update(stree, i, m, maxseg);
			ans = max(ans, segs[i].last - segs[i].start + 1 + max(0, stree[2 * m - 2].last - stree[2 * m - 2].start + 1));
			update(stree, i, m, segs[i]);
		}
	}

	cout << ans << endl;

	return 0;
}


Measured memory_bytes: 4064