#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 7, N = 1e6 + 7;
int n;
int p[N];
struct Max_Seg_Tree {
  pair<int, int> t[4 * N];
  int lazy[4 * N];
  void bld(int v = 1, int tl = 0, int tr = n) {
    lazy[v] = 0;
    if (tl == tr - 1) {
      t[v] = {p[tl], tl};
    } else {
      int tm = (tl + tr) / 2;
      bld(v * 2, tl, tm);
      bld(v * 2 + 1, tm, tr);
      t[v] = max(t[v * 2], t[v * 2 + 1]);
    }
  }
  void push(int v) {
    if (lazy[v]) {
      lazy[v * 2] += lazy[v];
      lazy[v * 2 + 1] += lazy[v];
      t[v * 2].first += lazy[v];
      t[v * 2 + 1].first += lazy[v];
      lazy[v] = 0;
    }
  }
  void upd(int l, int r, int add, int v = 1, int tl = 0, int tr = n) {
    if (l >= r) return;
    if (l == tl && r == tr) {
      t[v].first += add;
      lazy[v] += add;
      return;
    }
    push(v);
    int tm = (tl + tr) / 2;
    upd(l, min(r, tm), add, v * 2, tl, tm);
    upd(max(l, tm), r, add, v * 2 + 1, tm, tr);
    t[v] = max(t[v * 2], t[v * 2 + 1]);
  }
  pair<int, int> qry(int l, int r, int v = 1, int tl = 0, int tr = n) {
    if (l >= r) return {-INF, -INF};
    if (l == tl && r == tr) return t[v];
    push(v);
    int tm = (tl + tr) / 2;
    return max(qry(l, min(r, tm), v * 2, tl, tm),
               qry(max(l, tm), r, v * 2 + 1, tm, tr));
  }
} mxt;
struct Min_Seg_Tree {
  pair<int, int> t[4 * N];
  int lazy[4 * N];
  void bld(int v = 1, int tl = 0, int tr = n) {
    lazy[v] = 0;
    if (tl == tr - 1) {
      t[v] = {p[tl], tl};
    } else {
      int tm = (tl + tr) / 2;
      bld(v * 2, tl, tm);
      bld(v * 2 + 1, tm, tr);
      t[v] = min(t[v * 2], t[v * 2 + 1]);
    }
  }
  void push(int v) {
    if (lazy[v]) {
      lazy[v * 2] += lazy[v];
      lazy[v * 2 + 1] += lazy[v];
      t[v * 2].first += lazy[v];
      t[v * 2 + 1].first += lazy[v];
      lazy[v] = 0;
    }
  }
  void upd(int l, int r, int add, int v = 1, int tl = 0, int tr = n) {
    if (l >= r) return;
    if (l == tl && r == tr) {
      t[v].first += add;
      lazy[v] += add;
      return;
    }
    push(v);
    int tm = (tl + tr) / 2;
    upd(l, min(r, tm), add, v * 2, tl, tm);
    upd(max(l, tm), r, add, v * 2 + 1, tm, tr);
    t[v] = min(t[v * 2], t[v * 2 + 1]);
  }
  pair<int, int> qry(int l, int r, int v = 1, int tl = 0, int tr = n) {
    if (l >= r) return {INF, INF};
    if (l == tl && r == tr) return t[v];
    push(v);
    int tm = (tl + tr) / 2;
    return min(qry(l, min(r, tm), v * 2, tl, tm),
               qry(max(l, tm), r, v * 2 + 1, tm, tr));
  }
} mnt;
int solve(string s) {
  s = ' ' + s;
  n = s.size();
  set<int> tt;
  for (int i = 1; i < s.size(); i++) {
    p[i] = p[i - 1];
    if (s[i] == '1')
      p[i]++;
    else if (s[i] == '0')
      p[i]--;
    else
      tt.insert(i), p[i]--;
  }
  mnt.bld(), mxt.bld();
  int ans = INF;
  while (true) {
    pair<int, int> mx = mxt.qry(0, n), mn = mnt.qry(0, n);
    ans = min(ans, mx.first - mn.first);
    if (mn.second < mx.second) {
      break;
    } else {
      auto pos = tt.upper_bound(mx.second);
      if (pos == tt.end()) break;
      if (*pos > mn.second) break;
      if (*pos != mx.second + 1) {
        mnt.upd(*pos, n, 2);
        mxt.upd(*pos, n, 2);
        tt.erase(pos);
      } else {
        if (next(pos) != tt.end() && *next(pos) <= mn.second) ++pos;
        mnt.upd(*pos, n, 2);
        mxt.upd(*pos, n, 2);
        tt.erase(pos);
      }
    }
  }
  return ans;
}
int solve2(string s) {
  s = ' ' + s;
  n = s.size();
  set<int> tt;
  for (int i = 1; i < s.size(); i++) {
    p[i] = p[i - 1];
    if (s[i] == '1')
      p[i]++;
    else if (s[i] == '0')
      p[i]--;
    else
      tt.insert(i), p[i]--;
  }
  mnt.bld(), mxt.bld();
  int ans = INF;
  while (true) {
    pair<int, int> mx = mxt.qry(0, n), mn = mnt.qry(0, n);
    ans = min(ans, mx.first - mn.first);
    if (mn.second < mx.second) {
      break;
    } else {
      auto pos = tt.upper_bound(mx.second);
      if (pos == tt.end()) break;
      if (*pos > mn.second) break;
      if (next(pos) != tt.end() && *next(pos) <= mn.second) ++pos;
      mnt.upd(*pos, n, 2);
      mxt.upd(*pos, n, 2);
      tt.erase(pos);
    }
  }
  return ans;
}
signed main() {
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  ;
  string s;
  cin >> s;
  int ans = solve(s);
  ans = min(ans, solve2(s));
  cout << ans << endl;
}
