#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < n; i++)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define ll long long int
const int INF = 2147483647;
const ll MOD = 1000000007;

using namespace std;

template <class T> class SegmentTree {
public:
  SegmentTree(const int n, const T id, function<T(T, T)> op,
              function<T(T, T)> updateOp);
  void update(const int index, const T value);
  T find(const int l, const int r);

private:
  int leftChildIndex(const int parent);
  int rightChildIndex(const int parent);
  int parent(const int child);
  int leaf(const int index);
  T query(const int l, const int r, const int node, const int al, const int ar);

private:
  vector<T> data;
  int leafNum;
  T id;
  function<T(T, T)> op;
  function<T(T, T)> updateOp;
};

template <class T>
SegmentTree<T>::SegmentTree(const int n, const T id, function<T(T, T)> op,
                            function<T(T, T)> updateOp)
    : id(id), op(op), updateOp(updateOp) {
  leafNum = 1;
  while (leafNum < n)
    leafNum *= 2;
  data = vector<T>(2 * leafNum - 1, id);
}

template <class T> int SegmentTree<T>::leftChildIndex(const int parent) {
  return parent * 2 + 1;
}

template <class T> int SegmentTree<T>::rightChildIndex(const int parent) {
  return parent * 2 + 2;
}

template <class T> int SegmentTree<T>::parent(const int child) {
  return (child - 1) / 2;
}

template <class T> int SegmentTree<T>::leaf(const int index) {
  return index + leafNum - 1;
}

// [l,r)で探す
template <class T> T SegmentTree<T>::find(const int l, const int r) {
  return query(l, r, 0, 0, leafNum);
}

template <class T>
T SegmentTree<T>::query(const int l, const int r, const int node, const int al,
                        const int ar) {
  if (r <= al || ar <= l)
    return id;
  if (l <= al && ar <= r)
    return data[node];
  int mid = (al + ar) / 2;
  T leftValue = query(l, r, leftChildIndex(node), al, mid);
  T rightValue = query(l, r, rightChildIndex(node), mid, ar);
  return op(leftValue, rightValue);
}

template <class T> void SegmentTree<T>::update(const int index, const T value) {
  int i = leaf(index);
  data[i] = updateOp(data[i], value);
  while (i > 0) {
    i = parent(i);
    data[i] = op(data[rightChildIndex(i)], data[leftChildIndex(i)]);
  }
}

bool comp(const pair<int, int> a, const pair<int, int> b) {
  if (a.second != b.second) {
    return a.second < b.second;
  } else {
    return a.first < b.first;
  }
}

int main() {
  int n;
  cin >> n;
  vector<pair<ll, ll>> right(n), left(n);
  REP(i, n) {
    ll l, r;
    cin >> l >> r;
    right[i] = make_pair(l, r);
    left[i] = make_pair(l, r);
  }
  ll ans = 0;

  SegmentTree<ll> segr(n, INF, [](ll a, ll b) -> ll { return min(a, b); },
                       [](ll a, ll b) -> ll { return b; });

  SegmentTree<ll> segl(n, 0, [](ll a, ll b) -> ll { return max(a, b); },
                       [](ll a, ll b) -> ll { return b; });

  sort(left.begin(), left.end());
  REP(i, n) { segr.update(i, left[i].second); }
  REP(i, n - 1) {
    ll ans_left = max(0LL, segr.find(0, i + 1) - left[i].first + 1);
    ll ans_right = max(0LL, segr.find(i + 1, n) - left[n - 1].first + 1);
    ans = max(ans, ans_left + ans_right);
  }

  sort(right.begin(), right.end(), comp);
  REP(i, n) { segl.update(i, right[i].first); }
  REP(i, n - 1) {
    ll ans_left = max(0LL, right[0].second - segl.find(0, i + 1));
    ll ans_right = max(0LL, right[i].second - segl.find(i + 1, n));
    ans = max(ans, ans_left + ans_right);
  }

  REP(i, n) {
    ll areba = 0;
    if (i != 0 && i != n - 1)
      areba = max(0LL, right[0].second -
                           max(segl.find(0, i), segl.find(i + 1, n)) + 1);
    ans = max(ans, right[i].second - right[i].first + areba + 1);
  }
  REP(i, n) {
    ll areba = 0;
    if (i != 0 && i != n - 1)
      areba = max(0LL, min(segr.find(0, i), segr.find(i + 1, n)) -
                           left[n - 1].first + 1);
    ans = max(ans, left[i].second - left[i].first + areba + 1);
  }
  cout << ans << endl;
}


Measured memory_bytes: 7424