#include <bits/stdc++.h>
using namespace std;
using ll = long long;
mt19937 rng(1234);
const int MAXN = 1e6 + 10;
const int INF = 1e9;
int n;
pair<int, int> tree[4 * MAXN];
int prop[4 * MAXN];
void build(vector<int> &a, int tv = 1, int tl = 0, int tr = n - 1) {
  if (tl == tr) {
    tree[tv] = {a[tr], tr};
  } else {
    int tm = (tl + tr) / 2;
    build(a, 2 * tv, tl, tm);
    build(a, 2 * tv + 1, tm + 1, tr);
    tree[tv] = min(tree[2 * tv], tree[2 * tv + 1]);
  }
}
void propagate(int tv) {
  if (prop[tv] != -INF) {
    prop[2 * tv] = prop[tv];
    tree[2 * tv] = {prop[tv], -1};
    prop[2 * tv + 1] = prop[tv];
    tree[2 * tv + 1] = {prop[tv], -1};
  }
  prop[tv] = -INF;
}
pair<int, int> get_min(int l, int r, int tv = 1, int tl = 0, int tr = n - 1) {
  if (l <= tl && tr <= r) return tree[tv];
  if (tr < l || r < tl) return {INF, -1};
  propagate(tv);
  int tm = (tl + tr) / 2;
  return min(get_min(l, r, 2 * tv, tl, tm),
             get_min(l, r, 2 * tv + 1, tm + 1, tr));
}
void update(int l, int r, int val, int tv = 1, int tl = 0, int tr = n - 1) {
  if (l <= tl && tr <= r) {
    tree[tv] = {val, -1};
    prop[tv] = val;
    return;
  }
  if (tr < l || r < tl) return;
  propagate(tv);
  int tm = (tl + tr) / 2;
  update(l, r, val, 2 * tv, tl, tm);
  update(l, r, val, 2 * tv + 1, tm + 1, tr);
  tree[tv] = min(tree[2 * tv], tree[2 * tv + 1]);
}
void update(int l, int r) { update(l, r, INF); }
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string s;
  cin >> s;
  n = s.size();
  vector<int> left(n, -1), right(n, -1);
  vector<int> next_left(n), next_right(n);
  vector<int> dir_left(n), dir_right(n);
  for (int i = 0; i < n; ++i) {
    next_left[i] = (n + i - 1) % n;
    dir_left[i] = s[(n + i - 1) % n];
    next_right[i] = (n + i + 1) % n;
    dir_right[i] = s[i];
  }
  vector<int> visible(n);
  auto go_visible = [&](int start, vector<int> &left, vector<int> &right,
                        vector<int> &next_left, vector<int> &dir_left) {
    vector<int> que({start});
    for (int j = next_left[start];; j = next_left[j]) {
      que.push_back(j);
      if (dir_left[j] != dir_left[start]) {
        break;
      }
    }
    left[start] = que.back();
    visible[start] += que.size();
    for (int i = 1; i < que.size(); ++i) {
      right[que[i]] = start;
      visible[que[i]] += que.size();
    }
  };
  for (int i = 0; i < n; ++i) {
    if (dir_left[i] == dir_right[i]) continue;
    go_visible(i, left, right, next_left, dir_left);
    go_visible(i, right, left, next_right, dir_right);
  }
  for (int i = 0; i < n; ++i) {
    visible[i] /= 2;
    if (dir_left[i] != dir_right[i]) {
      visible[i]--;
    }
    if (visible[i] == n + 1) {
      if (s.find("00") != -1 && s.find("11") != -1) {
        cout << 2;
      } else {
        cout << 1;
      }
      return 0;
    }
  }
  build(visible);
  fill(prop, prop + 4 * n, -INF);
  int res = 0;
  while (true) {
    auto mx = get_min(0, n - 1);
    if (mx.first == INF) {
      cout << res;
      return 0;
    }
    ++res;
    int idx = mx.second;
    int l = left[idx];
    int r = right[idx];
    if (l < idx) {
      update(l, idx);
    } else {
      update(0, idx);
      update(l, n - 1);
    }
    if (idx < r) {
      update(idx, r);
    } else {
      update(idx, n - 1);
      update(0, r);
    }
  }
}
