#include <bits/stdc++.h>
using namespace std;
const int INF = 2147000000;
const long long inf = 1e18;
long long gcd(long long a, long long b) {
  if (!b) return a;
  return gcd(b, a % b);
}
void exgcd(long long a, long long b, long long& d, long long& x, long long& y) {
  if (!b) {
    d = a;
    x = 1;
    y = 0;
  } else {
    exgcd(b, a % b, d, y, x);
    y -= x * (a / b);
  }
}
long long pow_mod(long long a, long long p, long long n) {
  if (p == 0) return 1;
  long long ans = pow_mod(a, p / 2, n);
  ans = ans * ans % n;
  if (p % 2 == 1) ans = ans * a % n;
  return ans;
}
const int maxn = 6e5 + 100;
struct Seg {
  int l, r;
} seg[maxn];
vector<int> V;
int n;
int sumv[4 * maxn], maxv[4 * maxn], addv[4 * maxn];
void maintain(int o) {
  int lc = 2 * o, rc = 2 * o + 1;
  sumv[o] = sumv[lc] + sumv[rc];
  maxv[o] = max(maxv[lc], maxv[rc]);
}
void pushdown(int o, int L, int R) {
  if (addv[o]) {
    int lc = 2 * o, rc = 2 * o + 1;
    int M = L + (R - L) / 2;
    addv[lc] += addv[o];
    addv[rc] += addv[o];
    maxv[lc] += addv[o];
    maxv[rc] += addv[o];
    sumv[lc] += (M - L + 1) * addv[o];
    sumv[rc] += (R - M) * addv[o];
    addv[o] = 0;
  }
}
void update(int o, int L, int R, int ql, int qr, int v) {
  if (ql <= L && qr >= R) {
    addv[o] += v;
    sumv[o] += v * (R - L + 1);
    maxv[o] += v;
    return;
  }
  int M = L + (R - L) / 2;
  pushdown(o, L, R);
  if (ql <= M) {
    update(2 * o, L, M, ql, qr, v);
  }
  if (qr > M) {
    update(2 * o + 1, M + 1, R, ql, qr, v);
  }
  maintain(o);
}
int query(int o, int L, int R, int v) {
  if (maxv[o] < v) return 0;
  if (sumv[o] == (R - L + 1) * v) {
    return V[R + 1] - V[L];
  }
  pushdown(o, L, R);
  int M = L + (R - L) / 2;
  int res = 0;
  if (maxv[2 * o] >= v) res = query(2 * o, L, M, v);
  if (maxv[2 * o + 1] >= v) res += query(2 * o + 1, M + 1, R, v);
  maintain(o);
  return res;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &seg[i].l, &seg[i].r);
    V.push_back(seg[i].l);
    V.push_back(seg[i].r);
  }
  sort(V.begin(), V.end());
  V.erase(unique(V.begin(), V.end()), V.end());
  int N = V.size();
  int flag = 0;
  for (int i = 1; i <= n; i++) {
    int ql = lower_bound(V.begin(), V.end(), seg[i].l) - V.begin();
    int qr = lower_bound(V.begin(), V.end(), seg[i].r) - V.begin();
    qr--;
    if (ql > qr) {
      flag++;
      continue;
    }
    update(1, 0, N - 1, ql, qr, 1);
  }
  if (flag) {
    if (flag >= 2 || flag == n) {
      printf("0\n");
      return 0;
    }
    printf("%d\n", query(1, 0, N - 1, n - flag));
    return 0;
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int ql = lower_bound(V.begin(), V.end(), seg[i].l) - V.begin();
    int qr = lower_bound(V.begin(), V.end(), seg[i].r) - V.begin();
    qr--;
    update(1, 0, N - 1, ql, qr, -1);
    ans = max(ans, query(1, 0, N - 1, n - 1));
    update(1, 0, N - 1, ql, qr, 1);
  }
  printf("%d\n", ans);
  return 0;
}
