#include <bits/stdc++.h>
using namespace std;
char S[1000001];
set<pair<int, int>> st;
set<pair<int, char>> points;
int N;
int val[1000001];
void update(int ind) {
  set<pair<int, char>>::iterator it = points.lower_bound({ind, 'a' - 1});
  int cnt = 0;
  char C = it->second;
  it++;
  if (it != points.end()) {
    if (C != it->second) cnt++;
  }
  it--;
  if (it != points.begin()) {
    it--;
    if (C != it->second) cnt++;
  }
  st.erase({-val[ind], ind});
  val[ind] = cnt;
  st.insert({-val[ind], ind});
}
int main() {
  scanf("%s", S);
  N = strlen(S);
  for (int i = 0; i < N; i++) {
    int cnt = 0;
    if (i > 0 && S[i] != S[i - 1]) cnt++;
    if (i + 1 < N && S[i] != S[i + 1]) cnt++;
    val[i] = cnt;
    points.insert({i, S[i]});
    st.insert({-cnt, i});
  }
  for (int ans = 0;; ans++) {
    vector<int> todo;
    vector<int> pos;
    for (set<pair<int, int>>::iterator it = st.begin(); it != st.end(); it++) {
      if (it->first < 0)
        todo.push_back(it->second);
      else
        break;
    }
    if (todo.empty()) {
      cout << ans << '\n';
      return 0;
    }
    for (int i = 0; i < todo.size(); i++) {
      points.erase({todo[i], S[todo[i]]});
      st.erase({-val[todo[i]], todo[i]});
    }
    set<int> toupdate;
    for (int i = 0; i < todo.size(); i++) {
      int X = todo[i];
      set<pair<int, char>>::iterator it = points.lower_bound({X, S[X]});
      if (it != points.end()) {
        update(it->first);
      }
      if (it != points.begin()) {
        it--;
        update(it->first);
      }
    }
  }
  return 0;
}
