#include <bits/stdc++.h>
using ll = long long;
class SegmentTree {
 private:
  std::vector<std::pair<int, int>> aint;
  std::vector<int> lazy;

 public:
  SegmentTree(int n) {
    aint.resize(1 + 4 * n);
    lazy.resize(1 + 4 * n);
  }
  void cleannode(int node, int from, int to) {
    if (from < to) {
      int mid = (from + to) / 2;
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    aint[node].first += lazy[node];
    aint[node].second += lazy[node];
    lazy[node] = 0;
  }
  std::pair<int, int> join(std::pair<int, int> f1, std::pair<int, int> f2) {
    return {std::min(f1.first, f2.first), std::max(f1.second, f2.second)};
  }
  void update(int node, int from, int to, int x, int y, int val) {
    if (from == x && to == y) {
      lazy[node] += val;
      cleannode(node, from, to);
    } else {
      int mid = (from + to) / 2;
      cleannode(node * 2, from, mid);
      cleannode(node * 2 + 1, mid + 1, to);
      if (x <= mid)
        update(node * 2, from, mid, x, (((y) < (mid)) ? (y) : (mid)), val);
      if (mid + 1 <= y)
        update(node * 2 + 1, mid + 1, to, (((mid + 1) < (x)) ? (x) : (mid + 1)),
               y, val);
      aint[node] = join(aint[node * 2], aint[node * 2 + 1]);
    }
  }
  std::pair<int, int> query(int node, int from, int to, int x, int y) {
    cleannode(node, from, to);
    if (from == x && to == y)
      return aint[node];
    else {
      int mid = (from + to) / 2;
      if (x <= mid && y <= mid)
        return query(node * 2, from, mid, x, y);
      else if (mid + 1 <= x && mid + 1 <= y)
        return query(node * 2 + 1, mid + 1, to, x, y);
      else
        return join(query(node * 2, from, mid, x, mid),
                    query(node * 2 + 1, mid + 1, to, mid + 1, y));
    }
  }
};
int cost(std::pair<int, int> sol) { return sol.second - sol.first; }
int main() {
  std::string s;
  std::cin >> s;
  int n = s.size();
  s = "0" + s;
  SegmentTree aint(n);
  for (int i = 1; i <= n; i++) {
    int coef = 1;
    if (s[i] == '0') coef = -1;
    aint.update(1, 0, n, i, n, coef);
  }
  int result = cost(aint.query(1, 0, n, 0, n));
  int final_ = result;
  for (int i = 1; i <= n; i++) {
    if (s[i] == '?') {
      aint.update(1, 0, n, i, n, -2);
      int new_result = cost(aint.query(1, 0, n, 0, n));
      final_ = std::min(final_, new_result);
      if (new_result < result - 1)
        result = new_result;
      else
        aint.update(1, 0, n, i, n, 2);
    }
  }
  std::cout << final_;
}
