#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <vector>
#include <valarray>
#include <array>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <complex>
#include <random>

using namespace std;
typedef long long ll;

const int MN = 100100;

int lc = 0;
int l[MN], r[MN], p[MN], sz[MN];

int readtree(const string &s, int &c) {
    assert(s[c] == '(');
    c++;
    if (s[c] == ')') {
        c++;
        return -1;
    }
    int n = lc++;
    l[n] = readtree(s, c);
    r[n] = readtree(s, c);
    assert(s[c] == ')');
    c++;
    sz[n] = 1;
    if (l[n] != -1) {
        p[l[n]] = n;
        sz[n] += sz[l[n]];
    }
    if (r[n] != -1) {
        p[r[n]] = n;
        sz[n] += sz[r[n]];
    }
    return n;
}

int used[MN];
int uc = 0;

bool mark(int x, int y) {
    if (x == -1 || used[x] == uc) {
        if (y == -1) return true;
        return false;
    }
    if (y == -1) return false;
    used[x] = uc;
    return mark(l[x], l[y]) && mark(r[x], r[y]);
}

int dp[MN];
bool useddp[MN];

int solve(int n) {
    if (useddp[n]) return dp[n];
    useddp[n] = true;
    queue<int> q;
    vector<int> v;
    q.push(n);
    while (!q.empty()) {
        int m = q.front(); q.pop();
        v.push_back(m);
        if (l[m] != -1) {
            q.push(l[m]);
        }
        if (r[m] != -1) {
            q.push(r[m]);
        }
    }
    reverse(v.begin(), v.end());
    int ma = sz[n]-1;
    int S = sz[n];
    int m = v[0];
    int u = 0;
    while (n != m) {
        if (sz[n] % sz[m] == 0) {
            uc++;
            bool f = true;
            int fc = 0;
            for (int d: v) {
                if (used[d] != uc) {
                    int e = d;
                    for (int i = 0; i < u; i++) {
                        e = p[e];
                    }
                    if (!mark(e, m)) {
                        f = false;
                        break;
                    }
                    fc++;
                }
            }
            if (fc == sz[n] / sz[m] && f) {
                ma = min(ma, sz[n] / sz[m] - 1 + solve(m));
            }
        }
        u++;
        m = p[m];
    }
    return dp[n] = ma;
}

int main() {
    string s;
    cin >> s;
    int c = 0;
    p[0] = -1;
    readtree(s, c);
    cout << solve(0) << endl;
    return 0;
}
### Prompt

Please create a solution in CPP to the following problem:

You are a researcher investigating algorithms on binary trees. Binary tree is a data structure composed of branch nodes and leaf nodes. Every branch nodes have left child and right child, and each child is either a branch node or a leaf node. The root of a binary tree is the branch node which has no parent.

You are preparing for your presentation and you have to make a figure of binary trees using a software. You have already made a figure corresponding to a binary tree which is composed of one branch node and two leaf nodes (Figure 1.) However, suddenly the function of your software to create a figure was broken. You are very upset because in five hours you have to make the presentation in front of large audience.

You decided to make the figure of the binary trees using only copy function, shrink function and paste function of the presentation tool. That is, you can do only following two types of operations.

* Copy the current figure to the clipboard.

* The figure copied to the clipboard before is removed.

* Paste the copied figure (with shrinking, if needed), putting the root of the pasted figure on a leaf node of the current figure.

* You can paste the copied figure multiple times.




Moreover, you decided to make the figure using the minimum number of paste operations because paste operation is very time cosuming. Now, your job is to calculate the minimum possible number of paste operations to produce the target figure.

<image>

Figure 1: initial state

For example, the answer for the instance of sample 1(Figure 4) is 3, because you can produce the target figure by following operations and this is minimum.

<image>

Figure 2: intermediate 1

<image>

Figure 3: intermediate 2

<image>

Figure 4: Goal



Input

The input is a line which indicates a binary tree. The grammar of the expression is given by the following BNF.

> <tree> ::= <leaf> | "(" <tree> <tree> ")"
> <leaf> ::= "()"
>

Every input obeys this syntax. You can assume that every tree in the input has at least 1 branch node, and that it has no more than 10^5 branch nodes.

Output

A line containing the minimum possible number of paste operations to make the given binary tree.

Examples

Input

((()())(((()())(()()))()))


Output

3


Input

(((()())(()()))(()()))


Output

4


Input

((()(()()))((()(()()))()))


Output

3


Input

(()())


Output

0

### Response

```cpp
#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <vector>
#include <valarray>
#include <array>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <complex>
#include <random>

using namespace std;
typedef long long ll;

const int MN = 100100;

int lc = 0;
int l[MN], r[MN], p[MN], sz[MN];

int readtree(const string &s, int &c) {
    assert(s[c] == '(');
    c++;
    if (s[c] == ')') {
        c++;
        return -1;
    }
    int n = lc++;
    l[n] = readtree(s, c);
    r[n] = readtree(s, c);
    assert(s[c] == ')');
    c++;
    sz[n] = 1;
    if (l[n] != -1) {
        p[l[n]] = n;
        sz[n] += sz[l[n]];
    }
    if (r[n] != -1) {
        p[r[n]] = n;
        sz[n] += sz[r[n]];
    }
    return n;
}

int used[MN];
int uc = 0;

bool mark(int x, int y) {
    if (x == -1 || used[x] == uc) {
        if (y == -1) return true;
        return false;
    }
    if (y == -1) return false;
    used[x] = uc;
    return mark(l[x], l[y]) && mark(r[x], r[y]);
}

int dp[MN];
bool useddp[MN];

int solve(int n) {
    if (useddp[n]) return dp[n];
    useddp[n] = true;
    queue<int> q;
    vector<int> v;
    q.push(n);
    while (!q.empty()) {
        int m = q.front(); q.pop();
        v.push_back(m);
        if (l[m] != -1) {
            q.push(l[m]);
        }
        if (r[m] != -1) {
            q.push(r[m]);
        }
    }
    reverse(v.begin(), v.end());
    int ma = sz[n]-1;
    int S = sz[n];
    int m = v[0];
    int u = 0;
    while (n != m) {
        if (sz[n] % sz[m] == 0) {
            uc++;
            bool f = true;
            int fc = 0;
            for (int d: v) {
                if (used[d] != uc) {
                    int e = d;
                    for (int i = 0; i < u; i++) {
                        e = p[e];
                    }
                    if (!mark(e, m)) {
                        f = false;
                        break;
                    }
                    fc++;
                }
            }
            if (fc == sz[n] / sz[m] && f) {
                ma = min(ma, sz[n] / sz[m] - 1 + solve(m));
            }
        }
        u++;
        m = p[m];
    }
    return dp[n] = ma;
}

int main() {
    string s;
    cin >> s;
    int c = 0;
    p[0] = -1;
    readtree(s, c);
    cout << solve(0) << endl;
    return 0;
}
```