#include <bits/stdc++.h>
using namespace std;
using ll = long long;
string S;
int res, treeadd[1 << 21];
pair<int, int> treemax[1 << 21], treemin[1 << 21];
void add(int l, int r, int p, int q, int k, int x) {
  if (q < l || r < p) {
    return;
  } else if (p <= l && r <= q) {
    treeadd[k] += x;
    treemax[k].first += x;
    treemin[k].first += x;
  } else {
    treemax[k + k].first += treeadd[k];
    treemax[k + k + 1].first += treeadd[k];
    treemin[k + k].first += treeadd[k];
    treemin[k + k + 1].first += treeadd[k];
    treeadd[k + k] += treeadd[k];
    treeadd[k + k + 1] += treeadd[k];
    treeadd[k] = 0;
    add(l, (l + r) / 2, p, q, k + k, x);
    add((l + r) / 2 + 1, r, p, q, k + k + 1, x);
    treemax[k] = max(treemax[k + k], treemax[k + k + 1]);
    treemin[k] = min(treemin[k + k], treemin[k + k + 1]);
  }
}
pair<int, int> calcmax(int l, int r, int p, int q, int k) {
  if (q < l || r < p)
    return {-1, -1};
  else if (p <= l && r <= q) {
    return treemax[k];
  } else {
    treemax[k + k].first += treeadd[k];
    treemax[k + k + 1].first += treeadd[k];
    treemin[k + k].first += treeadd[k];
    treemin[k + k + 1].first += treeadd[k];
    treeadd[k + k] += treeadd[k];
    treeadd[k + k + 1] += treeadd[k];
    treeadd[k] = 0;
    return max(calcmax(l, (l + r) / 2, p, q, k + k),
               calcmax((l + r) / 2 + 1, r, p, q, k + k + 1));
  }
}
pair<int, int> calcmin(int l, int r, int p, int q, int k) {
  if (q < l || r < p)
    return {0xE869120, 0xE869120};
  else if (p <= l && r <= q) {
    return treemin[k];
  } else {
    treemax[k + k].first += treeadd[k];
    treemax[k + k + 1].first += treeadd[k];
    treemin[k + k].first += treeadd[k];
    treemin[k + k + 1].first += treeadd[k];
    treeadd[k + k] += treeadd[k];
    treeadd[k + k + 1] += treeadd[k];
    treeadd[k] = 0;
    return min(calcmin(l, (l + r) / 2, p, q, k + k),
               calcmin((l + r) / 2 + 1, r, p, q, k + k + 1));
  }
}
int main() {
  cin >> S;
  pair<int, int> mx = {-1, -1};
  int lv = 0;
  for (int i = 0; i < S.size(); i++) {
    mx = max(mx, {lv, i});
    if (S[i] == '1')
      lv++;
    else
      lv--;
  }
  for (int i = 0; i < mx.second; i++) {
    if (S[i] == '?') S[i] = '0';
  }
  vector<int> v;
  for (int i = 0; i <= S.size(); i++) {
    treemax[(1 << 20) + i].second = treemin[(1 << 20) + i].second = -i;
  }
  for (int i = mx.second; i < S.size(); i++) {
    if (S[i] == '0') {
      add(0, (1 << 20) - 1, i + 1, S.size(), 1, -1);
    }
    if (S[i] == '1') {
      add(0, (1 << 20) - 1, i + 1, S.size(), 1, 1);
    }
    if (S[i] == '?') {
      add(0, (1 << 20) - 1, i + 1, S.size(), 1, -1);
      v.push_back(i);
    }
  }
  for (int i = 0; i < v.size(); i++) {
    add(0, (1 << 20) - 1, v[i] + 1, S.size(), 1, 1);
    if (calcmax(0, (1 << 20) - 1, v[i] + 1, S.size(), 1).first >= 0) {
      S[v[i]] = '0';
      add(0, (1 << 20) - 1, v[i] + 1, S.size(), 1, -1);
    } else {
      S[v[i]] = '1';
      add(0, (1 << 20) - 1, v[i] + 1, S.size(), 1, 1);
    }
  }
  lv = 0;
  int MN = 0, MX = 0;
  for (int i = 0; i < S.size(); i++) {
    if (S[i] == '1')
      lv++;
    else
      lv--;
    MN = min(MN, lv);
    MX = max(MX, lv);
  }
  cout << MX - MN << endl;
}
