#include <bits/stdc++.h>
using namespace std;
void loadData(void);
int proc(void);
void printRes(int);
int left1, right1, left2, right2;
int pow2[31];
int getRes(int, int, int, int);
int getMaxCLevelAndPos(int, int, int&);
bool lyb_debug = false;
int main(int argc, char** argv) {
  loadData();
  printRes(proc());
  return 0;
}
int getMaxCLevelAndPos(int l, int r, int& pos) {
  if (lyb_debug) {
    printf("==check for (%d - %d)\n\n", l, r);
  }
  for (int i = 31 - 1; i >= 0; i--)
    if (r >= pow2[i] - 1 && l <= pow2[i] - 1) {
      pos = pow2[i] - 1;
      return i;
    }
  int min_pow2_pos;
  for (min_pow2_pos = 31 - 1; min_pow2_pos >= 0; min_pow2_pos--)
    if (l >= pow2[min_pow2_pos]) break;
  if (min_pow2_pos == -1)
    return -1;
  else {
    int ret =
        getMaxCLevelAndPos(l - pow2[min_pow2_pos], r - pow2[min_pow2_pos], pos);
    if (ret != -1) pos += pow2[min_pow2_pos];
    return ret;
  }
  return -1;
}
int getRes(int l1, int r1, int l2, int r2) {
  if (r1 < l1 || r2 < l2) return 0;
  int maxCPos1 = -1;
  int maxCLevel1 = getMaxCLevelAndPos(l1, r1, maxCPos1);
  if (lyb_debug) {
    printf("==res for l:%d r:%d : level:%d pos:%d\n\n", l1, r1, maxCLevel1,
           maxCPos1);
  }
  int maxCPos2 = -1;
  int maxCLevel2 = getMaxCLevelAndPos(l2, r2, maxCPos2);
  if (lyb_debug) {
    printf("==res for l:%d r:%d : level:%d pos:%d\n\n", l2, r2, maxCLevel2,
           maxCPos2);
  }
  if (maxCLevel1 == -1 || maxCLevel2 == -1) {
    if (maxCLevel1 == -1 && maxCLevel2 == -1) return 1;
    if (maxCLevel1 == -1) return r2 - l2 == 0 ? 0 : 1;
    if (maxCLevel2 == -1) return r1 - l1 == 0 ? 0 : 1;
  }
  if (maxCLevel1 == maxCLevel2) {
    int res = min(r1 - maxCPos1, r2 - maxCPos2) +
              min(maxCPos1 - l1, maxCPos2 - l2) + 1;
    int newl1, newr1, newl2, newr2;
    if (maxCPos1 - l1 > r1 - maxCPos1) {
      newl1 = l1;
      newr1 = maxCPos1 - 1;
    } else {
      newl1 = maxCPos1 + 1;
      newr1 = r1;
    }
    if (maxCPos2 - l2 > r2 - maxCPos2) {
      newl2 = l2;
      newr2 = maxCPos2 - 1;
    } else {
      newl2 = maxCPos2 + 1;
      newr2 = r2;
    }
    res = max(res, getRes(newl1, newr1, newl2, newr2));
    return res;
  } else if (maxCLevel1 > maxCLevel2) {
    return max(getRes(max(maxCPos1 - pow2[maxCLevel2 + 1] + 1, l1),
                      maxCPos1 - 1, l2, r2),
               getRes(maxCPos1 + 1,
                      min(r1, maxCPos1 + pow2[maxCLevel2 + 1] + 1), l2, r2));
  } else {
    return max(getRes(l1, r1, max(maxCPos2 - pow2[maxCLevel1 + 1] + 1, l2),
                      maxCPos2 - 1),
               getRes(l1, r1, maxCPos2 + 1,
                      min(r2, maxCPos2 + pow2[maxCLevel1 + 1] + 1)));
  }
  return 0;
}
void initPow2(void) {
  pow2[0] = 1;
  for (int i = 1; i < 31; i++) pow2[i] = 2 * pow2[i - 1];
  if (lyb_debug) {
    printf("==pow2==\n");
    for (int i = 0; i < 31; i++) printf("%d ", pow2[i]);
    printf("\n\n");
  }
  return;
}
int proc(void) {
  initPow2();
  return getRes(left1, right1, left2, right2);
}
void loadData(void) {
  scanf("%d%d%d%d", &left1, &right1, &left2, &right2);
  left1--;
  right1--;
  left2--;
  right2--;
  return;
}
void printRes(int res) {
  printf("%d\n", res);
  return;
}
