#include <bits/stdc++.h>
using namespace std;
struct node {
  int n;
  int l1;
  int r1;
  int l2;
  int r2;
  bool operator<(const node& rhs) const {
    if (n != rhs.n) return n < rhs.n;
    if (l1 != rhs.l1) return l1 < rhs.l1;
    if (l2 != rhs.l2) return l2 < rhs.l2;
    if (r1 != rhs.r1) return r1 < rhs.r1;
    return r2 < rhs.r2;
  }
};
map<node, int> dp;
int dfs(int n, int l1, int r1, int l2, int r2) {
  if (l1 < 0 || l2 < 0 || r1 < 0 || r2 < 0) return 0;
  if (l1 >= n || l2 >= n || r1 >= n || r2 >= n) return 0;
  if (n == 1) {
    return 1;
  }
  node p = {n, l1, r1, l2, r2};
  if (dp.find(p) != dp.end()) {
    return (dp[p]);
  }
  int mid = n / 2;
  int ans = 0;
  if (l1 <= mid && r1 >= mid && l2 <= mid && r2 >= mid) {
    ans = dfs(mid, l1, mid - 1, l2, mid - 1) + 1 +
          dfs(mid, 0, r1 - mid - 1, 0, r2 - mid - 1);
    ans = max(ans, dfs(mid, l1, mid - 1, l2, mid - 1));
    ans = max(ans, dfs(mid, l1, mid - 1, 0, r2 - mid - 1));
    ans = max(ans, dfs(mid, 0, r1 - mid - 1, l2, mid - 1));
    ans = max(ans, dfs(mid, 0, r1 - mid - 1, 0, r2 - mid - 1));
  } else if (l1 <= mid && r1 >= mid) {
    if (l2 > mid) {
      l2 -= mid + 1;
      r2 -= mid + 1;
    }
    ans = dfs(mid, l1, mid - 1, l2, r2);
    ans = max(ans, dfs(mid, 0, r1 - mid - 1, l2, r2));
  } else if (l2 <= mid && r2 >= mid) {
    if (l1 > mid) {
      l1 -= mid + 1;
      r1 -= mid + 1;
    }
    ans = dfs(mid, l1, r1, l2, mid - 1);
    ans = max(ans, dfs(mid, l1, r1, 0, r2 - mid - 1));
  } else {
    if (l1 > mid) {
      l1 -= mid + 1;
      r1 -= mid + 1;
    }
    if (l2 > mid) {
      l2 -= mid + 1;
      r2 -= mid + 1;
    }
    ans = dfs(mid, l1, r1, l2, r2);
  }
  dp[p] = ans;
  return ans;
}
int main() {
  int l1, r1, l2, r2;
  cin >> l1 >> r1 >> l2 >> r2;
  int ans = dfs((1 << 30) - 1, l1 - 1, r1 - 1, l2 - 1, r2 - 1);
  cout << ans << endl;
  return 0;
}
