import std.stdio, std.algorithm, std.string, std.conv, std.array, std.range, std.math;
int[] readints() { return readln.split.to!(int[]); }


void main() {
    auto a = readints();

    auto q = new Queue!(int[]);
    q.push(a ~ 0);
    int ans = 0;
    while (1) {
        auto t = q.front();
        if (t[0] == t[1] && t[1] == t[2]) {
            ans = t[3];
            break;
        }
        q.pop();
        t[3] += 1;
        // +2
        auto tt = t.dup; // 参照になってしまうから dup が必要
        tt[t[0..3].minIndex] += 2;
        q.push(tt);
        if (t[0..3].maxElement - t[0..3].minElement > 3) continue;
        // +1
        q.push([t[0] + 1, t[1] + 1, t[2] + 0, t[3]]);
        q.push([t[0] + 1, t[1] + 0, t[2] + 1, t[3]]);
        q.push([t[0] + 0, t[1] + 1, t[2] + 1, t[3]]);
    }
    writeln(ans);
}

class Queue(T) {
    T[] queue;
    this() { }
    T front(){
        return queue[0];
    }
    void pop(){
        queue = queue[1..$];
    }
    void push(T x){
        queue ~= x;
    }
    int size(){
        return queue.length;
    }
}