#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define endl "\n"

struct Node
{
    ll data = -1;
    Node *left, *right; // Pointers to left child and right child

    Node() // Constructor
    {
        data = -1;
        left = nullptr;
        right = nullptr;
    }
    Node(const ll &val)
    {
        data = val;
        left = nullptr;
        right = nullptr;
    }

    void createChildren() // Construct Childs
    {
        if (left == nullptr)
            left = new Node();
        if (right == nullptr)
            right = new Node();
    }
    ~Node() // Destructor. Notice the "~" character before the struct name.
    {
        delete left;
        delete right;
        left = nullptr;
        right = nullptr;
    }
};

class binaryTrie
{
private:
    Node *root = new Node();
    ll rootHeight = 32;
    Node *adjustedRoot = nullptr; // First diverging Node
    ll adjustedRootHeight = UINT_MAX;

public:
    void insert(ll x)
    {
        Node *currentNode = root;

        for (int k = 31; k >= 0; k--)
        {
            if (((x >> k) & 1) == 0) // curr bit is 0 - left
            {
                if (currentNode->left == nullptr)
                    currentNode->left = new Node();

                currentNode = currentNode->left;
            }
            else // curr bit is 1 - right
            {
                if (currentNode->right == nullptr)
                    currentNode->right = new Node();

                currentNode = currentNode->right;
            }
        }

        currentNode->data = x;
    }

    int getMin()
    {
        // Reconstruct value OR'ing with mask as go right
        // Always go left unless have to go right
        Node *currentNode = root;
        ll min = 0;
        for (ll mask = (1LL << 31); mask != 0; mask >>= 1)
        {
            if (currentNode->left)
                currentNode = currentNode->left;
            else
            {
                min |= mask;
                currentNode = currentNode->right;
            }
        }

        return min;
    }

    vector<ll> getMins()
    {
        vector<ll> mins;
        Node *currentNode = adjustedRoot->left;
        stack<Node *> treeStack;
        treeStack.push(currentNode);

        while (!treeStack.empty())
        {
            currentNode = treeStack.top();
            treeStack.pop();

            if (currentNode->data != -1)
                mins.push_back(currentNode->data);

            if (currentNode->left)
                treeStack.push(currentNode->left);

            if (currentNode->right)
                treeStack.push(currentNode->right);
        }

        return mins;
    }

    int getMax()
    {
        // Reconstruct value OR'ing with mask as go right
        // Always go right unless have to go left
        Node *currentNode = root;
        ll max = 0;
        for (ll mask = (1LL << 31); mask != 0; mask >>= 1)
        {
            if (currentNode->right)
            {
                max |= mask;
                currentNode = currentNode->right;
            }
            else
                currentNode = currentNode->left;
        }

        return max;
    }

    int getClosest(ll x)
    {
        // Reconstruct value OR'ing with mask as go right
        // Always go right unless have to go left
        Node *currentNode = root;
        ll closest = 0;

        for (ll mask = (1LL << 31); mask != 0; mask >>= 1)
        {
            ll applyMask = mask & x;
            if (applyMask) // we desire to go right in priority
            {
                if (currentNode->right)
                {
                    closest |= mask;
                    currentNode = currentNode->right;
                }
                else
                    currentNode = currentNode->left;
            }
            else // we desire to go to the left in priority
            {
                if (currentNode->left)
                    currentNode = currentNode->left;
                else
                {
                    closest |= mask;
                    currentNode = currentNode->right;
                }
            }
        }

        return closest;
    }

    bool setAdjustedRoot()
    {
        Node *currentNode = root;
        ll count = 0;

        // First node with both valid kiddoes
        while (currentNode->left == nullptr || currentNode->right == nullptr)
        {
            count++;

            if (count == rootHeight)
                return false;

            if (currentNode->left)
                currentNode = currentNode->left;
            else
                currentNode = currentNode->right;
        }

        adjustedRoot = currentNode;
        adjustedRootHeight = rootHeight - count;
        return true;
    }
};

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    ll N;
    // cin >> t;
    while (t--)
    {
        cin >> N;
        vector<ll> a(N);
        for (int i{}; i < N; i++)
            cin >> a[i];

        binaryTrie tree;

        // Insert Values
        for (const ll &x : a)
            tree.insert(x);

        bool set = tree.setAdjustedRoot();
        if (!set)
            return cout << 0, 0; // No adjustable root set, means only inserted same value, max Xor is 0

        ll treeMin = tree.getMin();
        ll treeMax = tree.getMax();

        // go left to right, 0 means bits align, stop at soon as we see a 1, means LCS
        ll diverge = treeMin ^ treeMax;
        ll countOnes = 31;

        ll mask = (1LL << 31);
        while ((mask & diverge) == 0)
        {
            countOnes--;
            mask >>= 1;
        }

        ll globalMin = LLONG_MAX;
        vector<ll> mins = tree.getMins();
        for (const ll &m : mins)
        {
            ll targetMax = m ^ mask;
            ll closestMax = tree.getClosest(targetMax);
            globalMin = min(globalMin, m ^ closestMax);
        }
        cout << globalMin;
    }
    return 0;
}
