Problem:
Presentation
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.
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.
Figure 2: intermediate 1
Figure 3: intermediate 2
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.
Sample Input 1
((()())(((()())(()()))()))
Output for the Sample Input 1
3
Sample Input 2
(((()())(()()))(()()))
Output for the Sample Input 2
4
Sample Input 3
((()(()()))((()(()()))()))
Output for the Sample Input 3
3
Sample Input 4
(()())
Output for the Sample Input 4
0

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

char s[1000005];
int len;

int n;
int ch[400005][2], fa[400005], sz[400005], spec[400005];

int dp[400005];

void build() {
	int now = 1, tot = 1;
	for (int i = 2; i <= len - 1; ++i) {
		if (s[i] == ')') {
			sz[now] = sz[ch[now][0]] + sz[ch[now][1]] + 1;
			now = fa[now];
		}
		else {
			if (ch[now][0]) {
				ch[now][1] = ++tot;
				sz[tot] = 1;
				fa[tot] = now;
				now = tot;
			}
			else {
				ch[now][0] = ++tot;
				sz[tot] = 1;
				fa[tot] = now;
				now = tot;
			}
		}
	}
	sz[1] = sz[ch[1][0]] + sz[ch[1][1]] + 1;
	
	for (int i = 1; i <= tot; ++i)
		spec[sz[i]] = i;
	
	n = tot;
}

int vec[400005], head, tail;

bool same(int x, int y) {
	if (!x) return 0;
	if (!ch[y][0]) {
		vec[++tail] = x;
		return 1;
	}
	if (same(ch[x][0], ch[y][0]) && same(ch[x][1], ch[y][1])) return 1;
	return 0;
}

bool Cover(int size) {
	if (!spec[size]) return 0;
	head = 1, tail = 0;
	vec[++tail] = 1;
	for (; head <= tail; ++head) {
		if (sz[vec[head]] == 1) continue;
		if (!same(vec[head], spec[size])) return 0;
	}
	return 1;
}

int main() {
	scanf("%s", s + 1);
	len = strlen(s + 1);
	
	build();
	
	memset(dp, 0x3f, sizeof dp);
	
	for (int i = 1; i <= n; ++i) {
		if (sz[i] <= 3) dp[i] = 0;
	}
	
	for (int size = 3; size <= n; size += 2) {
		if ((n - 1) % (size - 1) == 0 && Cover(size)) {
			for (int I = 1; I <= tail; ++I) {
				int i = vec[I];
				dp[i] = std::min(dp[i], (sz[i] - 1) / (size - 1) - 1 + dp[spec[size]]);
			}
		}
	}
	
	printf("%d\n", dp[1]);
	
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 16536
final_rank: 3

code_snippet: #line 1 "a.cpp"
/*	author:  Kite_kuma
	created: 2022.05.28 17:08:40 */

#line 2 "SPJ-Library/template/kuma.hpp"

#line 2 "SPJ-Library/template/basic_func.hpp"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool flag = true) { std::cout << (flag ? "Yes" : "No") << '\n'; }
void YES(bool flag = true) { std::cout << (flag ? "YES" : "NO") << '\n'; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(const T &x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(const Head &H, const Tail &... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T value) {
	for(auto &a : v) a += value;
	return;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

// ceil(a / b);
template <class T>
T dup(T a, T b) {
	assert(b);
	if(b < 0) {
		a *= -1;
		b *= -1;
	}
	return least_upper_multiple(a, b) / b;
}

long long pow_ll(long long a, long long n) {
	if(n == 0) return 1LL;
	if(a == 0) return 0LL;
	if(a == 1) return 1LL;
	if(a == -1) return (n & 1LL) ? -1LL : 1LL;
	long long res = 1;
	while(n > 0) {
		if(n & 1) res *= a;
		a *= a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, const long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(const std::vector<T> &a) {
	std::vector<T> vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(const auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}
#line 1 "SPJ-Library/template/header.hpp"
#include <bits/stdc++.h>
#line 2 "SPJ-Library/template/io.hpp"

#line 4 "SPJ-Library/template/io.hpp"

#line 8 "SPJ-Library/template/debug.hpp"

#line 3 "SPJ-Library/template/constants.hpp"

constexpr int inf = 1000'000'000;
constexpr long long INF = 1'000'000'000'000'000'000LL;
constexpr int mod_1000000007 = 1000000007;
constexpr int mod_998244353 = 998244353;
const long double pi = acosl(-1.);
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
#line 10 "SPJ-Library/template/debug.hpp"

namespace viewer {

template <typename T, typename U>
void view(const std::pair<T, U> &p);

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p);

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p);

void view(const long long &e);

void view(const int &e);

template <typename T>
void view(const T &e);

template <typename T>
void view(const std::set<T> &s);

template <typename T>
void view(const std::unordered_set<T> &s);

template <typename T>
void view(const std::multiset<T> &s);

template <typename T>
void view(const std::unordered_multiset<T> &s);

template <typename T>
void view(const std::vector<T> &v);

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v);

template <typename T>
void view(const std::vector<std::vector<T>> &vv);

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v);

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v);

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v);

template <typename map_type>
void view_map_container(const map_type &m);

template <typename T, typename U>
void view(const std::map<T, U> &m);

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m);

template <typename container_type>
void view_container(const container_type &c, bool vertically = false) {
	typename container_type::const_iterator begin = c.begin();
	const typename container_type::const_iterator end = c.end();
	if(vertically) {
		std::cerr << "{\n";
		while(begin != end) {
			std::cerr << '\t';
			view(*(begin++));
			if(begin != end) std::cerr << ',';
			std::cerr << '\n';
		}
		std::cerr << '}';
		return;
	}
	std::cerr << "{ ";
	while(begin != end) {
		view(*(begin++));
		if(begin != end) std::cerr << ',';
		std::cerr << ' ';
	}
	std::cerr << '}';
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << '(';
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ')';
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ')';
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ')';
}

void view(const long long &e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int &e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T &e) {
	std::cerr << e;
}

template <typename T>
void view(const std::set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::vector<T> &v) {
	view_container(v);
}

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v) {
	view_container(v);
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	view_container(vv, true);
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	view_container(v, true);
}

template <typename map_type>
void view_map_container(const map_type &m) {
	std::cerr << "{\n";
	for(typename map_type::const_iterator it = m.begin(); it != m.end(); it++) {
		std::cerr << "\t[";
		view(it->first);
		std::cerr << "] : ";
		view(it->second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	view_map_container(m);
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	view_map_container(m);
}

}  // namespace viewer

// when compiling : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(const T &x) {
	viewer::view(x);
}
template <typename Head, typename... Tail>
void debug_out(const Head &H, const Tail &... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
#line 2 "SPJ-Library/template/scanner.hpp"

#line 6 "SPJ-Library/template/scanner.hpp"

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#line 7 "SPJ-Library/template/io.hpp"

#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << ' ' << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++) {
		if(it != v.begin()) std::cerr << ' ';
		os << *it;
	}
	return os;
}

struct fast_io {
	fast_io() {
		std::ios::sync_with_stdio(false);
		std::cin.tie(nullptr);
		std::cout << std::fixed << std::setprecision(15);
		srand((unsigned)time(NULL));
	}
} fast_io_;
#line 2 "SPJ-Library/template/macros.hpp"

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;
#line 7 "SPJ-Library/template/kuma.hpp"

using namespace std;
#line 5 "a.cpp"

int solve(string s) {
	const int n = int(s.size()) / 2;
	vector<vector<int>> nxt(n);
	vector<int> depth(n, 0), subweight(n, 0), parent(n, -1);
	{
		auto it = s.begin();
		int now = 0;
		auto dfs = [&](auto self) -> void {
			assert(*it == '(');
			it++;
			const int par = now;
			if(*it == '(') {
				rep(2) {
					nxt[par].push_back(++now);
					depth[now] = depth[par] + 1;
					parent[now] = par;
					const int& sub = subweight[now];
					self(self);
					subweight[par] += sub + 1;
				}
			}
			assert(*it == ')');
			it++;
			return;
		};
		dfs(dfs);
		debug(nxt);
		assert(now == n - 1);
	}
	int bottom = (int)(max_element(all(depth)) - depth.begin());

	auto same_judge = [&](int subpar, int subchild, int largetreepar, int largechild, auto self) -> bool {
		if(nxt[subchild].empty()) subchild = subpar;
		if(nxt[largechild].empty()) return subchild == subpar;
		rep(i, 2) {
			if(!self(subpar, nxt[subchild][i], largetreepar, nxt[largechild][i], self)) {
				return false;
			}
		}
		return true;
	};

	vector<int> ok(n);
	vector<int> take(n, inf);
	take[2] = 0;

	for(int p = bottom; p != -1; p = parent[p]) {
		if(subweight[p] && subweight[0] % subweight[p] == 0) {
			if(same_judge(p, p, 0, 0, same_judge)) {
				ok[subweight[p]] = 1;
			}
		}
	}

	for(int i = 2; i < n; i += 2) {
		if(ok[i]) {
			for(int j = i + i; j < n; j += i) {
				chmin(take[j], take[i] + (j / i) - 1);
			}
		}
	}

	debug(bottom);
	debug(ok);
	debug(take);

	return take[n - 1];
}
int main() {
	string s;
	while(cin >> s) {
		cout << solve(s);
		cout << '\n';
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 26492
final_rank: 8

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
//constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	//if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
	if (loc >= v.size())v.resize(loc + 1, 0);
	v[loc] += val;
}
/*const int mn = 100005;
bool isp[mn];
vector<int> ps;
void init() {
	fill(isp + 2, isp + mn, true);
	for (int i = 2; i < mn; i++) {
		if (!isp[i])continue;
		ps.push_back(i);
		for (int j = 2 * i; j < mn; j += i) {
			isp[j] = false;
		}
	}
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	if (res == st.begin())return st.end();
	res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
	auto res = st.lower_bound(val);
	return res;
}
using mP = pair<modint, modint>;


int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
//-----------------------------------------


void solve() {
	string s; cin >> s;
	int n = s.size() / 2;
	vector<vector<int>> G(n);
	int tmp = 0;
	vector<int> cur;
	rep(i, s.size()) {
		if (s[i] == '(') {
			if (cur.size()) {
				G[cur.back()].push_back(tmp);
			}
			cur.push_back(tmp); tmp++;
		}
		else {
			cur.pop_back();
		}
	}
	assert(tmp == n);
	rep(i, n) {
		assert(G[i].size() == 0 || G[i].size() == 2);
	}
	int cntleaf = 0;
	rep(i, n)if (G[i].empty())cntleaf++;
	vector<bool> ok(cntleaf + 1);
	for (int i = 2; i <= cntleaf; i++) {
		if ((cntleaf-1) % (i - 1) == 0)ok[i] = true;
	}
	vector<vector<int>> ch(cntleaf + 1);
	vector<vector<int>> memo(cntleaf + 1);
	vector<int> dep(n);
	vector<int> sz(n);
	function<int(int)> dfs = [&](int id) {
		if (G[id].empty()) {
			return sz[id] = 1;
		}
		int res = 0;
		for (int to : G[id]) {
			dep[to] = dep[id] + 1;
			res += dfs(to);
		}
		if (ok[res] && memo[res].empty()) {
			function<void(int)> chdfs = [&](int i) {
				if (G[i].empty())memo[res].push_back(dep[i]-dep[id]);
				else {
					if (id != i && ok[sz[i]]) {
						ch[res].push_back(sz[i]);
					}
					for (int to : G[i])chdfs(to);
				}
			}; chdfs(id);
		}
		return sz[id]=res;
	};
	dfs(0);
	//cout << ok[2] << " " << ok[cntleaf] << "\n";
	//coutarray(memo[2]);
	vector<int> al = memo[cntleaf];
	auto isvalid = [&](vector<int> obj, vector<int>& v) {
		int rest = (al.size() - 1) / (v.size() - 1);
		vector<int> cur = { 0 };
		rep(_, rest) {
			if (cur.empty())return false;
			int z = cur.back(); cur.pop_back();
			rep(i, v.size())cur.push_back(z + v[i]);
			while (obj.size() && cur.size() && obj.back() == cur.back()) {
				cur.pop_back();
				obj.pop_back();
			}
		}
		if (cur.empty() && obj.empty())return true;
		return false;
	};
	for (int c = 2; c <= cntleaf; c++) {
		if (!isvalid(al, memo[c]))ok[c] = false;
	}
	vector<int> dp(cntleaf + 1,mod);
	dp[2] = 0;
	for (int c = 3; c <= cntleaf; c++) {
		if (ok[c]) {
			for (int s : ch[c]) {
				if (ok[s]) {
					//assert(s != c);
					if ((c - 1) % (s - 1) == 0) {
						chmin(dp[c], dp[s] + (c - 1) / (s - 1) - 1);
					}
				}
			}
		}
	}
	//coutarray(dp);
	//cout << ok[4] << "\n";
	//cout << dp[4] << "\n";
	cout << dp[cntleaf] << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 1140
memory_kb: 41256
final_rank: 11

code_snippet: #include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <random>
#include <complex>
#include <bitset>
#include <iomanip>
#include <memory>
#include <chrono>
#include <functional>

#define rep(i, n, s) for (int i = (s); i < int(n); i++)
#define per(i, n, s) for (int i = (n - 1); i >= int(s); i--)
#define MM << " " <<
#define all(x) x.begin(), x.end()
#define rall(x) rbegin(x), rend(x)

template <class T>
using MinHeap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T>
using MaxHeap = std::priority_queue<T>;

using ll = long long;
using Pii = std::pair<int, int>;
using Pll = std::pair<ll, ll>;
using Pdd = std::pair<double, double>;

template <class T>
bool chmin(T &a, const T b) {
    if (a > b) {
        a = b;
        return true;
    } else {
        return false;
    }
}

template <class T>
bool chmax(T &a, const T b) {
    if (a < b) {
        a = b;
        return true;
    } else {
        return false;
    }
}

template <class T>
void vdeb(const std::vector<T> &da) {
    auto n = da.size();
    for (size_t i = 0; i < n; i++) {
        if (i == n - 1)
            std::cout << da[i];
        else
            std::cout << da[i] << " ";
    }
    std::cout << std::endl;
}
template<class T>
void vdeb(const std::vector<std::vector<T>> &da) {
    auto n = da.size();
    for (size_t i = 0; i < n; i++) {
        // std::cout << i << " : ";
        vdeb(da[i]);
    }
    std::cout << std::endl;
}

template <>
void vdeb(const std::vector<std::string> &da) {
    auto n = da.size();
    for (size_t i = 0; i < n; i++) { std::cout << da[i] << std::endl; }
}

using namespace std;

struct Node;

using sitr = string::const_iterator;
using pt = shared_ptr<Node>;
set<int> st;
vector<int> correct;
int N;

struct Node {
    pt left, right;
    size_t sz;
    Node() {}
    Node(sitr &itr) {
        ++itr;
        if(*itr == '(') {
            left = make_shared<Node>(itr);
            right = make_shared<Node>(itr);
            sz = left->sz + right->sz + 2;
        } else {
            left = right = nullptr;
            sz = 0;
        }
        ++itr;
    }
    bool dcp(pt sub, pt root) {
        if(!left) {
            if(sub->left) return false;
            else return true;
        } else {
            if(sub->left) {
                return left->dcp(sub->left, root) & right->dcp(sub->right, root);
            } else {
                return dcp(root, root);
            }
        }
    }
    void dfs(pt root) {
        if(!left) return;
        if(N % sz == 0 && !st.count(sz)) {
            // cout << sz << endl;
            st.insert(sz);
            if(root->dcp(make_shared<Node>(*this), make_shared<Node>(*this))) {
                correct.push_back(sz);
            }
        }
        left->dfs(root);
        right->dfs(root);
    }
    void deb(int depth = 0) {
        rep(i,depth,0) cout << " ";
        cout << sz << endl;
        if(!left) return;
        left->deb(depth+1);
        right->deb(depth+1);
    }
};

int main() {
    string s; cin >> s;
    pt root;
    {
        auto itr = s.cbegin();
        root = make_shared<Node>(itr);
    }
    N = root->sz;
    root->dfs(root);
    // root->deb();
    sort(all(correct));
    vector<int> dp(correct.size(), N/2);
    int m = dp.size();
    dp[0] = 0;
    rep(i,m,0) rep(j,m,i) {
        if(correct[j] % correct[i] == 0) chmin(dp[j], dp[i] + correct[j] / correct[i] - 1);
    }
    // vdeb(dp);
    cout << dp.back() << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 70660
final_rank: 10

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 5000005

struct Node{

	int parent,left,right,size,DEPTH;
};

int num_nodes,root;
int dp[500];
Node nodes[NUM];
bool check[200005];
char buf[NUM];

void parse(){

	for(int i = 0; i < 200005; i++){
		check[i] = false;
	}

	stack<int> S;

	int depth = 0,node_id;

	for(int i = 0; buf[i] != '\0'; i++){
		if(buf[i] == '('){
			depth++;
			S.push(num_nodes);
			nodes[num_nodes].left = -1;
			nodes[num_nodes].right = -1;
			nodes[num_nodes].DEPTH = depth;

			num_nodes++;

		}else{ //buf[i] == ')'

			node_id = S.top();
			S.pop();

			if(S.empty()){

				nodes[node_id].parent = -1;

			}else{

				nodes[node_id].parent = S.top();

				if(check[nodes[node_id].parent]){

					nodes[nodes[node_id].parent].right = node_id;

				}else{

					nodes[nodes[node_id].parent].left = node_id;
					check[nodes[node_id].parent] = true;
				}
			}
			depth--;
		}
	}
}

void calc_size(int node_id,int DEPTH){

	nodes[node_id].size = 1;
	nodes[node_id].DEPTH = DEPTH;

	if(nodes[node_id].left != -1){
		calc_size(nodes[node_id].left,DEPTH+1);
		nodes[node_id].size += nodes[nodes[node_id].left].size;
	}

	if(nodes[node_id].right != -1){
		calc_size(nodes[node_id].right,DEPTH+1);
		nodes[node_id].size += nodes[nodes[node_id].right].size;
	}
}

bool is_ok(int base_tree_node,int copied_tree_node,int copied_root){

	if(nodes[base_tree_node].left == -1 && nodes[copied_tree_node].left != -1){

		return false;

	}else if(nodes[base_tree_node].left == -1 && nodes[copied_tree_node].left == -1){

		return true;

	}else if(nodes[base_tree_node].left != -1 && nodes[copied_tree_node].left == -1){

		return is_ok(nodes[base_tree_node].left,nodes[copied_root].left,copied_root) &&
				is_ok(nodes[base_tree_node].right,nodes[copied_root].right,copied_root);

	}else{ //nodes[base_tree_node].left != -1 && nodes[copied_tree_node].left != -1

		return is_ok(nodes[base_tree_node].left,nodes[copied_tree_node].left,copied_root) &&
				is_ok(nodes[base_tree_node].right,nodes[copied_tree_node].right,copied_root);
	}
}


int main(){

	scanf("%s",buf);

	num_nodes = 0;
	parse();

	root = 0;
	calc_size(root,0);

	int tmp_node,max_DEPTH = 0;

	for(int i = 0; i < num_nodes; i++){
		if(max_DEPTH < nodes[i].DEPTH){

			max_DEPTH = nodes[i].DEPTH;
			tmp_node = i;
		}
	}

	tmp_node = nodes[tmp_node].parent;
	if(tmp_node == -1){

		printf("0\n");
		return 0;
	}

	vector<int> V;

	while(true){

		if((nodes[root].size-1)%(nodes[tmp_node].size-1) == 0){

			if(is_ok(root,tmp_node,tmp_node)){
				V.push_back(nodes[tmp_node].size-1);
			}
		}

		if(tmp_node == root)break;

		tmp_node = nodes[tmp_node].parent;
	}

	for(int i = 0; i < V.size(); i++){

		dp[i] = BIG_NUM;
	}

	dp[0] = 0;

	for(int i = 1; i < V.size(); i++){
		for(int k = 0; k < i; k++){
			if(V[i]%V[k] == 0){

				dp[i] = min(dp[i],dp[k]+V[i]/V[k]-1);
			}
		}
	}

	printf("%d\n",dp[V.size()-1]);

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 12608
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define FOR(i,a,b) for(int i=int(a);i<int(b);i++)
#define REP(i,b) FOR(i,0,b)
using vi=vector<int>;
#define PB push_back
#define ALL(x) x.begin(),x.end()
	
const int Nmax=415514;
const int inf=1145141919;
char tree[Nmax],buf[Nmax];
int sub[Nmax],idx;
int dfs1(char*&p){
	if(*++p==')')return 0;
	int v=idx++,res=1;
	REP(_,2){
		res+=dfs1(p);
		p++;
	}
	return sub[v]=res;
}
bool check(int&i,char c){
	if(buf[i]=='?')buf[i]=c;
	else if(buf[i]!=c)return false;
	i++;
	return true;
}
bool dfs2(char*&p,int w,int*i){
	if(*++p==')')return true;
	int v=idx++,tmp=0;
	if(sub[v]%w==0)i=&tmp;
	REP(_,2){
		if(!check(*i,*p))return false;
		if(!dfs2(p,w,i))return false;
		if(!check(*i,*p))return false;
		p++;
	}
	return true;
}

int main(){
	scanf("%s",tree);
	char* beg=tree;
	dfs1(beg);
	int n=sub[0];
	vi canUse;
	FOR(i,1,n+1)if(n%i==0){
		beg=tree;
		REP(j,4*i)buf[j]='?';
		idx=0;
		if(dfs2(beg,i,0))
			canUse.PB(i);
	}
	vi dp(canUse.size(),inf);
	dp[0]=0;
	REP(i,dp.size())FOR(j,i+1,dp.size())if(canUse[j]%canUse[i]==0)
		dp[j]=min(dp[j],dp[i]+canUse[j]/canUse[i]-1);
	cout<<dp.back()<<endl;
}
accuracy: 1
time_ms: 60
memory_kb: 10624
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
using namespace std;
int N;
vector<int> G[200001];
int par[200001],dep[200001],num[200001];
void makegraph(){
	string s;
	cin>>s;
	int v=-1;
	for(char c:s){
		if(c=='('){
			if(v>=0) G[v].pb(N),dep[N]=dep[v]+1;
			par[N]=v;
			v=N;
			N++;
		}else{
			num[v]=1;
			for(int u:G[v]) num[v]+=num[u];
			v=par[v];
		}
	}
}
bool dfs(int v,int w,int s){
	if(G[v].size()==0&&G[w].size()==2) return false;
	if(G[v].size()==0&&G[w].size()==0) return true;
	if(G[v].size()==2&&G[w].size()==2) return dfs(G[v][0],G[w][0],s)&&dfs(G[v][1],G[w][1],s);
	return dfs(v,s,s);
}
bool ok(int v){
	return dfs(0,v,v);
}
int main(){
	BEGIN_STACK_EXTEND(128*1024*1024);
	makegraph();
	vector<int> ds;
	int v=0;
	rep(i,N) if(dep[i]>dep[v]) v=i;
	v=par[v];
	while(v>=0){
		if((N-1)%(num[v]-1)==0){
			if(ok(v)) ds.pb(num[v]-1);
		}
		v=par[v];
	}
	int K=ds.size();
	int dp[161]={};
	rep(i,K) dp[i]=1e9;
	dp[0]=0;
	rep(i,K){
		rep(j,i){
			if(ds[i]%ds[j]==0){
				chmin(dp[i],dp[j]+ds[i]/ds[j]-1);
			}
		}
	}
	cout<<dp[K-1]<<endl;
	END_STACK_EXTEND;
}
accuracy: 1
time_ms: 50
memory_kb: 16152
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
int N;
vector<int> G[200000];
int par[200000],dep[200000],num[200000];
void makegraph(){
	string s;
	cin>>s;
	int v=-1;
	for(char c:s){
		if(c=='('){
			if(v>=0) G[v].pb(N),dep[N]=dep[v]+1;
			par[N]=v;
			v=N;
			N++;
		}else{
			num[v]=1;
			for(int u:G[v]) num[v]+=num[u];
			v=par[v];
		}
	}
}
bool dfs(int v,int w,int s){
	int vs=G[v].size(),ws=G[w].size();
	if(vs==0&&ws==2) return false;
	if(vs==0&&ws==0) return true;
	if(vs==2&&ws==2) return dfs(G[v][0],G[w][0],s)&&dfs(G[v][1],G[w][1],s);
	return dfs(v,s,s);
}
bool ok(int v){
	return dfs(0,v,v);
}
int main(){
	makegraph();
	vector<int> ds;
	int v=0;
	rep(i,N) if(dep[i]>dep[v]) v=i;
	v=par[v];
	while(v>=0){
		if((N-1)%(num[v]-1)==0){
			if(ok(v)) ds.pb(num[v]-1);
		}
		v=par[v];
	}
	int K=ds.size();
	int dp[161]={};
	rep(i,K) dp[i]=1e9;
	dp[0]=0;
	rep(i,K){
		rep(j,i){
			if(ds[i]%ds[j]==0){
				chmin(dp[i],dp[j]+ds[i]/ds[j]-1);
			}
		}
	}
	cout<<dp[K-1]<<endl;
}
accuracy: 0.8421052631578947
time_ms: 20
memory_kb: 13556
final_rank: 12

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

bool f(string& s, string& t, int& i, int j) {
	int n = s.length(), m = t.length();
	for (int j = 0; j < m; j++) {
		if (i == n) return false;
		if (s[i] == '(' && t[j] == ')') {
			i--;
			if (!f(s, t, i, 0)) return false;
		}
		else if (s[i] == ')' && t[j] == '(') return false;
		else i++;
	}
	return true;
}

bool check(string& s, string& t) {
	int i = 0;
	return f(s, t, i, 0);
}

int main() {
	string s; cin >> s;
	int n = s.length(), N = n / 4;
	int m, x = 0, ma = -1;
	for (int i = 0; i < n; i++) {
		if (x > ma) {
			m = i;
			ma = x;
		}
		if (s[i] == '(') x++;
		if (s[i] == ')') x--;
	}
	vector<int> l;
	x = 0; ma = 1;
	for (int i = m - 1; i >= 0; i--) {
		if (s[i] == '(') x++;
		if (s[i] == ')') x--;
		if (x > ma) {
			l.push_back(i);
			ma = x;
		}
	}
	vector<int> r;
	x = 0; ma = 1;
	for (int i = m + 1; i <= n; i++) {
		if (s[i - 1] == ')') x++;
		if (s[i - 1] == '(') x--;
		if (x > ma) {
			r.push_back(i);
			ma = x;
		}
	}
	map<int, string> mp;
	for (int k = 0; k < l.size(); k++) {
		string t = s.substr(l[k], r[k] - l[k]);
		int m = t.length(), M = m / 4;
		if (N % M == 0) mp[M] = t;
	}
	vector<int> dp(N + 1, INT_MAX / 2);
	dp[1] = 0;
	for (auto z: mp) {
		int M = z.first;
		string t = z.second;
		for (int d = 1; d < M; d++)
			if (M % d == 0 && mp.count(d) && check(t, mp[d]))
				dp[M] = min(dp[M], dp[d] + M / d - 1);
	}
	cout << dp[N] << endl;
}
accuracy: 1
time_ms: 870
memory_kb: 13892
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#include<set>
using namespace std;
typedef unsigned long long wolf;
long long mod=1000000007;
char in[1100000];
int lc[210000];
int rc[210000];
int L[210000];
int R[210000];
wolf rj[610000];
int v[210000];
void dfs(int a){
	v[a]=1;
	if(lc[a]!=-1){
		dfs(lc[a]);
		v[a]+=v[lc[a]];
	}
	if(rc[a]!=-1){
		dfs(rc[a]);
		v[a]+=v[rc[a]];
	}
}
map<wolf,int> dp;
wolf sum[610000];
wolf hash[210000];
int sz;
int chk(int a,int b){
	queue<pair<int,int> >Q;
	Q.push(make_pair(a,b));
	while(Q.size()){
		int at=Q.front().first;
		int cur=Q.front().second;
		Q.pop();
		if(v[cur]==1){
			if(~lc[at]){
				Q.push(make_pair(lc[at],lc[b]));
				Q.push(make_pair(rc[at],rc[b]));
			}
		}else{
			if(v[at]==1)return 0;
			Q.push(make_pair(lc[at],lc[cur]));
			Q.push(make_pair(rc[at],rc[cur]));
		}
	}
	return 1;
}
int calc(int a){
	if(v[a]==3&&~lc[a]&&~rc[a])return 0;
	if(dp.count(hash[a]))return dp[hash[a]];
	
	set<wolf>S;
	int ret=999999999;
	for(int i=a+1;i<sz&&R[i]<R[a];i++){
		if(v[i]==1)continue;
		if(v[a]%(v[i]-1)!=1)continue;
		if(S.count(hash[i]))continue;
		if(!chk(a,i))continue;
		S.insert(hash[i]);
		ret=min(ret,v[a]/(v[i]-1)-1+calc(i));
	}
	return dp[hash[a]]=ret;
}
int main(){
	scanf("%s",in);
	rj[0]=1;
	for(int i=0;i<210000;i++)rc[i]=lc[i]=-1;
	for(int i=1;i<610000;i++)rj[i]=rj[i-1]*mod;
	for(int i=0;in[i];i++){
		sum[i+1]=sum[i]+rj[i]*in[i];
	}
	sz=0;
	stack<int>S;
	S.push(-1);
	for(int i=0;in[i];i++){
		if(in[i]=='('){
			L[sz]=i;
			if(S.top()!=-1){
				if(lc[S.top()]==-1)lc[S.top()]=sz;
				else rc[S.top()]=sz;
			}
			S.push(sz);
			sz++;
		}else{
			R[S.top()]=i;
			S.pop();
		}
	}
	dfs(0);
	for(int i=0;i<sz;i++){
		hash[i]=(sum[R[i]+1]-sum[L[i]])*rj[609999-L[i]];
	}
	printf("%d\n",calc(0));
}
accuracy: 1
time_ms: 60
memory_kb: 18324
final_rank: 7

code_snippet: #include<cstdio>
#include<string>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<utility>
#include<algorithm>

using namespace std;

typedef string::iterator State;

vector<int> G[200200];
int N;
int sz[200200];

string str;
stack<int> st,fin;
int c=0;

void parse(){
	for(int i=0;i<str.size();i++){
		if(str[i]=='('){
			st.push(c++);
		}else{
			if(str[i-1]=='('){
				int v=st.top();
				st.pop();
				fin.push(v);
				sz[v]=0;
			}else{
				int v=fin.top();
				fin.pop();
				int u=fin.top();
				fin.pop();
				int p=st.top();
				st.pop();
				fin.push(p);
				G[p].push_back(u);
				G[p].push_back(v);
				sz[p]=sz[u]+sz[v]+2;
			}
		}
	}
}

int cands[200200];

queue<int> que;
bool rec(int v,int a){
//	printf("(%d,%d)\n",v,a);
	if(G[a].size()>0&&G[v].size()==0) return false;
	if(G[v].size()>0&&G[a].size()==0){
		que.push(v);
	}
	bool flg=true;
	if(G[v].size()>0&&G[a].size()>0){
		int b=G[a][0],c=G[a][1];
		int u=G[v][0],w=G[v][1];
		flg&=rec(u,b);
		flg&=rec(w,c);
	}
	return flg;
}

bool check(int r){
//	printf("check %d\n",r);
	while(!que.empty()) que.pop();
	que.push(0);
	while(!que.empty()){
		int v=que.front();
		que.pop();
		bool flg=rec(v,r);
		if(flg==false) return false;
	}
	return true;
}

vector<int> vals;
vector<int> dis;

int main(){
	cin>>str;
	parse();
//	for(int i=0;i<c;i++){
//		printf("%d::",i);
//		for(int j=0;j<G[i].size();j++) printf("%d ",G[i][j]);
//		printf("\n");
//	}
	N=c;
	if(N==3){
		printf("0\n");
		return 0;
	}
	for(int i=0;i<200200;i++) cands[i]=-1;
	for(int i=1;i<N;i++){
		if(sz[i]==0) continue;
		if(cands[sz[i]]==-1&&sz[0]%sz[i]==0){
			cands[sz[i]]=i;
		}
	}
	for(int i=0;i<200200;i++){
		if(cands[i]!=-1){
			bool flg=check(cands[i]);
			if(flg){
				vals.push_back(i);
			}
		}
	}
	vals.push_back(N-1);
	for(int i=0;i<vals.size();i++){
		if(i==0){
			dis.push_back(0);
			continue;
		}
		int tmp=-1;
		for(int j=0;j<i;j++){
			if(vals[i]%vals[j]==0){
				int cur=dis[j]+(vals[i]/vals[j]-1);
				if(tmp==-1||tmp>cur) tmp=cur;
			}
		}
		dis.push_back(tmp);
	}
	printf("%d\n",dis.back());
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 13888
final_rank: 4

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>

#define EPS 1e-9
#define INF 1070000000LL
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(__typeof((X).begin()) it=(X).begin();it!=(X).end();it++)
#define ite iterator
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define pb push_back
#define sec second
#define sz(x) ((int)x.size())

using namespace std;

struct timer{
	time_t start;
	timer(){start=clock();}
	~timer(){cerr<<1.*(clock()-start)/CLOCKS_PER_SEC<<" secs"<<endl;}
};

typedef istringstream iss;
typedef long long ll;
typedef pair<int,int> pi;
typedef stringstream sst;
typedef vector<int> vi;

struct tree{
	bool leaf;
	tree *left,*right;
	int size;
} *root;

string s;
int cur=0;
int n;
int depth=0,deepest=-1;
tree *dnode;
vector<tree*> cand;
vi parts;

tree* parse(){
	tree* res=new tree;
	if(depth > deepest){
		deepest=depth;
		dnode=res;
	}
	assert(s[cur]=='(');
	if(s[cur+1]==')'){
		res->leaf=1;
		res->size=0;
		cur+=2;
		return res;
	}
	res->leaf=0;
	res->size=1;
	cur++;
	depth++;
	res->left = parse();
	res->size += res->left->size;
	res->right = parse();
	res->size += res->right->size;
	assert(s[cur]==')');
	cur++;
	depth--;
	return res;
}

bool markcand(tree* node){
	if(node->leaf){
		return node == dnode;
	}
	if(markcand(node->left) || markcand(node->right)){
		if(n % node->size == 0){
			cand.pb(node);
		}
		return 1;
	}
	return 0;
}

bool match(tree* node,int id,tree* node2){
	if(node->leaf && node2->leaf){
		return 1;
	}
	if(node->leaf && !node2->leaf){
		return 0;
	}
	if(!node->leaf && node2->leaf){
		return match(node->left,id,cand[id]->left)
		&& match(node->right,id,cand[id]->right);
	}
	if(!node->leaf && !node2->leaf){
		return match(node->left,id,node2->left)
		&& match(node->right,id,node2->right);
	}
	return 0;
}

int main(){
	cin.tie(0);
	ios_base::sync_with_stdio(0);
	
	cin>>s;
	root=parse();
	n=root->size;
	markcand(root);
	rep(i,sz(cand)){
		if(match(root,i,cand[i])){
			parts.pb(cand[i]->size);
		}
	}
	vi dp(sz(parts),INF);
	dp[0]=0;
	rep2(i,1,sz(parts)){
		rep(j,i)if(parts[i] % parts[j] == 0){
			dp[i]=min(dp[i],dp[j]+parts[i]/parts[j]-1);
		}
	}
	cout<<dp[sz(parts)-1]<<endl;
}
accuracy: 1
time_ms: 70
memory_kb: 15644
final_rank: 6