#include <bits/stdc++.h>
using namespace std;
template <typename T>
T max(T a_, T b_, T c_) {
  return max(a_, max(b_, c_));
}
template <typename T>
T min(T a_, T b_, T c_) {
  return min(a_, min(b_, c_));
}
const int maxn = 1000010;
string s;
set<int> st;
vector<int> todo;
int kdfnbfkd[maxn], klnjdfkbndf[maxn];
void apply() {
  vector<int> temp;
  temp = todo;
  todo.clear();
  for (int b : temp) st.erase(b);
  for (int b : temp) {
    auto it = st.lower_bound(b);
    int l = -1, r = -1;
    if (it != st.end()) r = *it;
    if (it != st.begin()) {
      it--, l = *it;
    }
    if (l == -1 and r == -1) continue;
    if (l == -1) {
      kdfnbfkd[r] = 0;
      if (kdfnbfkd[r] or klnjdfkbndf[r]) todo.push_back(r);
    }
    if (r == -1) {
      klnjdfkbndf[l] = 0;
      if (kdfnbfkd[l] or klnjdfkbndf[l]) todo.push_back(l);
    } else {
      klnjdfkbndf[l] = int(s[l] != s[r]);
      kdfnbfkd[r] = int(s[l] != s[r]);
      if (kdfnbfkd[l] or klnjdfkbndf[l]) todo.push_back(l);
      if (kdfnbfkd[r] or klnjdfkbndf[r]) todo.push_back(r);
    }
  }
  sort(todo.begin(), todo.end());
  todo.erase(unique(todo.begin(), todo.end()), todo.end());
}
int32_t main() {
  cin >> s;
  for (int i = 0; i < s.size(); i++) st.insert(i);
  for (int i = 0; i < s.size(); i++) {
    if (i != 0) kdfnbfkd[i] = int(s[i - 1] == s[i]);
    if (i != s.size() - 1) klnjdfkbndf[i] = int(s[i] != s[i + 1]);
    if (kdfnbfkd[i] or klnjdfkbndf[i]) todo.push_back(i);
  }
  int c = 0;
  while (!todo.empty()) {
    apply();
    c++;
  }
  cout << c << '\n';
  return 0;
}
