#include <bits/stdc++.h>
using namespace std;
inline long long max(long long a, long long b) { return (a > b) ? a : b; }
inline int min(int a, int b) { return (a < b) ? a : b; }
long long gcd(long long a, long long b) { return (b) ? gcd(b, a % b) : a; }
inline long long ab(long long a) { return (a > 0) ? a : -a; }
long long lcm(long long a, long long b) { return (a * b) / gcd(a, b); }
long long modpow(long long n, long long k, long long mod) {
  long long ans = 1;
  while (k > 0) {
    if (k & 1) ans = (ans * n) % mod;
    k >>= 1;
    n = (n * n) % mod;
  }
  return ans;
}
long long poww(long long n, long long k) {
  long long ans = 1;
  while (k > 0) {
    if (k & 1) ans = (ans * n);
    k >>= 1;
    n = (n * n);
  }
  return ans;
}
int myrandom(int i) { return rand() % i; }
vector<pair<char, long long> > V, V1;
string S;
int main() {
  ios::sync_with_stdio(false);
  cin >> S;
  long long count = 1;
  long long i, flag, k, ans = 0;
  for (i = 1; i < S.size(); i++) {
    if (S[i] == S[i - 1])
      count++;
    else {
      V.push_back(make_pair(S[i - 1], count));
      count = 1;
    }
  }
  V.push_back(make_pair(S[i - 1], count));
  flag = 1;
  while (flag) {
    ans++;
    flag = 0;
    V1.clear();
    for (i = 0; i < V.size(); i++) {
      V[i].second -= 2;
      if (i == 0 || i + 1 == V.size()) {
        V[i].second += 1;
      }
    }
    for (i = 0; i < V.size() && V[i].second <= 0; i++)
      ;
    V1.push_back(V[i]);
    k = 0;
    for (i++; i < V.size(); i++) {
      if (V[i].first == V1[k].first && V[i].second > 0) {
        V1[k].second += V[i].second;
      } else if (V[i].second > 0) {
        V1.push_back(V[i]);
        k++;
      }
    }
    V = V1;
    if (V.size() > 1) flag = 1;
  }
  cout << ans << endl;
  return 0;
}
