#include <bits/stdc++.h>
using namespace std;
pair<int, int> ad(pair<int, int> p, int v) {
  p.first += v;
  return p;
}
int ad(int a, int v) { return a + v; }
template <typename T>
struct StarrySky {
  int n, n_org;
  T e;
  vector<T> dat;
  vector<int> added;
  typedef function<T(T a, T b)> Func;
  Func f;
  StarrySky() {}
  StarrySky(int n_input, Func f_input, T e_input) {
    initialize(n_input, f_input, e_input);
  }
  void initialize(int n_input, Func f_input, T e_input) {
    n_org = n_input;
    f = f_input;
    e = e_input;
    n = 1;
    while (n < n_input) n <<= 1;
    dat.assign(2 * n - 1, e);
    added.assign(2 * n - 1, 0);
  }
  void build(vector<T>& A) {
    for (int k = 0; k < int(A.size()); k++) dat[k + n - 1] = A[k];
    for (int k = n - 2; k >= 0; k--) dat[k] = f(dat[2 * k + 1], dat[2 * k + 2]);
  }
  void add_between(int a, int b, int x) { add(a, b + 1, x, 0, 0, n); }
  void add(int a, int b, int x, int k, int lb, int rb) {
    if (b <= lb || rb <= a) return;
    if (a <= lb && rb <= b) {
      added[k] += x;
    } else {
      int mb = (lb + rb) >> 1;
      add(a, b, x, 2 * k + 1, lb, mb);
      add(a, b, x, 2 * k + 2, mb, rb);
      dat[k] = f(ad(dat[2 * k + 1], added[2 * k + 1]),
                 ad(dat[2 * k + 2], added[2 * k + 2]));
    }
  }
  T between(int a, int b) { return query(a, b + 1, 0, 0, n); }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return e;
    if (a <= l && r <= b) return ad(dat[k], added[k]);
    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return ad(f(vl, vr), added[k]);
  }
};
int main() {
  string str;
  cin >> str;
  int N = str.size();
  vector<int> Q;
  vector<int> S(N + 1);
  for (int i = 0; i < N; i++) {
    S[i + 1] = S[i] + (str[i] == '1' ? 1 : -1);
    if (str[i] == '?') Q.push_back(i);
  }
  vector<pair<int, int>> SP(N + 1);
  for (int i = 0; i <= N; i++) SP[i] = {S[i], i};
  StarrySky<int> stmax(
      N + 1, [](int a, int b) { return max(a, b); }, -1e9);
  stmax.build(S);
  int mx = *max_element(S.begin(), S.end());
  vector<int> added(N + 1);
  for (int i : Q) {
    int now = stmax.between(i + 1, N);
    if (now + 2 <= mx) {
      added[i + 1] += 2;
      stmax.add_between(i + 1, N, 2);
    }
  }
  for (int i = 1; i <= N; i++) {
    added[i] += added[i - 1];
    S[i] += added[i];
  }
  int ans = mx - *min_element(S.begin(), S.end());
  cout << ans << endl;
  return 0;
}
