#include <bits/stdc++.h>
using namespace std;
template <class T>
ostream& operator<<(ostream& os, vector<T> v) {
  for (long long i = (0); i < ((long long)(v).size()); i++)
    os << (i ? " " : "") << v[i];
  return os;
}
const bool debug = 1;
string s;
long long l[1000000];
long long r[1000000];
bool visited[1000000];
signed main() {
  cin >> s;
  for (long long i = 0; i < (long long)(s).size(); i++) {
    l[i] = i - 1;
    r[i] = i + 1;
  }
  vector<long long> q;
  for (long long i = 1; i < (long long)(s).size(); i++) {
    if (s[i] != s[i - 1]) {
      visited[i] = true;
      q.push_back(i);
      if (i == 1) q.push_back(i - 1), visited[i - 1] = true;
    }
  }
  long long ans = 0;
  while (!q.empty()) {
    vector<long long> nq;
    long long start = 0;
    for (long long i = 0; i < (long long)(q).size() - 1; i++) {
      if (r[q[i]] != q[i + 1]) {
        if (l[q[start]] >= 0) r[l[q[start]]] = r[q[i]];
        if (r[q[i]] < (long long)(s).size()) l[r[q[i]]] = l[q[start]];
        if (l[q[start]] >= 0 && r[q[i]] < (long long)(s).size()) {
          if (l[q[start]] >= 0 && r[q[i]] < (long long)(s).size()) {
            if (s[l[q[start]]] != s[r[q[i]]]) {
              if (!visited[l[q[start]]])
                visited[l[q[start]]] = true, nq.push_back(l[q[start]]);
              if (!visited[r[q[i]]])
                visited[r[q[i]]] = true, nq.push_back(r[q[i]]);
            }
          }
        }
        start = i + 1;
      }
    }
    long long m = (long long)(q).size() - 1;
    if (l[q[start]] >= 0) r[l[q[start]]] = r[q[m]];
    if (r[q[m]] < (long long)(s).size()) l[r[q[m]]] = l[q[start]];
    if (l[q[start]] >= 0 && r[q[m]] < (long long)(s).size()) {
      if (s[l[q[start]]] != s[r[q[m]]]) {
        if (!visited[l[q[start]]])
          visited[l[q[start]]] = true, nq.push_back(l[q[start]]);
        if (!visited[r[q[m]]]) visited[r[q[m]]] = true, nq.push_back(r[q[m]]);
      }
    }
    q = nq;
    ans++;
  }
  cout << ans << endl;
  return 0;
}
