#include <bits/stdc++.h>
#define lint long long
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define MP make_pair
using namespace std;

// cout << fixed << setprecision(12)

int main(){
  string S;
  cin >> S;
  lint L = S.size();
  vector<lint> score(L+1, 0); // i文字目(1-index)までの(1の個数)-(0の個数)
  lint deka = 0;
  lint tibi = 0;
  vector<lint> dek(0); // かたまりごと
  vector<lint> tib(0);
  vector<lint> las(0);
  
  if(S[0]=='?'){
    char ltr = '?';
    lint cnt = 0; // ?が連続する個数
    while(ltr != '?'){
      cnt++;
      ltr = S[cnt];
    }
    if(cnt % 2 == 0){ // even ?s
      if(ltr = '1'){
        for(lint i=0; i<cnt; i++){
          lint tmp = (i+1) % 2; // 1 0 1 0 ...
          string tmp2 = to_stirng(tmp);
          S[i] = tmp2[0]; // string -> char
        }
      }else{ // 0
        for(lint i=0; i<cnt; i++){
          lint tmp = i % 2; // 0 1 0 1 ...
          string tmp2 = to_stirng(tmp);
          S[i] = tmp2[0]; // string -> char
        }
      }
    }else{ // odd ?s
      if(ltr = '1'){
        for(lint i=0; i<cnt; i++){
          lint tmp = i % 2; // 0 1 0 1 ...
          string tmp2 = to_stirng(tmp);
          S[i] = tmp2[0]; // string -> char
        }
      }else{ // 0
        for(lint i=0; i<cnt; i++){
          lint tmp = i % 2; // 1 0 1 0 ...
          string tmp2 = to_stirng(tmp);
          S[i] = tmp2[0]; // string -> char
        }
      }
    }
  } // ?から始まるときの処理　おわり
  
  for(lint k=0; k<L; k++){
    if(S[k]=='1'){
      score[k+1] = score[k] + 1;
      deka = max(score[k+1], deka);
    }
    if(S[k]=='0'){
      score[k+1] = score[k] - 1;
      tibi = min(score[k-1], tibi);
    }
    if(s[k]=='?'){ // score[k]までは決まってる
      char ltr = '?';
      lint cnt = 0; // ?が連続する個数
      while(ltr != '?'){
        cnt++;
        ltr = S[k + cnt];
      }
      if(cnt == 1){ // リセットする
        dek.PB(deka);
        tib.PB(tibi);
        las.PB(score[k]);
        deka = 0;
        tibi = 0;
        continue;
      }
      if(deka == tibi){ // リセット後
        if(cnt % 2 == 0){ // even ?s
          if(ltr = '1'){
            for(lint i=0; i<cnt; i++){
              lint tmp = (i+1) % 2; // 1 0 1 0 ...
              string tmp2 = to_stirng(tmp);
              S[i] = tmp2[0]; // string -> char
            }
          }else{ // 0
            for(lint i=0; i<cnt; i++){
              lint tmp = i % 2; // 0 1 0 1 ...
              string tmp2 = to_stirng(tmp);
              S[i] = tmp2[0]; // string -> char
            }
          }
        }else{ // odd ?s
          if(ltr = '1'){
            for(lint i=0; i<cnt; i++){
              lint tmp = i % 2; // 0 1 0 1 ...
              string tmp2 = to_stirng(tmp);
              S[i] = tmp2[0]; // string -> char
            }
          }else{ // 0
            for(lint i=0; i<cnt; i++){
              lint tmp = i % 2; // 1 0 1 0 ...
              string tmp2 = to_stirng(tmp);
              S[i] = tmp2[0]; // string -> char
            }
          }
        }
      }else{ // リセット後ではない
        if(cnt % 2 == 0){ // even ?s
          if(deka == score[k]){
            for(lint i=0; i<cnt; i++){
              lint tmp = i % 2; // 0 1 0 1 ...
              string tmp2 = to_stirng(tmp);
              S[k + i] = tmp2[0]; // string -> char
            }
          }else{ // tibiと等しい場合は1 0 1 0 ... それ以外はどっちでもよい
            for(lint i=0; i<cnt; i++){
              lint tmp = i % 2; // 1 0 1 0 ...
              string tmp2 = to_stirng(tmp);
              S[k + i] = tmp2[0]; // string -> char
            }
          }
        }else{ // odd ?s 最後1個の?以外は上と同じ
          if(deka == score[k]){
            for(lint i=0; i<cnt-1; i++){
              lint tmp = i % 2; // 0 1 0 1 ...
              string tmp2 = to_stirng(tmp);
              S[k + i] = tmp2[0]; // string -> char
            }
          }else{ // tibiと等しい場合は1 0 1 0 ... それ以外はどっちでもよい
            for(lint i=0; i<cnt-1; i++){
              lint tmp = i % 2; // 1 0 1 0 ...
              string tmp2 = to_stirng(tmp);
              S[k + i] = tmp2[0]; // string -> char
            }
          } 
        } // ?はあと1個
      }
    }
    if(S[k]=='1'){
      score[k+1] = score[k] + 1;
      deka = max(score[k+1], deka);
    }
    if(S[k]=='0'){
      score[k+1] = score[k] - 1;
      tibi = min(score[k-1], tibi);
    }
  } // かたまりごとのdek,tib,las計算おわり
  
  dek.PB(deka);
  tib.PB(tibi);
  las.PB(score[L]);
  
  lint N = dek.size();
  lint mdeka = dek[0];
  lint mtibi = tib[0];
  lint mlast = las[0];
  
  if(N==1){
    cout << mdeka - mtibi << endl;
    return 0;
  }

  for(lint i=1; i<N; i++){
    lint tmpdeka = mlast + dek[i];
    lint tmptibi = mlast + tib[i];
    
    if(tmpdeka > mdeka){
      mdeka = mlast + dek[i] - 1;
      mtibi = mlast + tib[i] - 1;
      mlast = mlast + las[i] - 1;
    }else{
       mdeka = mlast + dek[i] + 1;
      mtibi = mlast + tib[i] + 1;
      mlast = mlast + las[i] + 1;
    }
  }
  cout << mdeka - mtibi << endl;
}
      
    
    
    
  

        
        
           


        
  
      
  
        
        
      
      
      
    