#include <bits/stdc++.h>
//#define inf 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f3f
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define inv(x) Power(x, mod - 2)
#define fi first
#define se second
#define MP make_pair
#define PB push_back

typedef std::vector<int> Poly;
typedef std::pair<int,int> Pair;
typedef unsigned long long ull;
typedef long double ld;
typedef long long ll;

const int maxn = 1000000, maxm = 1e5, MAX = 1e6 + 5, mod = 998244353;
//template{{{
const long double Pi = 3.14159265358979323846l, Eps = 1e-4;
template <class T> inline bool equal(T x, T y) { return fabs(x - y) < Eps; }
inline int add(int x, int y) { x += y; return x >= mod ? x - mod : x; };
inline void inc(int &x, int y) { x += y; x -= (x >= mod ? mod : 0); }
inline int mul(int x, int y) { return 1ll * x * y % mod; }
inline int Power(int x, int y, int Mod = mod) {
	int ans = 1;
	while (y) {
		if (y & 1) ans = (ll) ans * x % Mod;
		x = (ll) x * x % Mod, y >>= 1;
	} return ans;
}

/*char buf[1<<23],obuf[1<<23],*p1=buf,*p2=buf, *O = obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
void print(int x) {
    if(x > 9) print(x / 10);
    *O++=x%10+'0';
} */

template <class T> inline T	input() {
	T x; char ch; bool flag = false;
	while (!isdigit(ch = getchar())) flag |= ch == '-';
	for (x = ch ^ 48; isdigit(ch = getchar()); x = x * 10 + (ch ^ 48));
	return flag ? -x : x;
}

template <class T> inline bool chkmin(T &x, T y) { x = x < y ? x : y; return x == y; }
template <class T> inline bool chkmax(T &x, T y) { x = x > y ? x : y; return x == y; }
template <class T> inline T gcd(T x, T y) { return !y ? x : gcd(y, x % y); }
template <class T> inline T sqrm(T x) { return (ll) x * x % mod; }
template <class T> inline T sqr(T x) { return x * x; }

struct _{
	inline operator int () { return input<int>(); }
	inline operator long long () { return input<long long>(); }
	template <class T> inline void operator () (T &x) { x = *this; }
	template<class T, class ...A> inline void operator () (T &x, A &...a)
	{ x = *this; this -> operator ()(a...); }
} read; //}}}

int n;
char s[maxn + 5];
int l0[maxn + 5], r0[maxn + 5], l1[maxn + 5], r1[maxn + 5];
std::set<int> S;

int pre(int p) {
	auto it = S.lower_bound(p);
	if (it == S.begin()) return 0;
	return *--it;
}

int nxt(int p) {
	auto it = S.upper_bound(p);
	if (it == S.end()) return 0;
	return *it;
}

int c[maxn + 5];

void Add(int p, int v) {
	for (int i = p; i <= maxn; i += i & -i)
		c[i] += v;
}

int query(int p) {
	int res = 0;
	for (int i = p; i; i ^= i & -i)
		res += c[i];
	return res;
}

int query(int l, int r) {
	if (l && l <= r) return query(r) - query(l - 1);
	else return 0;
}

signed main() {
#ifdef local
	freopen("in", "r", stdin);
	freopen("out", "w", stdout);
	freopen("log", "w", stderr);
#endif

	scanf("%s", s + 1);
	n = strlen(s + 1);


	for (int i = 1; i <= n; ++i)
		if (s[i] == '?') S.insert(i);
		else if (s[i] == '1') Add(i, 1);
		else Add(i, -1);

	int s0 = 0, s1 = 0;
	for (int i = 1; i <= n; ++i) {
		if (s[i] == '0') { ++s0; if (s1) --s1; }
		else if (s[i] == '1') { ++s1; if (s0) --s0; }
		else l0[i] = s0, l1[i] = s1, s0 = s1 = 0;
	}

	s0 = 0, s1 = 0;
	for (int i = n; i; --i) {
		if (s[i] == '0') { ++s0; if (s1) --s1; }
		else if (s[i] == '1') { ++s1; if (s0) --s0; }
		else r0[i] = s0, r1[i] = s1, s0 = s1 = 0;
	}

	#define Push(i) que.push(Pair(abs((l0[i] + r0[i]) - (l1[i] + r1[i])), i))
	std::priority_queue<Pair> que;
	for (int i = 1; i <= n; ++i)
		if (s[i] == '?' && (s[i - 1] != '?' || s[i + 1] != '?'))
			Push(i);

	while (!que.empty()) {
		int u = que.top().second; que.pop();
		if (s[u] != '?') continue;
		if (l0[u] + r0[u] > l1[u] + r1[u]) s[u] = '1', Add(u, 1);
		else s[u] = '0', Add(u, -1);
		int l = pre(u), r = nxt(u);
		chkmax(r0[l], -query(l, u) + r0[u]);
		chkmax(r1[l], query(l, u) + r1[u]), Push(l);
		chkmax(l0[r], -query(u, r) + l0[u]);
		chkmax(l1[r], query(u, r) + l1[u]), Push(r);
		S.erase(u);
	}

	int res = 0; s0 = s1 = 0;
	for (int i = 1; i <= n; ++i) {
		if (s[i] == '0') { chkmax(res, ++s0); if (s1) --s1; }
		else if (s[i] == '1') { chkmax(res, ++s1); if (s0) --s0; }
	}

	printf("%d\n", res);
	return 0;
}


Measured memory_bytes: 71064