#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &t) {
	t=0; char ch=getchar(); int f=1;
	while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
	do { (t*=10)+=ch-'0'; ch=getchar(); } while ('0'<=ch&&ch<='9'); t*=f;
}
const int maxn=(1e6)+10;
const int INF=(1e9);
int n,sum[maxn],mx[maxn];
char s[maxn];

int solve(int mid) {
	int mn=0,now=0,mxx=0;
	for (int i=1;i<=n;i++) {
		if (s[i]=='?') {
			if (mx[i]+2+now<=mid) {
				now+=2;
			}
		}
		mn=min(mn,sum[i]+now);
		mxx=max(mxx,sum[i]+now);
	}
	if (mxx>mid) return INF;
	return mid-mn;
}
int main() {
	//freopen("1.txt","r",stdin);
	scanf("%s",s+1);
	n=strlen(s+1);
	for (int i=1;i<=n;i++) {
		sum[i]=sum[i-1];
		if (s[i]=='1') sum[i]++;
		else sum[i]--;
	}
	mx[n]=sum[n];
	for (int i=n-1;i>=1;i--)
		mx[i]=max(mx[i+1],sum[i]);
	//for (int i=0;i<=n;i++) printf("%d ",solve(i)); printf("\n");
	int l=0,r=n-1,res=n,mid,ans=2*n;
	while (l<=r) {
		mid=(l+r)/2;
		if (solve(mid)<solve(mid+1)) r=mid-1,res=mid;
		else l=mid+1;
	}
	for (int i=res-10;i<=res+10;i++)
		if (0<=i&&i<=n) ans=min(ans,solve(i));
	printf("%d\n",ans);
	return 0;
}
/*
  0. Enough array size? Enough array size? Enough array size? Interger overflow?
  
  1. Think TWICE, Code ONCE!
  Are there any counterexamples to your algo?
    
  2. Be careful about the BOUNDARIES!
  N=1? P=1? Something about 0?
    
  3. Do not make STUPID MISTAKES!
  Time complexity? Memory usage? Precision error?
*/