import java.util.*;
import java.io.*;
public class D {
  
  static InputReader in = new InputReader(System.in);
  static PrintWriter out = new PrintWriter(System.out);
  
  public static void main(String[] args) {
    char[] points = in.next().toCharArray();
    int n = points.length;
    Set<Integer> q = new HashSet<Integer>();
    int[] next = new int[n];
    int[] prev = new int[n];
    for (int i = 0; i < n; i++) {
      next[i] = i+1;
      prev[i] = i-1;
    }
    next[n-1] = -1;
    for (int i = 0; i < n; i++) {
      if ((i < n-1 && points[i] != points[i+1]) || (i > 0 && points[i] != points[i-1])) {
        q.add(i);
      }
    }
    Set<Integer> q2 = new HashSet<Integer>();
    int sol = 0;
    while (!q.isEmpty()) {
      //out.println(q.toString());
      for (int p : q) {
        boolean nex = next[p] != -1;
        boolean pex = prev[p] != -1;
        if (nex && pex && points[prev[p]] != points[next[p]]) {
          q2.add(prev[p]);
          q2.add(next[p]);
        } else {
          if (!pex || prev[prev[p]] == -1 || points[prev[prev[p]]] == points[prev[p]])
            q2.remove(prev[p]);
          if (!nex || next[next[p]] == -1 || points[next[next[p]]] == points[next[p]])
            q2.remove(next[p]);
        }
        q2.remove(p);
        if (pex)
          next[prev[p]] = next[p];
        if (nex)
          prev[next[p]] = prev[p];
      }
      q = q2;
      q2 = new HashSet<Integer>();
      sol++;
    }
    out.println(sol);
    finish();
  }
  
  public static void finish() {
    out.close();
    in.close();
    System.exit(0);
  }

  static class InputReader implements Iterator<String>, Closeable {
    // Fast input reader. Based on Kattio.java from open.kattis.com
    // but has method names to match Scanner

    private BufferedReader r;
    private String line;
    private StringTokenizer st;
    private String token;

    public InputReader(InputStream i) {
      r = new BufferedReader(new InputStreamReader(i));
    }

    public boolean hasNext() {
      return peekToken() != null;
    }

    public int nextInt() {
      return Integer.parseInt(nextToken());
    }

    public double nextDouble() {
      return Double.parseDouble(nextToken());
    }

    public long nextLong() {
      return Long.parseLong(nextToken());
    }

    public String next() {
      return nextToken();
    }
    
    public String nextLine() {
      try {
        line = r.readLine();
      } catch (IOException e) {
        line = null;
      }
      token = null;
      st = null;
      return line;
    }
    
    public void close() {
      try {
        r.close();
      } catch (IOException e) {
      }
    }

    private String peekToken() {
      if (token == null)
        try {
          while (st == null || !st.hasMoreTokens()) {
            line = r.readLine();
            if (line == null)
              return null;
            st = new StringTokenizer(line);
          }
          token = st.nextToken();
        } catch (IOException e) {
        }
      return token;
    }

    private String nextToken() {
      String ans = peekToken();
      token = null;
      return ans;
    }
    
  }

}