#include <bits/stdc++.h>
using namespace std;
inline bool EQ(double a, double b) { return fabs(a - b) < 1e-9; }
const int INF = (((1 << 30) - 1) << 1) + 1;
const int nINF = 1 << 31;
int main() {
  ios::sync_with_stdio(false);
  int ans = 1;
  set<pair<int, char> > p;
  set<pair<int, char> > nn, nnoth;
  set<pair<int, char> > rem;
  string s;
  cin >> s;
  if (s.size() == 1) {
    cout << 0 << endl;
    exit(0);
  }
  for (int i = 0; i < (s.size()); i++) p.insert({i, s[i]});
  auto next = p.begin(), cur = next++, prev = cur++;
  ++next;
  while (next != p.end()) {
    if (cur->second != prev->second) {
      rem.insert(*cur);
      rem.insert(*prev);
    }
    if (cur->second != next->second) {
      rem.insert(*cur);
      rem.insert(*next);
    }
    if (cur->second != prev->second && cur->second == next->second) {
      nn.insert(*next);
    }
    if (cur->second == prev->second && cur->second != next->second) {
      nn.insert(*prev);
    }
    prev = cur;
    cur = next;
    ++next;
  }
  if (cur->second != prev->second) {
    rem.insert(*cur);
    rem.insert(*prev);
  }
  if (rem.size() == 0) {
    cout << 0 << endl;
    return 0;
  }
  for (auto itr = rem.begin(); itr != rem.end(); ++itr) {
    nn.erase(*itr);
    p.erase(*itr);
  }
  rem.clear();
  set<pair<int, char> > *curSet = &nn, *nextSet = &nnoth;
  while (curSet->size()) {
    for (auto itr = curSet->begin(); itr != curSet->end(); ++itr) {
      auto pit = p.lower_bound(*itr);
      auto nextP = pit, prev = pit;
      ++nextP;
      if (pit != p.begin()) --prev;
      if (pit != p.begin()) {
        if (prev->second != pit->second) {
          rem.insert(*pit);
          rem.insert(*prev);
          if (nextP != p.end() && pit->second == nextP->second) {
            nextSet->insert(*nextP);
          }
        }
      }
      if (nextP != p.end()) {
        if (nextP->second != pit->second) {
          rem.insert(*pit);
          rem.insert(*nextP);
          if (pit != p.begin() && pit->second == prev->second) {
            nextSet->insert(*prev);
          }
        }
      }
    }
    if (rem.size() == 0) break;
    for (auto itr = rem.begin(); itr != rem.end(); ++itr) {
      nextSet->erase(*itr);
      p.erase(*itr);
    }
    ++ans;
    swap(curSet, nextSet);
    nextSet->clear();
    rem.clear();
  }
  cout << ans << endl;
  return 0;
}
