Polycarpus analyzes a string called abracadabra. This string is constructed using the following algorithm:   On the first step the string consists of a single character "a".  On the k-th step Polycarpus concatenates two copies of the string obtained on the (k - 1)-th step, while inserting the k-th character of the alphabet between them. Polycarpus uses the alphabet that consists of lowercase Latin letters and digits (a total of 36 characters). The alphabet characters are numbered like this: the 1-st character is "a", the 2-nd — "b", ..., the 26-th — "z", the 27-th — "0", the 28-th — "1", ..., the 36-th — "9". Let's have a closer look at the algorithm. On the second step Polycarpus will concatenate two strings "a" and insert the character "b" between them, resulting in "aba" string. The third step will transform it into "abacaba", and the fourth one - into "abacabadabacaba". Thus, the string constructed on the k-th step will consist of 2k - 1 characters. Polycarpus wrote down the string he got after 30 steps of the given algorithm and chose two non-empty substrings of it. Your task is to find the length of the longest common substring of the two substrings selected by Polycarpus.A substring s[i... j] (1 ≤ i ≤ j ≤ |s|) of string s = s1s2... s|s| is a string sisi + 1... sj. For example, substring s[2...4] of string s = "abacaba" equals "bac". The string is its own substring.The longest common substring of two strings s and t is the longest string that is a substring of both s and t. For example, the longest common substring of "contest" and "systemtesting" is string "test". There can be several common substrings of maximum length.

The input consists of a single line containing four integers l1, r1, l2, r2 (1 ≤ li ≤ ri ≤ 109, i = 1, 2). The numbers are separated by single spaces. li and ri give the indices of the first and the last characters of the i-th chosen substring, correspondingly (i = 1, 2). The characters of string abracadabra are numbered starting from 1.

Print a single number — the length of the longest common substring of the given strings. If there are no common substrings, print 0.

NoteIn the first sample the first substring is "acab", the second one is "abac". These two substrings have two longest common substrings "ac" and "ab", but we are only interested in their length — 2.In the second sample the first substring is "a", the second one is "c". These two substrings don't have any common characters, so the length of their longest common substring is 0.

using System;

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
    public class Input
    {
        private static string _line;

        public static bool Next()
        {
            _line = Console.ReadLine();
            return _line != null;
        }

        public static bool Next(out long a)
        {
            var ok = Next();
            a = ok ? long.Parse(_line) : 0;
            return ok;
        }

        public static bool Next(out long a, out long b)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
            }
            else
            {
                a = b = 0;
            }

            return ok;
        }

        public static bool Next(out long a, out long b, out long c)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
            }
            else
            {
                a = b = c = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
            }
            else
            {
                a = b = c = d = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d, out long e)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
                e = array[4];
            }
            else
            {
                a = b = c = d = e = 0;
            }
            return ok;
        }

        public static List<long> Numbers()
        {
            return !Next() ? new List<long>() : _line.Split(' ').Select(long.Parse).ToList();
        }

        public static bool Next(out string value)
        {
            value = string.Empty;
            if (!Next()) return false;
            value = _line;
            return true;
        }
    }

    public class DisjointSet
    {
        private readonly int[] _parent;
        private readonly int[] _rank;
        public int Count { get; private set; }

        public DisjointSet(int count, int initialize = 0)
        {
            Count = count;
            _parent = new int[Count];
            _rank = new int[Count];
            for (var i = 0; i < initialize; i++) _parent[i] = i;
        }

        private DisjointSet(int count, int[] parent, int[] rank)
        {
            Count = count;
            _parent = parent;
            _rank = rank;
        }

        public void Add(int v)
        {
            _parent[v] = v;
            _rank[v] = 0;
        }

        public int Find_Recursive(int v)
        {
            if (_parent[v] == v) return v;
            return _parent[v] = Find(_parent[v]);
        }

        public int Find(int v)
        {
            if (_parent[v] == v) return v;
            var last = v;
            while (_parent[last] != last) last = _parent[last];
            while (_parent[v] != v)
            {
                var t = _parent[v];
                _parent[v] = last;
                v = t;
            }
            return last;
        }

        public int this[int v]
        {
            get { return Find(v); }
            set { Union(v, value); }
        }

        public void Union(int a, int b)
        {
            a = Find(a);
            b = Find(b);
            if (a == b) return;
            if (_rank[a] < _rank[b])
            {
                var t = _rank[a];
                _rank[a] = _rank[b];
                _rank[b] = t;
            }
            _parent[b] = a;
            if (_rank[a] == _rank[b]) _rank[a]++;
        }

        public int GetSetCount()
        {
            var result = 0;
            for (var i = 0; i < Count; i++)
            {
                if (_parent[i] == i) result++;
            }
            return result;
        }

        public DisjointSet Clone()
        {
            var rank = new int[Count];
            _rank.CopyTo(rank, 0);
            var parent = new int[Count];
            _parent.CopyTo(parent, 0);
            return new DisjointSet(Count, parent, rank);
        }

        public override string ToString()
        {
            return string.Join(",", _parent.Take(50));
        }
    }

    public class Matrix
    {
        public static Matrix Create(int i, int j)
        {
            var m = new Matrix(i, j);
            return m;
        }

        public static Matrix Create(int i)
        {
            var m = new Matrix(i, i);
            return m;
        }

        public long Modulo { get; set; }

        private readonly int _width;
        private readonly int _height;
        private readonly long[,] _data;
        public int Width{get { return _width; }}
        public int Height{get { return _height; }}

        private Matrix(int i, int j)
        {
            Modulo = 1000000000000000000L;
            _width = j;
            _height = i;
            _data = new long[_height, _width];
        }

        public static Matrix operator *(Matrix m1, Matrix m2)
        {
            if (m1.Width != m2.Height) throw new InvalidDataException("m1.Width != m2.Height");
            var m = Create(m2.Width, m1.Height);
            m.Modulo = m1.Modulo;
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                {
                    for (var k = 0; k < m1.Width; k++)
                        m[j, i] += (m1[j, k]*m2[k, i]) % m1.Modulo;
                    m[j, i] %= m1.Modulo;
                }
            return m;
        }

        public static Matrix operator +(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] + m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator -(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] - m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator *(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i=0;i<m1.Width;i++)
                for (var j=0;j<m1.Height;j++)
                        m[j, i] = (m[j, i] * l) % m.Modulo;
            return m;
        }

        public static Matrix operator *(long l, Matrix m1)
        {
            return m1*l;
        }

        public static Matrix operator +(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i = 0; i < m1.Width; i++)
                    m[i, i] = (m[i, i] + l) % m.Modulo;
            return m;
        }

        public static Matrix operator +(long l, Matrix m1)
        {
            return m1 + l;
        }

        public static Matrix operator -(Matrix m1, long l)
        {
            return m1 + (-l);
        }

        public static Matrix operator -(long l, Matrix m1)
        {
            var m = m1.Clone() * -1;
            return m + l;
        }

        public Matrix BinPower(long l)
        {
            var n = 1;
            var m = Clone();
            var result = new Matrix(m.Height, m.Width) + 1;
            result.Modulo = m.Modulo;
            while (l != 0)
            {
                var i = l & ~(l - 1);
                l -= i;
                while (n < i)
                {
                    m = m*m;
                    n <<= 1;
                }
                result *= m;
            }
            return result;
        }

        public void Fill(long l)
        {
            l %= Modulo;
            for (var i = 0; i < _height; i++)
                for (var j = 0; j < _width; j++)
                    _data[i, j] = l;
        }

        public Matrix Clone()
        {
            var m = new Matrix(_width, _height);
            Array.Copy(_data, m._data, _data.Length);
            m.Modulo = Modulo;
            return m;
        }

        public long this[int i, int j]
        {
            get { return _data[i, j]; }
            set { _data[i, j] = value % Modulo; }
        }
    }

    public class RedBlackTree<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        private readonly List<Node> _items = new List<Node>();
        private Node _root;
        private readonly IComparer<TKey> _comparer;

        public RedBlackTree()
        {
            _comparer = Comparer<TKey>.Default;
        }

        private Node _search(TKey key)
        {
            var node = _root;
            while (node != null)
            {
                var i = _comparer.Compare(key, node.Key);
                if (i == 0) return node;
                node = i > 0 ? node.Right : node.Left;
            }
            return null;
        }

        public void Add(TKey key, TValue value)
        {
            var node = new Node { Key = key, Value = value, Red = true };
            _items.Add(node);
            if (_root == null)
            {
                _root = node;
                _root.Red = false;
                return;
            }
            var x = _root;
            Node y = null;
            while (x != null)
            {
                y = x;
                x = _comparer.Compare(key, x.Key) > 0 ? x.Right : x.Left;
            }
            node.Parent = y;
            if (y == null) _root = node;
            else if (_comparer.Compare(key, y.Key) > 0) y.Right = node;
            else y.Left = node;
            InsertFixup(node);
        }

        private void InsertFixup(Node node)
        {
            while (true)
            {
                var parent = node.Parent;
                if (parent == null || !parent.Red || parent.Parent == null) break;
                var grand = parent.Parent;

                if (parent == grand.Left)
                {
                    var uncle = grand.Right;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Right) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateLeft(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateRight(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
                else
                {
                    if (_root.Parent != null) Debugger.Break();

                    var uncle = grand.Left;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Left) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateRight(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateLeft(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
            }
            _root.Red = false;
        }

        private void RotateLeft(Node node)
        {
            if (node.Right == null)
                throw new NotSupportedException("Cannot rotate left: right node is missing");
            var parent = node.Parent;
            var right = node.Right;
            right.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = right;
                else parent.Right = right;
            }
            node.Right = right.Left;
            if (node.Right != null)
                node.Right.Parent = node;
            right.Left = node;
            node.Parent = right;
        }

        private void RotateRight(Node node)
        {
            if (node.Left == null)
                throw new NotSupportedException("Cannot rotate right: left node is missing");
            var parent = node.Parent;
            var left = node.Left;
            left.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = left;
                else parent.Right = left;
            }
            node.Left = left.Right;
            if (node.Left != null)
                node.Left.Parent = node;
            left.Right = node;
            node.Parent = left;
        }

        public void Remove(TKey key)
        {
            var node = _search(key);
            if (node == null) return;

            var deleted = node.Left == null || node.Right == null ? node : Next(node);
            var child = deleted.Left ?? deleted.Right;
            if (child != null)
                child.Parent = deleted.Parent;
            if (deleted.Parent == null) /* root */
                _root = child;
            else if (deleted == deleted.Parent.Left)
                deleted.Parent.Left = child;
            else
                deleted.Parent.Right = child;
            if (node != deleted)
            {
                node.Key = deleted.Key;
                node.Value = deleted.Value;
            }

            if (!deleted.Red)
            {
                DeleteFixup(child, deleted.Parent);
            }
        }

        private void DeleteFixup(Node node, Node parent)
        {
            while (parent != null && (node == null || !node.Red))
            {
                if (node == parent.Left)
                {
                    var brother = parent.Right;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateLeft(parent);
                        brother = parent.Right;
                    }
                    if ((brother.Left == null || !brother.Left.Red) && (brother.Right == null || !brother.Right.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Right == null || !brother.Right.Red)
                        {
                            if (brother.Left != null)
                                brother.Left.Red = false;
                            brother.Red = true;
                            RotateRight(brother);
                            brother = parent.Right;
                        }
                        if (!brother.Right.Red) Debugger.Break();
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Right != null)
                            brother.Right.Red = false;
                        RotateLeft(parent);
                        node = _root;
                    }
                }
                else
                {
                    var brother = parent.Left;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateRight(parent);
                        brother = parent.Left;
                    }
                    if ((brother.Right == null || !brother.Right.Red) && (brother.Left == null || !brother.Left.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Left == null || !brother.Left.Red)
                        {
                            if (brother.Right != null)
                                brother.Right.Red = false;
                            brother.Red = true;
                            RotateLeft(brother);
                            brother = parent.Left;
                        }
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Left != null)
                            brother.Left.Red = false;
                        RotateRight(parent);
                        node = _root;
                    }
                }
                parent = node.Parent;
            }

            node.Red = false;
        }

        public TValue this[TKey key]
        {
            get
            {
                var node = _search(key);
                return node == null ? default(TValue) : node.Value;
            }
            set
            {
                var node = _search(key);
                if (node == null) Add(key, value);
                else node.Value = value;
            }
        }

        public bool Check()
        {
            int count;
            return _root == null || _root.Check(out count);
        }

        private Node Minimum(Node node)
        {
            var result = node;
            while (result.Left != null) result = result.Left;
            return result;
        }

        private Node Maximum(Node node)
        {
            var result = node;
            while (result.Right != null) result = result.Right;
            return result;
        }

        private Node Next(Node node)
        {
            Node result;
            if (node.Right != null)
            {
                result = Minimum(node.Right);
            }
            else
            {
                while (node.Parent != null && node.Parent.Right == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        private Node Previous(Node node)
        {
            Node result;
            if (node.Left != null)
            {
                result = Maximum(node.Left);
            }
            else
            {
                while (node.Parent != null && node.Parent.Left == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        public void Print()
        {
            var node = Minimum(_root);
            while (node != null)
            {
                Console.Write(node.Red ? '*' : ' ');
                Console.Write(node.Key);
                Console.Write('\t');
                node = Next(node);
            }
        }

        #region Nested classes

        [DebuggerDisplay("{ToString()}")]
        private sealed class Node
        {
            public TKey Key;
            public TValue Value;
            public bool Red;

            public Node Parent;
            public Node Left;
            public Node Right;

            public bool Check(out int count)
            {
                count = 0;
                if (Red)
                {
                    if (Left != null && Left.Red) return false;
                    if (Right != null && Right.Red) return false;
                }
                var left = 0;
                var right = 0;
                if (Left != null && !Left.Check(out left)) return false;
                if (Right != null && !Right.Check(out right)) return false;
                count = left + (Red ? 0 : 1);
                if (left != right)
                {
                    ;
                }
                return left == right;
            }

            public override string ToString()
            {
                return ToShortString(2);
            }

            private string ToShortString(int depth = 0)
            {
                return depth == 0
                    ? string.Format("{0}{1}", Red ? "*" : "", Key)
                    : string.Format("({1}<{0}>{2})", ToShortString(), Left == null ? "null" : Left.ToShortString(depth - 1), Right == null ? "null" : Right.ToShortString(depth - 1));
            }
        }

        #endregion

        #region IEnumerable

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}

namespace Codeforces.TaskC
{
    public class Task
    {
        public static void Main()
        {
            var task = new Task();
            try
            {
                task.Solve();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex);
                throw;
            }
        }

        /*abacabadabacaba*/

        private long MaxSubstring(long best, long l, long r, long a, long b, int ch)
        {
            if (l > r || a > b) return best;
            if ((best >= b - a + 1) || (best >= r - l + 1)) return best;

            best = Math.Max(best, Math.Min(r, b) - Math.Max(l, a) + 1);
            var divide = 1 << ch;
             bool f1 = false, f2 = false;

            if (r == divide && l == r) return best;
            if (a == divide && a == b) return best;

            if (l == divide) l++;
            if (r == divide) r--;
            if (a == divide) a++;
            if (b == divide) b--;

            if (l > divide)
            {
                l -= divide;
                f1 = true;
            }
            if (r > divide)
            {
                r -= divide;
                f1 = !f1;
            }
            if (a > divide)
            {
                a -= divide;
                f2 = true;
            }
            if (b > divide)
            {
                b -= divide;
                f2 = !f2;
            }

            if (--ch >= 0)
            {
                if (f1 && f2) best = Math.Max(Math.Max(best, divide - Math.Max(l, a)), Math.Min(r, b));
                if (f1 && !f2)
                {
                    best = MaxSubstring(best, l, divide - 1, a, b, ch);
                    best = MaxSubstring(best, 1, r, a, b, ch);
                }
                if (!f1 && f2)
                {
                    best = MaxSubstring(best, l, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, r, 1, b, ch);
                }
                if (!f1 && !f2) best = MaxSubstring(best, l, r, a, b, ch);
                if (f1 && f2)
                {
                    best = MaxSubstring(best, 1, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, divide - 1, 1, b, ch);
                }
            }

            return best;
        }

        void Solve()
        {
            long l1, r1, l2, r2;
            Input.Next(out l1, out r1, out l2, out r2);
            var n = MaxSubstring(0, l1, r1, l2, r2, 29);
            Console.WriteLine(n);
        }
    }
}

using System;

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
    public class Input
    {
        private static string _line;

        public static bool Next()
        {
            _line = Console.ReadLine();
            return _line != null;
        }

        public static bool Next(out long a)
        {
            var ok = Next();
            a = ok ? long.Parse(_line) : 0;
            return ok;
        }

        public static bool Next(out long a, out long b)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
            }
            else
            {
                a = b = 0;
            }

            return ok;
        }

        public static bool Next(out long a, out long b, out long c)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
            }
            else
            {
                a = b = c = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
            }
            else
            {
                a = b = c = d = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d, out long e)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
                e = array[4];
            }
            else
            {
                a = b = c = d = e = 0;
            }
            return ok;
        }

        public static List<long> Numbers()
        {
            return !Next() ? new List<long>() : _line.Split(' ').Select(long.Parse).ToList();
        }

        public static bool Next(out string value)
        {
            value = string.Empty;
            if (!Next()) return false;
            value = _line;
            return true;
        }
    }

    public class DisjointSet
    {
        private readonly int[] _parent;
        private readonly int[] _rank;
        public int Count { get; private set; }

        public DisjointSet(int count, int initialize = 0)
        {
            Count = count;
            _parent = new int[Count];
            _rank = new int[Count];
            for (var i = 0; i < initialize; i++) _parent[i] = i;
        }

        private DisjointSet(int count, int[] parent, int[] rank)
        {
            Count = count;
            _parent = parent;
            _rank = rank;
        }

        public void Add(int v)
        {
            _parent[v] = v;
            _rank[v] = 0;
        }

        public int Find_Recursive(int v)
        {
            if (_parent[v] == v) return v;
            return _parent[v] = Find(_parent[v]);
        }

        public int Find(int v)
        {
            if (_parent[v] == v) return v;
            var last = v;
            while (_parent[last] != last) last = _parent[last];
            while (_parent[v] != v)
            {
                var t = _parent[v];
                _parent[v] = last;
                v = t;
            }
            return last;
        }

        public int this[int v]
        {
            get { return Find(v); }
            set { Union(v, value); }
        }

        public void Union(int a, int b)
        {
            a = Find(a);
            b = Find(b);
            if (a == b) return;
            if (_rank[a] < _rank[b])
            {
                var t = _rank[a];
                _rank[a] = _rank[b];
                _rank[b] = t;
            }
            _parent[b] = a;
            if (_rank[a] == _rank[b]) _rank[a]++;
        }

        public int GetSetCount()
        {
            var result = 0;
            for (var i = 0; i < Count; i++)
            {
                if (_parent[i] == i) result++;
            }
            return result;
        }

        public DisjointSet Clone()
        {
            var rank = new int[Count];
            _rank.CopyTo(rank, 0);
            var parent = new int[Count];
            _parent.CopyTo(parent, 0);
            return new DisjointSet(Count, parent, rank);
        }

        public override string ToString()
        {
            return string.Join(",", _parent.Take(50));
        }
    }

    public class Matrix
    {
        public static Matrix Create(int i, int j)
        {
            var m = new Matrix(i, j);
            return m;
        }

        public static Matrix Create(int i)
        {
            var m = new Matrix(i, i);
            return m;
        }

        public long Modulo { get; set; }

        private readonly int _width;
        private readonly int _height;
        private readonly long[,] _data;
        public int Width{get { return _width; }}
        public int Height{get { return _height; }}

        private Matrix(int i, int j)
        {
            Modulo = 1000000000000000000L;
            _width = j;
            _height = i;
            _data = new long[_height, _width];
        }

        public static Matrix operator *(Matrix m1, Matrix m2)
        {
            if (m1.Width != m2.Height) throw new InvalidDataException("m1.Width != m2.Height");
            var m = Create(m2.Width, m1.Height);
            m.Modulo = m1.Modulo;
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                {
                    for (var k = 0; k < m1.Width; k++)
                        m[j, i] += (m1[j, k]*m2[k, i]) % m1.Modulo;
                    m[j, i] %= m1.Modulo;
                }
            return m;
        }

        public static Matrix operator +(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] + m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator -(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] - m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator *(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i=0;i<m1.Width;i++)
                for (var j=0;j<m1.Height;j++)
                        m[j, i] = (m[j, i] * l) % m.Modulo;
            return m;
        }

        public static Matrix operator *(long l, Matrix m1)
        {
            return m1*l;
        }

        public static Matrix operator +(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i = 0; i < m1.Width; i++)
                    m[i, i] = (m[i, i] + l) % m.Modulo;
            return m;
        }

        public static Matrix operator +(long l, Matrix m1)
        {
            return m1 + l;
        }

        public static Matrix operator -(Matrix m1, long l)
        {
            return m1 + (-l);
        }

        public static Matrix operator -(long l, Matrix m1)
        {
            var m = m1.Clone() * -1;
            return m + l;
        }

        public Matrix BinPower(long l)
        {
            var n = 1;
            var m = Clone();
            var result = new Matrix(m.Height, m.Width) + 1;
            result.Modulo = m.Modulo;
            while (l != 0)
            {
                var i = l & ~(l - 1);
                l -= i;
                while (n < i)
                {
                    m = m*m;
                    n <<= 1;
                }
                result *= m;
            }
            return result;
        }

        public void Fill(long l)
        {
            l %= Modulo;
            for (var i = 0; i < _height; i++)
                for (var j = 0; j < _width; j++)
                    _data[i, j] = l;
        }

        public Matrix Clone()
        {
            var m = new Matrix(_width, _height);
            Array.Copy(_data, m._data, _data.Length);
            m.Modulo = Modulo;
            return m;
        }

        public long this[int i, int j]
        {
            get { return _data[i, j]; }
            set { _data[i, j] = value % Modulo; }
        }
    }

    public class RedBlackTree<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        private readonly List<Node> _items = new List<Node>();
        private Node _root;
        private readonly IComparer<TKey> _comparer;

        public RedBlackTree()
        {
            _comparer = Comparer<TKey>.Default;
        }

        private Node _search(TKey key)
        {
            var node = _root;
            while (node != null)
            {
                var i = _comparer.Compare(key, node.Key);
                if (i == 0) return node;
                node = i > 0 ? node.Right : node.Left;
            }
            return null;
        }

        public void Add(TKey key, TValue value)
        {
            var node = new Node { Key = key, Value = value, Red = true };
            _items.Add(node);
            if (_root == null)
            {
                _root = node;
                _root.Red = false;
                return;
            }
            var x = _root;
            Node y = null;
            while (x != null)
            {
                y = x;
                x = _comparer.Compare(key, x.Key) > 0 ? x.Right : x.Left;
            }
            node.Parent = y;
            if (y == null) _root = node;
            else if (_comparer.Compare(key, y.Key) > 0) y.Right = node;
            else y.Left = node;
            InsertFixup(node);
        }

        private void InsertFixup(Node node)
        {
            while (true)
            {
                var parent = node.Parent;
                if (parent == null || !parent.Red || parent.Parent == null) break;
                var grand = parent.Parent;

                if (parent == grand.Left)
                {
                    var uncle = grand.Right;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Right) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateLeft(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateRight(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
                else
                {
                    if (_root.Parent != null) Debugger.Break();

                    var uncle = grand.Left;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Left) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateRight(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateLeft(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
            }
            _root.Red = false;
        }

        private void RotateLeft(Node node)
        {
            if (node.Right == null)
                throw new NotSupportedException("Cannot rotate left: right node is missing");
            var parent = node.Parent;
            var right = node.Right;
            right.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = right;
                else parent.Right = right;
            }
            node.Right = right.Left;
            if (node.Right != null)
                node.Right.Parent = node;
            right.Left = node;
            node.Parent = right;
        }

        private void RotateRight(Node node)
        {
            if (node.Left == null)
                throw new NotSupportedException("Cannot rotate right: left node is missing");
            var parent = node.Parent;
            var left = node.Left;
            left.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = left;
                else parent.Right = left;
            }
            node.Left = left.Right;
            if (node.Left != null)
                node.Left.Parent = node;
            left.Right = node;
            node.Parent = left;
        }

        public void Remove(TKey key)
        {
            var node = _search(key);
            if (node == null) return;

            var deleted = node.Left == null || node.Right == null ? node : Next(node);
            var child = deleted.Left ?? deleted.Right;
            if (child != null)
                child.Parent = deleted.Parent;
            if (deleted.Parent == null) /* root */
                _root = child;
            else if (deleted == deleted.Parent.Left)
                deleted.Parent.Left = child;
            else
                deleted.Parent.Right = child;
            if (node != deleted)
            {
                node.Key = deleted.Key;
                node.Value = deleted.Value;
            }

            if (!deleted.Red)
            {
                DeleteFixup(child, deleted.Parent);
            }
        }

        private void DeleteFixup(Node node, Node parent)
        {
            while (parent != null && (node == null || !node.Red))
            {
                if (node == parent.Left)
                {
                    var brother = parent.Right;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateLeft(parent);
                        brother = parent.Right;
                    }
                    if ((brother.Left == null || !brother.Left.Red) && (brother.Right == null || !brother.Right.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Right == null || !brother.Right.Red)
                        {
                            if (brother.Left != null)
                                brother.Left.Red = false;
                            brother.Red = true;
                            RotateRight(brother);
                            brother = parent.Right;
                        }
                        if (!brother.Right.Red) Debugger.Break();
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Right != null)
                            brother.Right.Red = false;
                        RotateLeft(parent);
                        node = _root;
                    }
                }
                else
                {
                    var brother = parent.Left;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateRight(parent);
                        brother = parent.Left;
                    }
                    if ((brother.Right == null || !brother.Right.Red) && (brother.Left == null || !brother.Left.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Left == null || !brother.Left.Red)
                        {
                            if (brother.Right != null)
                                brother.Right.Red = false;
                            brother.Red = true;
                            RotateLeft(brother);
                            brother = parent.Left;
                        }
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Left != null)
                            brother.Left.Red = false;
                        RotateRight(parent);
                        node = _root;
                    }
                }
                parent = node.Parent;
            }

            node.Red = false;
        }

        public TValue this[TKey key]
        {
            get
            {
                var node = _search(key);
                return node == null ? default(TValue) : node.Value;
            }
            set
            {
                var node = _search(key);
                if (node == null) Add(key, value);
                else node.Value = value;
            }
        }

        public bool Check()
        {
            int count;
            return _root == null || _root.Check(out count);
        }

        private Node Minimum(Node node)
        {
            var result = node;
            while (result.Left != null) result = result.Left;
            return result;
        }

        private Node Maximum(Node node)
        {
            var result = node;
            while (result.Right != null) result = result.Right;
            return result;
        }

        private Node Next(Node node)
        {
            Node result;
            if (node.Right != null)
            {
                result = Minimum(node.Right);
            }
            else
            {
                while (node.Parent != null && node.Parent.Right == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        private Node Previous(Node node)
        {
            Node result;
            if (node.Left != null)
            {
                result = Maximum(node.Left);
            }
            else
            {
                while (node.Parent != null && node.Parent.Left == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        public void Print()
        {
            var node = Minimum(_root);
            while (node != null)
            {
                Console.Write(node.Red ? '*' : ' ');
                Console.Write(node.Key);
                Console.Write('\t');
                node = Next(node);
            }
        }

        #region Nested classes

        [DebuggerDisplay("{ToString()}")]
        private sealed class Node
        {
            public TKey Key;
            public TValue Value;
            public bool Red;

            public Node Parent;
            public Node Left;
            public Node Right;

            public bool Check(out int count)
            {
                count = 0;
                if (Red)
                {
                    if (Left != null && Left.Red) return false;
                    if (Right != null && Right.Red) return false;
                }
                var left = 0;
                var right = 0;
                if (Left != null && !Left.Check(out left)) return false;
                if (Right != null && !Right.Check(out right)) return false;
                count = left + (Red ? 0 : 1);
                if (left != right)
                {
                    ;
                }
                return left == right;
            }

            public override string ToString()
            {
                return ToShortString(2);
            }

            private string ToShortString(int depth = 0)
            {
                return depth == 0
                    ? string.Format("{0}{1}", Red ? "*" : "", Key)
                    : string.Format("({1}<{0}>{2})", ToShortString(), Left == null ? "null" : Left.ToShortString(depth - 1), Right == null ? "null" : Right.ToShortString(depth - 1));
            }
        }

        #endregion

        #region IEnumerable

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}

namespace Codeforces.TaskC
{
    public class Task
    {
        public static void Main()
        {
            var task = new Task();
            try
            {
                task.Solve();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex);
                throw;
            }
        }

        /*abacabadabacaba*/

        private long MaxSubstring(long best, long l, long r, long a, long b, int ch)
        {
            if (l > r || a > b) return best;
            if ((best >= b - a + 1) || (best >= r - l + 1)) return best;

            best = Math.Max(best, Math.Min(r, b) - Math.Max(l, a) + 1);
            var divide = 1 << ch;
             bool f1 = false, f2 = false;

            if (l == divide) l++;
            if (r == divide) r--;
            if (a == divide) a++;
            if (b == divide) b--;

            if (l > divide)
            {
                l -= divide;
                f1 = true;
            }
            if (r > divide)
            {
                r -= divide;
                f1 = !f1;
            }
            if (a > divide)
            {
                a -= divide;
                f2 = true;
            }
            if (b > divide)
            {
                b -= divide;
                f2 = !f2;
            }

            if (--ch > 1)
            {
                if (f1 && f2) best = Math.Max(Math.Max(best, divide - Math.Max(l, a)), Math.Min(r, b));
                if (f1 && !f2)
                {
                    best = MaxSubstring(best, l, divide - 1, a, b, ch);
                    best = MaxSubstring(best, 1, r, a, b, ch);
                }
                if (!f1 && f2)
                {
                    best = MaxSubstring(best, l, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, r, 1, b, ch);
                }
                if (!f1 && !f2) best = MaxSubstring(best, l, r, a, b, ch);
                if (f1 && f2)
                {
                    best = MaxSubstring(best, 1, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, divide - 1, 1, b, ch);
                }
            }

            return best;
        }

        void Solve()
        {
            long l1, r1, l2, r2;
            Input.Next(out l1, out r1, out l2, out r2);
            var n = MaxSubstring(0, l1, r1, l2, r2, 29);
            Console.WriteLine(n);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
    public class Input
    {
        private static string _line;

        public static bool Next()
        {
            _line = Console.ReadLine();
            return _line != null;
        }

        public static bool Next(out long a)
        {
            var ok = Next();
            a = ok ? long.Parse(_line) : 0;
            return ok;
        }

        public static bool Next(out long a, out long b)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
            }
            else
            {
                a = b = 0;
            }

            return ok;
        }

        public static bool Next(out long a, out long b, out long c)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
            }
            else
            {
                a = b = c = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
            }
            else
            {
                a = b = c = d = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d, out long e)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
                e = array[4];
            }
            else
            {
                a = b = c = d = e = 0;
            }
            return ok;
        }

        public static List<long> Numbers()
        {
            return !Next() ? new List<long>() : _line.Split(' ').Select(long.Parse).ToList();
        }

        public static bool Next(out string value)
        {
            value = string.Empty;
            if (!Next()) return false;
            value = _line;
            return true;
        }
    }

    public class DisjointSet
    {
        private readonly int[] _parent;
        private readonly int[] _rank;
        public int Count { get; private set; }

        public DisjointSet(int count, int initialize = 0)
        {
            Count = count;
            _parent = new int[Count];
            _rank = new int[Count];
            for (var i = 0; i < initialize; i++) _parent[i] = i;
        }

        private DisjointSet(int count, int[] parent, int[] rank)
        {
            Count = count;
            _parent = parent;
            _rank = rank;
        }

        public void Add(int v)
        {
            _parent[v] = v;
            _rank[v] = 0;
        }

        public int Find_Recursive(int v)
        {
            if (_parent[v] == v) return v;
            return _parent[v] = Find(_parent[v]);
        }

        public int Find(int v)
        {
            if (_parent[v] == v) return v;
            var last = v;
            while (_parent[last] != last) last = _parent[last];
            while (_parent[v] != v)
            {
                var t = _parent[v];
                _parent[v] = last;
                v = t;
            }
            return last;
        }

        public int this[int v]
        {
            get { return Find(v); }
            set { Union(v, value); }
        }

        public void Union(int a, int b)
        {
            a = Find(a);
            b = Find(b);
            if (a == b) return;
            if (_rank[a] < _rank[b])
            {
                var t = _rank[a];
                _rank[a] = _rank[b];
                _rank[b] = t;
            }
            _parent[b] = a;
            if (_rank[a] == _rank[b]) _rank[a]++;
        }

        public int GetSetCount()
        {
            var result = 0;
            for (var i = 0; i < Count; i++)
            {
                if (_parent[i] == i) result++;
            }
            return result;
        }

        public DisjointSet Clone()
        {
            var rank = new int[Count];
            _rank.CopyTo(rank, 0);
            var parent = new int[Count];
            _parent.CopyTo(parent, 0);
            return new DisjointSet(Count, parent, rank);
        }

        public override string ToString()
        {
            return string.Join(",", _parent.Take(50));
        }
    }

    public class Matrix
    {
        public static Matrix Create(int i, int j)
        {
            var m = new Matrix(i, j);
            return m;
        }

        public static Matrix Create(int i)
        {
            var m = new Matrix(i, i);
            return m;
        }

        public long Modulo { get; set; }

        private readonly int _width;
        private readonly int _height;
        private readonly long[,] _data;
        public int Width{get { return _width; }}
        public int Height{get { return _height; }}

        private Matrix(int i, int j)
        {
            Modulo = 1000000000000000000L;
            _width = j;
            _height = i;
            _data = new long[_height, _width];
        }

        public static Matrix operator *(Matrix m1, Matrix m2)
        {
            if (m1.Width != m2.Height) throw new InvalidDataException("m1.Width != m2.Height");
            var m = Create(m2.Width, m1.Height);
            m.Modulo = m1.Modulo;
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                {
                    for (var k = 0; k < m1.Width; k++)
                        m[j, i] += (m1[j, k]*m2[k, i]) % m1.Modulo;
                    m[j, i] %= m1.Modulo;
                }
            return m;
        }

        public static Matrix operator +(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] + m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator -(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] - m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator *(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i=0;i<m1.Width;i++)
                for (var j=0;j<m1.Height;j++)
                        m[j, i] = (m[j, i] * l) % m.Modulo;
            return m;
        }

        public static Matrix operator *(long l, Matrix m1)
        {
            return m1*l;
        }

        public static Matrix operator +(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i = 0; i < m1.Width; i++)
                    m[i, i] = (m[i, i] + l) % m.Modulo;
            return m;
        }

        public static Matrix operator +(long l, Matrix m1)
        {
            return m1 + l;
        }

        public static Matrix operator -(Matrix m1, long l)
        {
            return m1 + (-l);
        }

        public static Matrix operator -(long l, Matrix m1)
        {
            var m = m1.Clone() * -1;
            return m + l;
        }

        public Matrix BinPower(long l)
        {
            var n = 1;
            var m = Clone();
            var result = new Matrix(m.Height, m.Width) + 1;
            result.Modulo = m.Modulo;
            while (l != 0)
            {
                var i = l & ~(l - 1);
                l -= i;
                while (n < i)
                {
                    m = m*m;
                    n <<= 1;
                }
                result *= m;
            }
            return result;
        }

        public void Fill(long l)
        {
            l %= Modulo;
            for (var i = 0; i < _height; i++)
                for (var j = 0; j < _width; j++)
                    _data[i, j] = l;
        }

        public Matrix Clone()
        {
            var m = new Matrix(_width, _height);
            Array.Copy(_data, m._data, _data.Length);
            m.Modulo = Modulo;
            return m;
        }

        public long this[int i, int j]
        {
            get { return _data[i, j]; }
            set { _data[i, j] = value % Modulo; }
        }
    }

    public class RedBlackTree<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        private readonly List<Node> _items = new List<Node>();
        private Node _root;
        private readonly IComparer<TKey> _comparer;

        public RedBlackTree()
        {
            _comparer = Comparer<TKey>.Default;
        }

        private Node _search(TKey key)
        {
            var node = _root;
            while (node != null)
            {
                var i = _comparer.Compare(key, node.Key);
                if (i == 0) return node;
                node = i > 0 ? node.Right : node.Left;
            }
            return null;
        }

        public void Add(TKey key, TValue value)
        {
            var node = new Node { Key = key, Value = value, Red = true };
            _items.Add(node);
            if (_root == null)
            {
                _root = node;
                _root.Red = false;
                return;
            }
            var x = _root;
            Node y = null;
            while (x != null)
            {
                y = x;
                x = _comparer.Compare(key, x.Key) > 0 ? x.Right : x.Left;
            }
            node.Parent = y;
            if (y == null) _root = node;
            else if (_comparer.Compare(key, y.Key) > 0) y.Right = node;
            else y.Left = node;
            InsertFixup(node);
        }

        private void InsertFixup(Node node)
        {
            while (true)
            {
                var parent = node.Parent;
                if (parent == null || !parent.Red || parent.Parent == null) break;
                var grand = parent.Parent;

                if (parent == grand.Left)
                {
                    var uncle = grand.Right;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Right) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateLeft(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateRight(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
                else
                {
                    if (_root.Parent != null) Debugger.Break();

                    var uncle = grand.Left;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Left) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateRight(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateLeft(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
            }
            _root.Red = false;
        }

        private void RotateLeft(Node node)
        {
            if (node.Right == null)
                throw new NotSupportedException("Cannot rotate left: right node is missing");
            var parent = node.Parent;
            var right = node.Right;
            right.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = right;
                else parent.Right = right;
            }
            node.Right = right.Left;
            if (node.Right != null)
                node.Right.Parent = node;
            right.Left = node;
            node.Parent = right;
        }

        private void RotateRight(Node node)
        {
            if (node.Left == null)
                throw new NotSupportedException("Cannot rotate right: left node is missing");
            var parent = node.Parent;
            var left = node.Left;
            left.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = left;
                else parent.Right = left;
            }
            node.Left = left.Right;
            if (node.Left != null)
                node.Left.Parent = node;
            left.Right = node;
            node.Parent = left;
        }

        public void Remove(TKey key)
        {
            var node = _search(key);
            if (node == null) return;

            var deleted = node.Left == null || node.Right == null ? node : Next(node);
            var child = deleted.Left ?? deleted.Right;
            if (child != null)
                child.Parent = deleted.Parent;
            if (deleted.Parent == null) /* root */
                _root = child;
            else if (deleted == deleted.Parent.Left)
                deleted.Parent.Left = child;
            else
                deleted.Parent.Right = child;
            if (node != deleted)
            {
                node.Key = deleted.Key;
                node.Value = deleted.Value;
            }

            if (!deleted.Red)
            {
                DeleteFixup(child, deleted.Parent);
            }
        }

        private void DeleteFixup(Node node, Node parent)
        {
            while (parent != null && (node == null || !node.Red))
            {
                if (node == parent.Left)
                {
                    var brother = parent.Right;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateLeft(parent);
                        brother = parent.Right;
                    }
                    if ((brother.Left == null || !brother.Left.Red) && (brother.Right == null || !brother.Right.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Right == null || !brother.Right.Red)
                        {
                            if (brother.Left != null)
                                brother.Left.Red = false;
                            brother.Red = true;
                            RotateRight(brother);
                            brother = parent.Right;
                        }
                        if (!brother.Right.Red) Debugger.Break();
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Right != null)
                            brother.Right.Red = false;
                        RotateLeft(parent);
                        node = _root;
                    }
                }
                else
                {
                    var brother = parent.Left;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateRight(parent);
                        brother = parent.Left;
                    }
                    if ((brother.Right == null || !brother.Right.Red) && (brother.Left == null || !brother.Left.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Left == null || !brother.Left.Red)
                        {
                            if (brother.Right != null)
                                brother.Right.Red = false;
                            brother.Red = true;
                            RotateLeft(brother);
                            brother = parent.Left;
                        }
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Left != null)
                            brother.Left.Red = false;
                        RotateRight(parent);
                        node = _root;
                    }
                }
                parent = node.Parent;
            }

            node.Red = false;
        }

        public TValue this[TKey key]
        {
            get
            {
                var node = _search(key);
                return node == null ? default(TValue) : node.Value;
            }
            set
            {
                var node = _search(key);
                if (node == null) Add(key, value);
                else node.Value = value;
            }
        }

        public bool Check()
        {
            int count;
            return _root == null || _root.Check(out count);
        }

        private Node Minimum(Node node)
        {
            var result = node;
            while (result.Left != null) result = result.Left;
            return result;
        }

        private Node Maximum(Node node)
        {
            var result = node;
            while (result.Right != null) result = result.Right;
            return result;
        }

        private Node Next(Node node)
        {
            Node result;
            if (node.Right != null)
            {
                result = Minimum(node.Right);
            }
            else
            {
                while (node.Parent != null && node.Parent.Right == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        private Node Previous(Node node)
        {
            Node result;
            if (node.Left != null)
            {
                result = Maximum(node.Left);
            }
            else
            {
                while (node.Parent != null && node.Parent.Left == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        public void Print()
        {
            var node = Minimum(_root);
            while (node != null)
            {
                Console.Write(node.Red ? '*' : ' ');
                Console.Write(node.Key);
                Console.Write('\t');
                node = Next(node);
            }
        }

        #region Nested classes

        [DebuggerDisplay("{ToString()}")]
        private sealed class Node
        {
            public TKey Key;
            public TValue Value;
            public bool Red;

            public Node Parent;
            public Node Left;
            public Node Right;

            public bool Check(out int count)
            {
                count = 0;
                if (Red)
                {
                    if (Left != null && Left.Red) return false;
                    if (Right != null && Right.Red) return false;
                }
                var left = 0;
                var right = 0;
                if (Left != null && !Left.Check(out left)) return false;
                if (Right != null && !Right.Check(out right)) return false;
                count = left + (Red ? 0 : 1);
                if (left != right)
                {
                    ;
                }
                return left == right;
            }

            public override string ToString()
            {
                return ToShortString(2);
            }

            private string ToShortString(int depth = 0)
            {
                return depth == 0
                    ? string.Format("{0}{1}", Red ? "*" : "", Key)
                    : string.Format("({1}<{0}>{2})", ToShortString(), Left == null ? "null" : Left.ToShortString(depth - 1), Right == null ? "null" : Right.ToShortString(depth - 1));
            }
        }

        #endregion

        #region IEnumerable

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}

namespace Codeforces.TaskC
{
    public class Task
    {
        public static void Main()
        {
            var task = new Task();
            try
            {
                task.Solve();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex);
                throw;
            }
        }

        /*abacabadabacaba*/

        private long CommonLength(long l, long r, long a, long b)
        {
            return Math.Min(r, b) - Math.Max(l, a) + 1;
        }

        private long MaxSubstring(long best, long l, long r, long a, long b, int ch)
        {
            if ((best >= b - a + 1) || (best >= r - l + 1)) return best;

            best = Math.Max(best, CommonLength(l, r, a, b));
            var divide = 1 << ch--;
            bool f1 = false, f2 = false;

            if (l == divide) l++;
            if (r == divide) r--;
            if (a == divide) a++;
            if (b == divide) b--;

            if (l > divide)
            {
                l -= divide;
                f1 = true;
            }
            if (r > divide)
            {
                r -= divide;
                f1 = !f1;
            }
            if (a > divide)
            {
                a -= divide;
                f2 = true;
            }
            if (b > divide)
            {
                b -= divide;
                f2 = !f2;
            }

            if (ch > 0)
            {
                if (f1 && f2) best = Math.Max(Math.Max(best, divide - Math.Max(l, a)), Math.Min(r, b));
                if (f1) best = MaxSubstring(best, l, divide - 1, f2 ? 1 : a, b, ch);
                if (f2) best = MaxSubstring(best, f1 ? l : 1, r, a, divide - 1, ch);
                if (!f1 && !f2) best = MaxSubstring(best, l, r, a, b, ch);
                if (f1 && f2)
                {
                    best = MaxSubstring(best, 1, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, divide - 1, 1, b, ch);
                }
            }

            return best;
        }

        void Solve()
        {
            long l1, r1, l2, r2;
            Input.Next(out l1, out r1, out l2, out r2);
            l1++; r1++; l2++; r2++;
            var n = MaxSubstring(0, l1, r1, l2, r2, 29);
            Console.WriteLine(n);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
    public class Input
    {
        private static string _line;

        public static bool Next()
        {
            _line = Console.ReadLine();
            return _line != null;
        }

        public static bool Next(out long a)
        {
            var ok = Next();
            a = ok ? long.Parse(_line) : 0;
            return ok;
        }

        public static bool Next(out long a, out long b)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
            }
            else
            {
                a = b = 0;
            }

            return ok;
        }

        public static bool Next(out long a, out long b, out long c)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
            }
            else
            {
                a = b = c = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
            }
            else
            {
                a = b = c = d = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d, out long e)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
                e = array[4];
            }
            else
            {
                a = b = c = d = e = 0;
            }
            return ok;
        }

        public static List<long> Numbers()
        {
            return !Next() ? new List<long>() : _line.Split(' ').Select(long.Parse).ToList();
        }

        public static bool Next(out string value)
        {
            value = string.Empty;
            if (!Next()) return false;
            value = _line;
            return true;
        }
    }

    public class DisjointSet
    {
        private readonly int[] _parent;
        private readonly int[] _rank;
        public int Count { get; private set; }

        public DisjointSet(int count, int initialize = 0)
        {
            Count = count;
            _parent = new int[Count];
            _rank = new int[Count];
            for (var i = 0; i < initialize; i++) _parent[i] = i;
        }

        private DisjointSet(int count, int[] parent, int[] rank)
        {
            Count = count;
            _parent = parent;
            _rank = rank;
        }

        public void Add(int v)
        {
            _parent[v] = v;
            _rank[v] = 0;
        }

        public int Find_Recursive(int v)
        {
            if (_parent[v] == v) return v;
            return _parent[v] = Find(_parent[v]);
        }

        public int Find(int v)
        {
            if (_parent[v] == v) return v;
            var last = v;
            while (_parent[last] != last) last = _parent[last];
            while (_parent[v] != v)
            {
                var t = _parent[v];
                _parent[v] = last;
                v = t;
            }
            return last;
        }

        public int this[int v]
        {
            get { return Find(v); }
            set { Union(v, value); }
        }

        public void Union(int a, int b)
        {
            a = Find(a);
            b = Find(b);
            if (a == b) return;
            if (_rank[a] < _rank[b])
            {
                var t = _rank[a];
                _rank[a] = _rank[b];
                _rank[b] = t;
            }
            _parent[b] = a;
            if (_rank[a] == _rank[b]) _rank[a]++;
        }

        public int GetSetCount()
        {
            var result = 0;
            for (var i = 0; i < Count; i++)
            {
                if (_parent[i] == i) result++;
            }
            return result;
        }

        public DisjointSet Clone()
        {
            var rank = new int[Count];
            _rank.CopyTo(rank, 0);
            var parent = new int[Count];
            _parent.CopyTo(parent, 0);
            return new DisjointSet(Count, parent, rank);
        }

        public override string ToString()
        {
            return string.Join(",", _parent.Take(50));
        }
    }

    public class Matrix
    {
        public static Matrix Create(int i, int j)
        {
            var m = new Matrix(i, j);
            return m;
        }

        public static Matrix Create(int i)
        {
            var m = new Matrix(i, i);
            return m;
        }

        public long Modulo { get; set; }

        private readonly int _width;
        private readonly int _height;
        private readonly long[,] _data;
        public int Width{get { return _width; }}
        public int Height{get { return _height; }}

        private Matrix(int i, int j)
        {
            Modulo = 1000000000000000000L;
            _width = j;
            _height = i;
            _data = new long[_height, _width];
        }

        public static Matrix operator *(Matrix m1, Matrix m2)
        {
            if (m1.Width != m2.Height) throw new InvalidDataException("m1.Width != m2.Height");
            var m = Create(m2.Width, m1.Height);
            m.Modulo = m1.Modulo;
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                {
                    for (var k = 0; k < m1.Width; k++)
                        m[j, i] += (m1[j, k]*m2[k, i]) % m1.Modulo;
                    m[j, i] %= m1.Modulo;
                }
            return m;
        }

        public static Matrix operator +(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] + m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator -(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] - m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator *(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i=0;i<m1.Width;i++)
                for (var j=0;j<m1.Height;j++)
                        m[j, i] = (m[j, i] * l) % m.Modulo;
            return m;
        }

        public static Matrix operator *(long l, Matrix m1)
        {
            return m1*l;
        }

        public static Matrix operator +(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i = 0; i < m1.Width; i++)
                    m[i, i] = (m[i, i] + l) % m.Modulo;
            return m;
        }

        public static Matrix operator +(long l, Matrix m1)
        {
            return m1 + l;
        }

        public static Matrix operator -(Matrix m1, long l)
        {
            return m1 + (-l);
        }

        public static Matrix operator -(long l, Matrix m1)
        {
            var m = m1.Clone() * -1;
            return m + l;
        }

        public Matrix BinPower(long l)
        {
            var n = 1;
            var m = Clone();
            var result = new Matrix(m.Height, m.Width) + 1;
            result.Modulo = m.Modulo;
            while (l != 0)
            {
                var i = l & ~(l - 1);
                l -= i;
                while (n < i)
                {
                    m = m*m;
                    n <<= 1;
                }
                result *= m;
            }
            return result;
        }

        public void Fill(long l)
        {
            l %= Modulo;
            for (var i = 0; i < _height; i++)
                for (var j = 0; j < _width; j++)
                    _data[i, j] = l;
        }

        public Matrix Clone()
        {
            var m = new Matrix(_width, _height);
            Array.Copy(_data, m._data, _data.Length);
            m.Modulo = Modulo;
            return m;
        }

        public long this[int i, int j]
        {
            get { return _data[i, j]; }
            set { _data[i, j] = value % Modulo; }
        }
    }

    public class RedBlackTree<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        private readonly List<Node> _items = new List<Node>();
        private Node _root;
        private readonly IComparer<TKey> _comparer;

        public RedBlackTree()
        {
            _comparer = Comparer<TKey>.Default;
        }

        private Node _search(TKey key)
        {
            var node = _root;
            while (node != null)
            {
                var i = _comparer.Compare(key, node.Key);
                if (i == 0) return node;
                node = i > 0 ? node.Right : node.Left;
            }
            return null;
        }

        public void Add(TKey key, TValue value)
        {
            var node = new Node { Key = key, Value = value, Red = true };
            _items.Add(node);
            if (_root == null)
            {
                _root = node;
                _root.Red = false;
                return;
            }
            var x = _root;
            Node y = null;
            while (x != null)
            {
                y = x;
                x = _comparer.Compare(key, x.Key) > 0 ? x.Right : x.Left;
            }
            node.Parent = y;
            if (y == null) _root = node;
            else if (_comparer.Compare(key, y.Key) > 0) y.Right = node;
            else y.Left = node;
            InsertFixup(node);
        }

        private void InsertFixup(Node node)
        {
            while (true)
            {
                var parent = node.Parent;
                if (parent == null || !parent.Red || parent.Parent == null) break;
                var grand = parent.Parent;

                if (parent == grand.Left)
                {
                    var uncle = grand.Right;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Right) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateLeft(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateRight(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
                else
                {
                    if (_root.Parent != null) Debugger.Break();

                    var uncle = grand.Left;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Left) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateRight(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateLeft(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
            }
            _root.Red = false;
        }

        private void RotateLeft(Node node)
        {
            if (node.Right == null)
                throw new NotSupportedException("Cannot rotate left: right node is missing");
            var parent = node.Parent;
            var right = node.Right;
            right.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = right;
                else parent.Right = right;
            }
            node.Right = right.Left;
            if (node.Right != null)
                node.Right.Parent = node;
            right.Left = node;
            node.Parent = right;
        }

        private void RotateRight(Node node)
        {
            if (node.Left == null)
                throw new NotSupportedException("Cannot rotate right: left node is missing");
            var parent = node.Parent;
            var left = node.Left;
            left.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = left;
                else parent.Right = left;
            }
            node.Left = left.Right;
            if (node.Left != null)
                node.Left.Parent = node;
            left.Right = node;
            node.Parent = left;
        }

        public void Remove(TKey key)
        {
            var node = _search(key);
            if (node == null) return;

            var deleted = node.Left == null || node.Right == null ? node : Next(node);
            var child = deleted.Left ?? deleted.Right;
            if (child != null)
                child.Parent = deleted.Parent;
            if (deleted.Parent == null) /* root */
                _root = child;
            else if (deleted == deleted.Parent.Left)
                deleted.Parent.Left = child;
            else
                deleted.Parent.Right = child;
            if (node != deleted)
            {
                node.Key = deleted.Key;
                node.Value = deleted.Value;
            }

            if (!deleted.Red)
            {
                DeleteFixup(child, deleted.Parent);
            }
        }

        private void DeleteFixup(Node node, Node parent)
        {
            while (parent != null && (node == null || !node.Red))
            {
                if (node == parent.Left)
                {
                    var brother = parent.Right;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateLeft(parent);
                        brother = parent.Right;
                    }
                    if ((brother.Left == null || !brother.Left.Red) && (brother.Right == null || !brother.Right.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Right == null || !brother.Right.Red)
                        {
                            if (brother.Left != null)
                                brother.Left.Red = false;
                            brother.Red = true;
                            RotateRight(brother);
                            brother = parent.Right;
                        }
                        if (!brother.Right.Red) Debugger.Break();
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Right != null)
                            brother.Right.Red = false;
                        RotateLeft(parent);
                        node = _root;
                    }
                }
                else
                {
                    var brother = parent.Left;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateRight(parent);
                        brother = parent.Left;
                    }
                    if ((brother.Right == null || !brother.Right.Red) && (brother.Left == null || !brother.Left.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Left == null || !brother.Left.Red)
                        {
                            if (brother.Right != null)
                                brother.Right.Red = false;
                            brother.Red = true;
                            RotateLeft(brother);
                            brother = parent.Left;
                        }
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Left != null)
                            brother.Left.Red = false;
                        RotateRight(parent);
                        node = _root;
                    }
                }
                parent = node.Parent;
            }

            node.Red = false;
        }

        public TValue this[TKey key]
        {
            get
            {
                var node = _search(key);
                return node == null ? default(TValue) : node.Value;
            }
            set
            {
                var node = _search(key);
                if (node == null) Add(key, value);
                else node.Value = value;
            }
        }

        public bool Check()
        {
            int count;
            return _root == null || _root.Check(out count);
        }

        private Node Minimum(Node node)
        {
            var result = node;
            while (result.Left != null) result = result.Left;
            return result;
        }

        private Node Maximum(Node node)
        {
            var result = node;
            while (result.Right != null) result = result.Right;
            return result;
        }

        private Node Next(Node node)
        {
            Node result;
            if (node.Right != null)
            {
                result = Minimum(node.Right);
            }
            else
            {
                while (node.Parent != null && node.Parent.Right == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        private Node Previous(Node node)
        {
            Node result;
            if (node.Left != null)
            {
                result = Maximum(node.Left);
            }
            else
            {
                while (node.Parent != null && node.Parent.Left == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        public void Print()
        {
            var node = Minimum(_root);
            while (node != null)
            {
                Console.Write(node.Red ? '*' : ' ');
                Console.Write(node.Key);
                Console.Write('\t');
                node = Next(node);
            }
        }

        #region Nested classes

        [DebuggerDisplay("{ToString()}")]
        private sealed class Node
        {
            public TKey Key;
            public TValue Value;
            public bool Red;

            public Node Parent;
            public Node Left;
            public Node Right;

            public bool Check(out int count)
            {
                count = 0;
                if (Red)
                {
                    if (Left != null && Left.Red) return false;
                    if (Right != null && Right.Red) return false;
                }
                var left = 0;
                var right = 0;
                if (Left != null && !Left.Check(out left)) return false;
                if (Right != null && !Right.Check(out right)) return false;
                count = left + (Red ? 0 : 1);
                if (left != right)
                {
                    ;
                }
                return left == right;
            }

            public override string ToString()
            {
                return ToShortString(2);
            }

            private string ToShortString(int depth = 0)
            {
                return depth == 0
                    ? string.Format("{0}{1}", Red ? "*" : "", Key)
                    : string.Format("({1}<{0}>{2})", ToShortString(), Left == null ? "null" : Left.ToShortString(depth - 1), Right == null ? "null" : Right.ToShortString(depth - 1));
            }
        }

        #endregion

        #region IEnumerable

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}

namespace Codeforces.TaskC
{
    public class Task
    {
        public static void Main()
        {
            var task = new Task();
            try
            {
                task.Solve();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex);
                throw;
            }
        }

        /*abacabadabacaba*/

        private long CommonLength(long l, long r, long a, long b)
        {
            return Math.Min(r, b) - Math.Max(l, a) + 1;
        }

        private long MaxSubstring(long best, long l, long r, long a, long b, int ch)
        {
            if ((best >= b - a + 1) || (best >= r - l + 1)) return 0;

            var len = CommonLength(l, r, a, b);
            var divide = 1 << ch--;
            bool f1 = false, f2 = false;

            if (l == divide) l++;
            if (r == divide) r--;
            if (a == divide) a++;
            if (b == divide) b--;

            if (l > divide)
            {
                l -= divide;
                f1 ^= true;
            }
            if (r > divide)
            {
                r -= divide;
                f1 ^= true;
            }
            if (a > divide)
            {
                a -= divide;
                f2 ^= true;
            }
            if (b > divide)
            {
                b -= divide;
                f2 ^= true;
            }

            if (ch > 0)
            {
                if (f1 && f2) len = Math.Max(len, divide - Math.Max(l, a));
                len = Math.Max(len, MaxSubstring(len, r >= l ? l : 1, r, b >= a ? a : 1, b, ch));
                if (f1) len = Math.Max(len, MaxSubstring(len, l, divide - 1, b >= a ? a : 1, b, ch));
                if (f2) len = Math.Max(len, MaxSubstring(len, r >= l ? l : 1, r, a, divide - 1, ch));
            }

            return len;
        }

        void Solve()
        {
            var length = (1<<30) - 1; // 1 073 741 823
            long l1, r1, l2, r2;
            Input.Next(out l1, out r1, out l2, out r2);
            l1++; r1++; l2++; r2++;

            var n = MaxSubstring(0, l1, r1, l2, r2, 30);
            Console.WriteLine(Math.Max(0, n));
            //Console.WriteLine(GetLength(36, l1, r1, l2, r2));
        }
    }
}

using System;

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace Codeforces
{
    public class Input
    {
        private static string _line;

        public static bool Next()
        {
            _line = Console.ReadLine();
            return _line != null;
        }

        public static bool Next(out long a)
        {
            var ok = Next();
            a = ok ? long.Parse(_line) : 0;
            return ok;
        }

        public static bool Next(out long a, out long b)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
            }
            else
            {
                a = b = 0;
            }

            return ok;
        }

        public static bool Next(out long a, out long b, out long c)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
            }
            else
            {
                a = b = c = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
            }
            else
            {
                a = b = c = d = 0;
            }
            return ok;
        }

        public static bool Next(out long a, out long b, out long c, out long d, out long e)
        {
            var ok = Next();
            if (ok)
            {
                var array = _line.Split(' ').Select(long.Parse).ToArray();
                a = array[0];
                b = array[1];
                c = array[2];
                d = array[3];
                e = array[4];
            }
            else
            {
                a = b = c = d = e = 0;
            }
            return ok;
        }

        public static List<long> Numbers()
        {
            return !Next() ? new List<long>() : _line.Split(' ').Select(long.Parse).ToList();
        }

        public static bool Next(out string value)
        {
            value = string.Empty;
            if (!Next()) return false;
            value = _line;
            return true;
        }
    }

    public class DisjointSet
    {
        private readonly int[] _parent;
        private readonly int[] _rank;
        public int Count { get; private set; }

        public DisjointSet(int count, int initialize = 0)
        {
            Count = count;
            _parent = new int[Count];
            _rank = new int[Count];
            for (var i = 0; i < initialize; i++) _parent[i] = i;
        }

        private DisjointSet(int count, int[] parent, int[] rank)
        {
            Count = count;
            _parent = parent;
            _rank = rank;
        }

        public void Add(int v)
        {
            _parent[v] = v;
            _rank[v] = 0;
        }

        public int Find_Recursive(int v)
        {
            if (_parent[v] == v) return v;
            return _parent[v] = Find(_parent[v]);
        }

        public int Find(int v)
        {
            if (_parent[v] == v) return v;
            var last = v;
            while (_parent[last] != last) last = _parent[last];
            while (_parent[v] != v)
            {
                var t = _parent[v];
                _parent[v] = last;
                v = t;
            }
            return last;
        }

        public int this[int v]
        {
            get { return Find(v); }
            set { Union(v, value); }
        }

        public void Union(int a, int b)
        {
            a = Find(a);
            b = Find(b);
            if (a == b) return;
            if (_rank[a] < _rank[b])
            {
                var t = _rank[a];
                _rank[a] = _rank[b];
                _rank[b] = t;
            }
            _parent[b] = a;
            if (_rank[a] == _rank[b]) _rank[a]++;
        }

        public int GetSetCount()
        {
            var result = 0;
            for (var i = 0; i < Count; i++)
            {
                if (_parent[i] == i) result++;
            }
            return result;
        }

        public DisjointSet Clone()
        {
            var rank = new int[Count];
            _rank.CopyTo(rank, 0);
            var parent = new int[Count];
            _parent.CopyTo(parent, 0);
            return new DisjointSet(Count, parent, rank);
        }

        public override string ToString()
        {
            return string.Join(",", _parent.Take(50));
        }
    }

    public class Matrix
    {
        public static Matrix Create(int i, int j)
        {
            var m = new Matrix(i, j);
            return m;
        }

        public static Matrix Create(int i)
        {
            var m = new Matrix(i, i);
            return m;
        }

        public long Modulo { get; set; }

        private readonly int _width;
        private readonly int _height;
        private readonly long[,] _data;
        public int Width{get { return _width; }}
        public int Height{get { return _height; }}

        private Matrix(int i, int j)
        {
            Modulo = 1000000000000000000L;
            _width = j;
            _height = i;
            _data = new long[_height, _width];
        }

        public static Matrix operator *(Matrix m1, Matrix m2)
        {
            if (m1.Width != m2.Height) throw new InvalidDataException("m1.Width != m2.Height");
            var m = Create(m2.Width, m1.Height);
            m.Modulo = m1.Modulo;
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                {
                    for (var k = 0; k < m1.Width; k++)
                        m[j, i] += (m1[j, k]*m2[k, i]) % m1.Modulo;
                    m[j, i] %= m1.Modulo;
                }
            return m;
        }

        public static Matrix operator +(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] + m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator -(Matrix m1, Matrix m2)
        {
            var m = m1.Clone();
            for (var i=0;i<m2.Width;i++)
                for (var j = 0; j < m1.Height; j++)
                    m[j, i] = (m[j, i] - m2[j, i]) % m1.Modulo;
            return m;
        }

        public static Matrix operator *(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i=0;i<m1.Width;i++)
                for (var j=0;j<m1.Height;j++)
                        m[j, i] = (m[j, i] * l) % m.Modulo;
            return m;
        }

        public static Matrix operator *(long l, Matrix m1)
        {
            return m1*l;
        }

        public static Matrix operator +(Matrix m1, long l)
        {
            var m = m1.Clone();
            for (var i = 0; i < m1.Width; i++)
                    m[i, i] = (m[i, i] + l) % m.Modulo;
            return m;
        }

        public static Matrix operator +(long l, Matrix m1)
        {
            return m1 + l;
        }

        public static Matrix operator -(Matrix m1, long l)
        {
            return m1 + (-l);
        }

        public static Matrix operator -(long l, Matrix m1)
        {
            var m = m1.Clone() * -1;
            return m + l;
        }

        public Matrix BinPower(long l)
        {
            var n = 1;
            var m = Clone();
            var result = new Matrix(m.Height, m.Width) + 1;
            result.Modulo = m.Modulo;
            while (l != 0)
            {
                var i = l & ~(l - 1);
                l -= i;
                while (n < i)
                {
                    m = m*m;
                    n <<= 1;
                }
                result *= m;
            }
            return result;
        }

        public void Fill(long l)
        {
            l %= Modulo;
            for (var i = 0; i < _height; i++)
                for (var j = 0; j < _width; j++)
                    _data[i, j] = l;
        }

        public Matrix Clone()
        {
            var m = new Matrix(_width, _height);
            Array.Copy(_data, m._data, _data.Length);
            m.Modulo = Modulo;
            return m;
        }

        public long this[int i, int j]
        {
            get { return _data[i, j]; }
            set { _data[i, j] = value % Modulo; }
        }
    }

    public class RedBlackTree<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
    {
        private readonly List<Node> _items = new List<Node>();
        private Node _root;
        private readonly IComparer<TKey> _comparer;

        public RedBlackTree()
        {
            _comparer = Comparer<TKey>.Default;
        }

        private Node _search(TKey key)
        {
            var node = _root;
            while (node != null)
            {
                var i = _comparer.Compare(key, node.Key);
                if (i == 0) return node;
                node = i > 0 ? node.Right : node.Left;
            }
            return null;
        }

        public void Add(TKey key, TValue value)
        {
            var node = new Node { Key = key, Value = value, Red = true };
            _items.Add(node);
            if (_root == null)
            {
                _root = node;
                _root.Red = false;
                return;
            }
            var x = _root;
            Node y = null;
            while (x != null)
            {
                y = x;
                x = _comparer.Compare(key, x.Key) > 0 ? x.Right : x.Left;
            }
            node.Parent = y;
            if (y == null) _root = node;
            else if (_comparer.Compare(key, y.Key) > 0) y.Right = node;
            else y.Left = node;
            InsertFixup(node);
        }

        private void InsertFixup(Node node)
        {
            while (true)
            {
                var parent = node.Parent;
                if (parent == null || !parent.Red || parent.Parent == null) break;
                var grand = parent.Parent;

                if (parent == grand.Left)
                {
                    var uncle = grand.Right;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Right) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateLeft(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateRight(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
                else
                {
                    if (_root.Parent != null) Debugger.Break();

                    var uncle = grand.Left;
                    if (uncle != null && uncle.Red) /* parent and uncle both red: we could swap colors of them with grand */
                    {
                        parent.Red = false;
                        uncle.Red = false;
                        grand.Red = true;
                        node = grand; /* and continue fixing tree for grand */
                    }
                    else if (node == parent.Left) /* we rotate around the parent */
                    {
                        node = parent;
                        RotateRight(node);
                    }
                    else /* rotate around grand and switch colors of grand and parent */
                    {
                        parent.Red = false;
                        grand.Red = true;
                        RotateLeft(grand);
                        if (grand == _root) _root = parent;
                        break; /* and finish since tree is fixed */
                    }
                }
            }
            _root.Red = false;
        }

        private void RotateLeft(Node node)
        {
            if (node.Right == null)
                throw new NotSupportedException("Cannot rotate left: right node is missing");
            var parent = node.Parent;
            var right = node.Right;
            right.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = right;
                else parent.Right = right;
            }
            node.Right = right.Left;
            if (node.Right != null)
                node.Right.Parent = node;
            right.Left = node;
            node.Parent = right;
        }

        private void RotateRight(Node node)
        {
            if (node.Left == null)
                throw new NotSupportedException("Cannot rotate right: left node is missing");
            var parent = node.Parent;
            var left = node.Left;
            left.Parent = parent;
            if (parent != null)
            {
                if (parent.Left == node) parent.Left = left;
                else parent.Right = left;
            }
            node.Left = left.Right;
            if (node.Left != null)
                node.Left.Parent = node;
            left.Right = node;
            node.Parent = left;
        }

        public void Remove(TKey key)
        {
            var node = _search(key);
            if (node == null) return;

            var deleted = node.Left == null || node.Right == null ? node : Next(node);
            var child = deleted.Left ?? deleted.Right;
            if (child != null)
                child.Parent = deleted.Parent;
            if (deleted.Parent == null) /* root */
                _root = child;
            else if (deleted == deleted.Parent.Left)
                deleted.Parent.Left = child;
            else
                deleted.Parent.Right = child;
            if (node != deleted)
            {
                node.Key = deleted.Key;
                node.Value = deleted.Value;
            }

            if (!deleted.Red)
            {
                DeleteFixup(child, deleted.Parent);
            }
        }

        private void DeleteFixup(Node node, Node parent)
        {
            while (parent != null && (node == null || !node.Red))
            {
                if (node == parent.Left)
                {
                    var brother = parent.Right;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateLeft(parent);
                        brother = parent.Right;
                    }
                    if ((brother.Left == null || !brother.Left.Red) && (brother.Right == null || !brother.Right.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Right == null || !brother.Right.Red)
                        {
                            if (brother.Left != null)
                                brother.Left.Red = false;
                            brother.Red = true;
                            RotateRight(brother);
                            brother = parent.Right;
                        }
                        if (!brother.Right.Red) Debugger.Break();
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Right != null)
                            brother.Right.Red = false;
                        RotateLeft(parent);
                        node = _root;
                    }
                }
                else
                {
                    var brother = parent.Left;
                    if (brother.Red)
                    {
                        brother.Red = false;
                        parent.Red = true;
                        RotateRight(parent);
                        brother = parent.Left;
                    }
                    if ((brother.Right == null || !brother.Right.Red) && (brother.Left == null || !brother.Left.Red))
                    {
                        node = parent.Red ? _root : parent;
                        brother.Red = true;
                        parent.Red = false;
                    }
                    else
                    {
                        if (brother.Left == null || !brother.Left.Red)
                        {
                            if (brother.Right != null)
                                brother.Right.Red = false;
                            brother.Red = true;
                            RotateLeft(brother);
                            brother = parent.Left;
                        }
                        brother.Red = parent.Red;
                        parent.Red = false;
                        if (brother.Left != null)
                            brother.Left.Red = false;
                        RotateRight(parent);
                        node = _root;
                    }
                }
                parent = node.Parent;
            }

            node.Red = false;
        }

        public TValue this[TKey key]
        {
            get
            {
                var node = _search(key);
                return node == null ? default(TValue) : node.Value;
            }
            set
            {
                var node = _search(key);
                if (node == null) Add(key, value);
                else node.Value = value;
            }
        }

        public bool Check()
        {
            int count;
            return _root == null || _root.Check(out count);
        }

        private Node Minimum(Node node)
        {
            var result = node;
            while (result.Left != null) result = result.Left;
            return result;
        }

        private Node Maximum(Node node)
        {
            var result = node;
            while (result.Right != null) result = result.Right;
            return result;
        }

        private Node Next(Node node)
        {
            Node result;
            if (node.Right != null)
            {
                result = Minimum(node.Right);
            }
            else
            {
                while (node.Parent != null && node.Parent.Right == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        private Node Previous(Node node)
        {
            Node result;
            if (node.Left != null)
            {
                result = Maximum(node.Left);
            }
            else
            {
                while (node.Parent != null && node.Parent.Left == node)
                    node = node.Parent;
                result = node.Parent;
            }
            return result;
        }

        public void Print()
        {
            var node = Minimum(_root);
            while (node != null)
            {
                Console.Write(node.Red ? '*' : ' ');
                Console.Write(node.Key);
                Console.Write('\t');
                node = Next(node);
            }
        }

        #region Nested classes

        [DebuggerDisplay("{ToString()}")]
        private sealed class Node
        {
            public TKey Key;
            public TValue Value;
            public bool Red;

            public Node Parent;
            public Node Left;
            public Node Right;

            public bool Check(out int count)
            {
                count = 0;
                if (Red)
                {
                    if (Left != null && Left.Red) return false;
                    if (Right != null && Right.Red) return false;
                }
                var left = 0;
                var right = 0;
                if (Left != null && !Left.Check(out left)) return false;
                if (Right != null && !Right.Check(out right)) return false;
                count = left + (Red ? 0 : 1);
                if (left != right)
                {
                    ;
                }
                return left == right;
            }

            public override string ToString()
            {
                return ToShortString(2);
            }

            private string ToShortString(int depth = 0)
            {
                return depth == 0
                    ? string.Format("{0}{1}", Red ? "*" : "", Key)
                    : string.Format("({1}<{0}>{2})", ToShortString(), Left == null ? "null" : Left.ToShortString(depth - 1), Right == null ? "null" : Right.ToShortString(depth - 1));
            }
        }

        #endregion

        #region IEnumerable

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}

namespace Codeforces.TaskC
{
    public class Task
    {
        public static void Main()
        {
            var task = new Task();
            try
            {
                task.Solve();
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex);
                throw;
            }
        }

        /*abacabadabacaba*/

        private long MaxSubstring(long best, long l, long r, long a, long b, int ch)
        {
            if (l > r || a > b) return best;
            if ((best >= b - a + 1) || (best >= r - l + 1)) return best;

            best = Math.Max(best, Math.Min(r, b) - Math.Max(l, a) + 1);
            var divide = 1 << ch;
             bool f1 = false, f2 = false;

            if (r == divide && l == r) return best;
            if (a == divide && a == b) return best;

            if (l == divide) l++;
            if (r == divide) r--;
            if (a == divide) a++;
            if (b == divide) b--;

            if (l > divide)
            {
                l -= divide;
                f1 = true;
            }
            if (r > divide)
            {
                r -= divide;
                f1 = !f1;
            }
            if (a > divide)
            {
                a -= divide;
                f2 = true;
            }
            if (b > divide)
            {
                b -= divide;
                f2 = !f2;
            }

            if (--ch > 0)
            {
                if (f1 && f2) best = Math.Max(Math.Max(best, divide - Math.Max(l, a)), Math.Min(r, b));
                if (f1 && !f2)
                {
                    best = MaxSubstring(best, l, divide - 1, a, b, ch);
                    best = MaxSubstring(best, 1, r, a, b, ch);
                }
                if (!f1 && f2)
                {
                    best = MaxSubstring(best, l, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, r, 1, b, ch);
                }
                if (!f1 && !f2) best = MaxSubstring(best, l, r, a, b, ch);
                if (f1 && f2)
                {
                    best = MaxSubstring(best, 1, r, a, divide - 1, ch);
                    best = MaxSubstring(best, l, divide - 1, 1, b, ch);
                }
            }

            return best;
        }

        void Solve()
        {
            long l1, r1, l2, r2;
            Input.Next(out l1, out r1, out l2, out r2);
            var n = MaxSubstring(0, l1, r1, l2, r2, 29);
            Console.WriteLine(n);
        }
    }
}