#include <bits/stdc++.h>
using namespace std;
int fastMax(int x, int y) { return (((y - x) >> (32 - 1)) & (x ^ y)) ^ y; }
int fastMin(int x, int y) { return (((y - x) >> (32 - 1)) & (x ^ y)) ^ x; }
const long long int MAXN = 1e6 + 5;
long long int n, pre[MAXN], nxt[MAXN];
char second[MAXN];
set<long long int> active;
void update(long long int idx) {
  if (idx <= 0 || idx > n) return;
  if (active.find(idx) != active.end()) active.erase(idx);
  if (pre[idx] != 0 && second[idx] != second[pre[idx]]) active.insert(idx);
  if (nxt[idx] != n + 1 && second[idx] != second[nxt[idx]]) active.insert(idx);
}
void solve() {
  string str;
  cin >> str;
  n = str.size();
  for (int i = (1); i <= (n); ++i) {
    second[i] = str[i - 1];
    pre[i] = i - 1;
    nxt[i] = i + 1;
  }
  for (int i = (1); i <= (n); ++i) {
    if (i >= 2 && second[i] != second[i - 1])
      active.insert(i), active.insert(i - 1);
  }
  for (long long int ops = 0; ops <= n; ops++) {
    if (!active.size()) {
      cout << ops;
      return;
    }
    vector<long long int> v;
    for (auto it : active) {
      v.push_back(it);
    }
    for (auto it : v) {
      long long int idx = it;
      active.erase(idx);
      long long int prev = pre[idx];
      long long int next = nxt[idx];
      pre[next] = prev;
      nxt[prev] = next;
      update(prev);
      update(next);
    }
  }
}
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  long long int t;
  t = 1;
  while (t--) solve();
}
