import java.io.IOException;
import java.util.*;

public class Test {
    int readInt() {
        int ans = 0;
        boolean neg = false;
        try {
            boolean start = false;
            for (int c = 0; (c = System.in.read()) != -1; ) {
                if (c == '-') {
                    start = true;
                    neg = true;
                    continue;
                } else if (c >= '0' && c <= '9') {
                    start = true;
                    ans = ans * 10 + c - '0';
                } else if (start) break;
            }
        } catch (IOException e) {
        }
        return neg ? -ans : ans;
    }

    final int N = 1000_010;
    int[][] nb = new int[N][2];
    boolean[] removed = new boolean[N], updated = new boolean[N];
    int[] removes = new int[N], updates = new int[N];
    int nr = 0, nu = 0;
    char[] pts;
    int n;

    int[] setted = new int[3*N];

    void set(int p, int ll, int rr, int i, int v) {
        setted[p] += v;
        if (ll == rr) return;
        int mid = (ll + rr) >>> 1;
        if (i <= mid) set(p+p, ll, mid, i, v);
        else set(p+p+1, mid + 1, rr, i, v);
    }

    int next(int p, int ll, int rr, int i) {
        if (setted[p] == 0) return -1;
        if (ll == rr) return ll;
        int mid = (ll + rr) >>> 1;
        int ans = -1;
        if (i <= mid) ans = next(p+p, ll, mid, i);
        if (ans < 0) ans = next(p+p+1, mid+1, rr, mid+1);
        return ans;
    }

    int prev(int p, int ll, int rr, int i) {
        if (setted[p] == 0) return -1;
        if (ll == rr) return ll;
        int mid = (ll + rr) >>> 1;
        int ans = -1;
        if (i >= mid + 1) ans = prev(p+p+1, mid+1, rr, i);
        if (ans < 0) ans = prev(p+p, ll, mid, mid);
        return ans;
    }

    void add(int[] a, int i) {
        a[1] = a[0];
        a[0] = i;
    }
    void remove(int i) {
        if (!removed[i]) {
            removes[nr++] = i;
            removed[i] = true;
        }
    }

    void update(int i) {
        if (!updated[i]) {
            updates[nu++] = i;
            updated[i] = true;
        }
    }

    Scanner sca = new Scanner(System.in);
    void start() {
        pts = sca.nextLine().toCharArray();
        n = pts.length;
        for (int i = 0; i < n; i++) nb[i][0] = -1;
        for (int i = 0; i < n; i++) {
            set(1, 0, n, i, 1);
            if (i < n - 1) {
                add(nb[i], i+1);
                add(nb[i+1], i);
                if (pts[i] != pts[i + 1]) {
                    remove(i);
                    remove(i + 1);
                }
            }
        }
        int ans = 0;
        while (nr > 0) {
            ans++;
            nu = 0;
            for (int k = 0; k < nr; k++) {
                int i = removes[k];
                for (int j : nb[i])
                    if (j >= 0) updated[j] = false;
            }
            for (int k = 0; k < nr; k++) {
                int i = removes[k];
                for (int j : nb[i])
                    if (j >= 0 && !removed[j]) update(j);
                set(1, 0, n, i, -1);
            }
            for (int k = 0; k < nu; k++) {
                int i = updates[k];
                nb[i][0] = -1;
                int low = (i == 0 ? -1 : prev(1, 0, n, i-1)),
                        high = (i == n - 1 ? - 1 : next(1, 0, n, i+1));
                if (low >= 0) add(nb[i], low);
                if (high <= 0) add(nb[i], high);
            }
            nr = 0;
            loop:
            for (int k = 0; k < nu; k++) {
                int i = updates[k];
                for (int j : nb[i]) {
                    if (j >= 0 && pts[i] != pts[j]) {
                        remove(i);
                        continue loop;
                    }
                }
            }
        }
        System.out.println(ans);
    }

    public static void main(String[] args) {

        new Test().start();

    }
}