#include<bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
using B = bitset<16>;
string s;
vector<int> quest, kakko, minMax, cnt;
void print(const vector<int> &a) {
for (int x : a) cerr << " " << x;
cerr << endl;
}
vector<vector<int>> G;
vector<int> dpl, dpr;
int cur = 0, n = 0;
// [l, r) の木を構築
void calc(int now, int l = 0, int r = s.size()) {
int left = 0, right = 0;
if (s[l+1] == 'i') minMax[now] = 0;
else minMax[now] = 1;
// 辺の構築
if (s[l+4] == '?') {
cnt[now]++;
G[now].push_back(quest[l+4]);
}
else {
G[now].push_back(cur++); calc(cur-1, l+4, kakko[l+7]+1); cnt[now] += cnt[G[now][0]];
}
if (s[r-2] == '?') {
G[now].push_back(quest[r-2]); cnt[now]++;
}
else {
G[now].push_back(cur++); calc(cur-1, kakko[r-2]-3, r-1); cnt[now] += cnt[G[now][1]];
}
}
// dfsでとる値の計算
void dfs(int now) {
if (now < n) {
dpl[now] = 1; dpr[now] = 1; return;
}
dfs(G[now][0]); dfs(G[now][1]);
if (minMax[now] == 0) {
dpl[now] = min(dpl[G[now][0]], dpl[G[now][1]]);
dpr[now] = dpr[G[now][0]] + dpr[G[now][1]] - 1;
}
else {
dpl[now] = dpl[G[now][0]] + dpl[G[now][1]];
dpr[now] = max(dpr[G[now][0]] + cnt[G[now][1]], dpr[G[now][1]] + cnt[G[now][0]]);
}
}
int main() {
cin >> s;
if (s == "?") {
cout << 1 << endl; return 0;
}
quest.assign(s.size(), -1); kakko.assign(s.size(), -1);
stack<int> st;
rep(i, s.size()) {
if (s[i] == '?') {
quest[i] = n; n++;
}
else if (s[i] == '(') st.push(i);
else if (s[i] == ')') {
kakko[i] = st.top(); kakko[st.top()] = i; st.pop();
}
}
minMax.resize(n * 2 + 3, -1); G.resize(n * 2 + 3); cur = n + 1; // min 0 max 1
cnt.resize(n * 2 + 3, 0);
calc(n);
for (int i = 0; i < n; i++) cnt[i] = 1;
dpl.assign(n * 2 + 3, n + 1); dpr.assign(n * 2 + 3, -1);
dfs(n);
cout << dpr[n] - dpl[n] + 1 << endl;
}