import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }


enum INF = 10L^^18;

void main() {
  try {
    for (; ; ) {
      const N = readInt();
      auto A = new long[N];
      auto B = new long[N];
      foreach (i; 0 .. N) {
        A[i] = readLong() - 1;
        B[i] = readLong();
      }
      
      const xs = A.dup.sort.uniq.array;
      const ys = B.dup.sort.uniq.array;
      const xsLen = cast(int)(xs.length);
      const ysLen = cast(int)(ys.length);
      debug {
        writeln("xs = ", xs);
        writeln("ys = ", ys);
      }
      
      long lMax;
      foreach (i; 0 .. N) {
        chmax(lMax, B[i] - A[i]);
      }
      
      
      auto xbs = new long[xsLen];
      auto xMaxAs = new long[xsLen];
      auto xMinBs = new long[xsLen];
      auto yMaxAs = new long[ysLen];
      auto yMinBs = new long[ysLen];
      xbs[] = -INF;
      xMaxAs[] = -INF;
      xMinBs[] = +INF;
      yMaxAs[] = -INF;
      yMinBs[] = +INF;
      foreach (i; 0 .. N) {
        const posX = xs.lowerBound(A[i]);
        chmax(xbs[posX], B[i]);
        if (posX - 1 >= 0) {
          chmax(xMaxAs[posX - 1], A[i]);
          chmin(xMinBs[posX - 1], B[i]);
        }
        const posY = ys.lowerBound(B[i]);
        if (posY + 1 < ysLen) {
          chmax(yMaxAs[posY + 1], A[i]);
          chmin(yMinBs[posY + 1], B[i]);
        }
      }
      foreach (e; 1 .. xsLen) {
        chmax(xbs[e], xbs[e - 1]);
      }
      foreach_reverse (e; 0 .. xsLen - 1) {
        chmax(xMaxAs[e], xMaxAs[e + 1]);
        chmin(xMinBs[e], xMinBs[e + 1]);
      }
      foreach (f; 1 .. ysLen) {
        chmax(yMaxAs[f], yMaxAs[f - 1]);
        chmin(yMinBs[f], yMinBs[f - 1]);
      }
      debug {
        writeln("xbs = ", xbs);
        writeln("xMaxAs = ", xMaxAs);
        writeln("xMinBs = ", xMinBs);
        writeln("yMaxAs = ", yMaxAs);
        writeln("yMinBs = ", yMinBs);
      }
      
      long ans;
      {
        const e = xsLen - 1;
        foreach (f; 0 .. ysLen) {
          if (ys[f] <= xbs[e]) {
            const z = max(xMaxAs[e], yMaxAs[f]);
            const w = min(xMinBs[e], yMinBs[f]);
            long score;
            score += max(ys[f] - xs[e], 0);
            if (-INF < z && w < +INF) {
              score += max(w - z, 0);
            } else {
              score += lMax;
            }
            writefln("%s %s: [%s, %s] [%s, %s] %s", e, f, xs[e], ys[f], z, w, score);
            chmax(ans, score);
          }
        }
      }
      writeln(ans);
      
    }
  } catch (EOFException e) {
  }
}
