#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U>
using P = pair<T, U>;
template <class T>
using Heap = priority_queue<T>;
template <class T>
using heaP = priority_queue<T, vector<T>, greater<T>>;
template <class T, class U>
using umap = unordered_map<T, U>;
template <class T>
using uset = unordered_set<T>;
template <class T>
bool ChangeMax(T& a, const T& b) {
  if (a >= b) return false;
  a = b;
  return true;
}
template <class T>
bool ChangeMin(T& a, const T& b) {
  if (a <= b) return false;
  a = b;
  return true;
}
template <class T, size_t N, class U>
void Fill(T (&a)[N], const U& v) {
  fill((U*)a, (U*)(a + N), v);
}
template <class T>
istream& operator>>(istream& is, vector<T>& v) {
  for (auto& e : v) is >> e;
  return is;
}
vector<char> t;
string s;
int len;
int ans = 1001001001;
void Rec(int i, int v, int maxv, int minv) {
  if (maxv - minv >= ans) return;
  if (i == len) {
    ans = min(ans, maxv - minv);
    return;
  }
  if (s[i] == '0') {
    ChangeMin(minv, v - 1);
    Rec(i + 1, v - 1, maxv, minv);
  } else if (s[i] == '1') {
    ChangeMax(maxv, v + 1);
    Rec(i + 1, v + 1, maxv, minv);
  } else {
    Rec(i + 1, v - 1, maxv, min(minv, v - 1));
    Rec(i + 1, v + 1, max(maxv, v + 1), minv);
  }
}
int main() {
  cin >> s;
  len = (int)s.size();
  Rec(0, 0, 0, 0);
  cout << ans << endl;
  return 0;
}
