#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define DEBUG(...)
#endif

template <class T> constexpr T inf = numeric_limits<T>::max() / 2.1;

auto chmin = [](auto&& a, auto b) { return b < a ? a = b, 1 : 0; };
auto chmax = [](auto&& a, auto b) { return a < b ? a = b, 1 : 0; };

pair<int, int> f(const string& s) {
  int mn = 0, mx = 0;
  int t = 0, mnt = 0, mxt = 0;
  for (auto c : s) {
    if (c == '0') {
      ++t;
    } else {
      --t;
    }
    mn = min(mn, t - mxt);
    mx = max(mx, t - mnt);
    mnt = min(mnt, t);
    mxt = max(mxt, t);
  }
  return {mn, mx};
}

int solve(string s) {
  int n = size(s);
  auto s0 = s;
  for (auto&& e : s0) {
    if (e == '?') {
      e = '0';
    }
  }
  int a = -f(s0).first;
  auto s1 = s;
  for (auto&& e : s1) {
    if (e == '?') {
      e = '1';
    }
  }
  int b = f(s1).second;
  int x = max(a, b);
  vector<bool> need0(n);
  {
    vector<int> mn(n + 1), mx(n + 1);
    for (int i = n; i--; ) {
      if (s0[i] == '0') {
        chmin(mn[i], mn[i + 1] + 1);
      } else {
        chmin(mn[i], mn[i + 1] - 1);
      }
    }
    for (int i = 0; i < n; ++i) {
      if (s0[i] == '0') {
        chmax(mx[i + 1], mx[i] - 1);
      } else {
        chmax(mx[i + 1], mx[i] + 1);
      }
    }
    for (int i = 0; i < n; ++i) {
      if (s[i] != '?') continue;
      need0[i] = mx[i] - mn[i + 1] + 1 > x;
    }
  }
  vector<bool> need1(n);
  {
    vector<int> mn(n + 1), mx(n + 1);
    for (int i = n; i--; ) {
      if (s1[i] == '0') {
        chmax(mx[i], mx[i + 1] + 1);
      } else {
        chmax(mx[i], mx[i + 1] - 1);
      }
    }
    for (int i = 0; i < n; ++i) {
      if (s1[i] == '0') {
        chmin(mn[i + 1], mn[i] - 1);
      } else {
        chmin(mn[i + 1], mn[i] + 1);
      }
    }
    for (int i = 0; i < n; ++i) {
      if (s[i] != '?') continue;
      need1[i] = mx[i + 1] - mn[i] + 1 > x;
    }
  }
  for (int i = 0; i < n; ++i) {
    if (need0[i] and need1[i]) {
      return x + 1;
    }
    if (need0[i]) {
      s[i] = '0';
    }
    if (need1[i]) {
      s[i] = '1';
    }
  }
  if (s.find('?') == string::npos) {
    auto [mn, mx] = f(s);
    return max(-mn, mx);
  }
  auto g = [&](int mi) {
    int res = 0;
    {
      int t = 0, mnt = 0;
      for (int i = mi; i < n; ++i) {
        if (s[i] == '0') {
          ++t;
        } else if (s[i] == '1') {
          --t;
        } else {
          if (t == mnt) {
            ++t;
          } else {
            --t;
          }
        }
        chmax(res, t - mnt);
        chmin(mnt, t);
      }
    }
    {
      int t = 0, mnt = 0;
      for (int i = mi; i--; ) {
        if (s[i] == '0') {
          --t;
        } else if (s[i] == '1') {
          ++t;
        } else {
          if (t == mnt) {
            ++t;
          } else {
            --t;
          }
        }
        chmax(res, t - mnt);
        chmin(mnt, t);
      }
    }
    return res;
  };
  vector<int> h(n + 1);
  for (int i = 0; i < n; ++i) {
    h[i + 1] = h[i];
    h[i + 1] += s[i] == '0';
    h[i + 1] -= s[i] == '1';
  }
  int mi = min_element(begin(h), end(h)) - begin(h);
  int res = g(mi);
  for (int i = n; i--; ) {
    if (h[i] == h[mi]) {
      chmin(res, g(i));
      break;
    }
  }
  return res;
}

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  string s;
  cin >> s;
  int res = solve(s);
  reverse(begin(s), end(s));
  chmax(res, solve(s));
  cout << res << endl;
}
