#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0; i<(n); i++)
using P = pair<int,int>;
constexpr int INF = 1e9+7, e2 = 0;
constexpr P e1 = {INF,-INF};
inline P marge(P ch1, P ch2){
	return {min(ch1.first, ch2.first), max(ch1.second, ch2.second)};
}
struct SegTree{
	int sz;
	vector<P> dat;
	vector<int> del;
	SegTree(char* s){
		int n = strlen(s)+1, t = 0;
		for(sz = 2; sz < n; sz *= 2);
		dat.assign(sz*2, e1);
		del.assign(sz*2, e2);
		rep(i,n){
			dat[i+sz] = {t, t};
			t += s[i] == '0' ? -1 : 1;
		}
		for(int i=sz-1; i>0; i--) dat[i] = marge(dat[i*2], dat[i*2+1]);
	}
	void add2(int k, int x){
		del[k] += x;
		dat[k].first += x;
		dat[k].second += x;
	}
	void prop(int k){
		if(k<sz){
			add2(k*2,del[k]);
			add2(k*2+1,del[k]);
		}
		del[k] = 0;
	}
	void add(int a, int b, int x, int k, int l, int r){
		if(r <= a || b <= l) return;
		if(a <= l && r <= b){
			add2(k,x);
			return;
		}
		prop(k);
		add(a, b, x, k*2, l, (l+r)/2);
		add(a, b, x, k*2+1, (l+r)/2, r);
		dat[k] = marge(dat[k*2], dat[k*2+1]);
	}
	void add(int a, int b, int x){add(a,b,x,1,0,sz);}
	P query(int a, int b, int k, int l, int r){
		if(r <= a || b <= l) return {INF,-INF};
		if(a <= l && r <= b) return dat[k];
		prop(k);
		return dat[k] = marge(query(a, b, k*2, l, (l+r)/2), query(a, b, k*2+1, (l+r)/2, r));
	}
	P query(int a, int b){return query(a,b,1,0,sz);}
};
int n;
char s[1000005];
int main(){
	scanf("%s", s);
	SegTree sg(s);
	n = strlen(s)+1;
	auto [mn, mx] = sg.query(0,n);
	rep(i,n-1) if(s[i] == '?'){
		sg.add(i+1, n, -2);
		auto [mn2, mx2] = sg.query(0,n);
		if(mx2 - mn2 < mx - mn){
			mx = mx2; mn = mn2;
		}else sg.add(i+1, n, 2);
	}
	printf("%d\n", mx-mn);
	
}