Gorillas in Kyoto University are good at math. They are currently trying to solve problems to find the value of an expression that contains two functions, `_` , `^`. Each of these functions takes two input values. `_` function returns the smaller of the two input values and `^` function returns the larger. Gorillas know that integers in the expression are non-negative and less than or equal to 99, but can not find out the length of the expression until they read a terminal symbol `?` that represents the end of the expression. The number of characters included in each expression is less than or equal to 1000, but they do not even know this fact. Ai, a smart gorilla, noticed that she may be able to know the value of the expression even if they don't read the whole expression.

For example,

Assume you read the following sentence from the left.


^(41,3)?

When you read the sixth character, that is, when you read the following expression,


^(41,3

you can tell the second input value of the funcion is whether 3 or an integer between 30 and 39, and the value turns out 41.

Since Ai wants to solve problems earlier than other gorillas, she decided to solve the problems such that she reads as fewer characters as possible from the left. For each expression, Find the value of the expression and the minimum number of characters Ai needs to read to know the value.

Constraints

* 1 \leq Q \leq 200
* The number of characters each expression contains is less than or equal to 1000.

Input

The input consists of multiple test cases and is given from Standard Input in the following format:


Q
statement_1
...
statement_Q

Input

The input consists of multiple test cases and is given from Standard Input in the following format:


Q
statement_1
...
statement_Q

Output

Output consists of Q lines. On line i (1 \leq i \leq Q), print the value of the expression and the number of character Ai needs to read for the test case i separated by space.

Examples

Input

4
_(4,51)?
^(99,_(3,67))?
_(0,87)?
3?


Output

4 5
99 4
0 3
3 2


Input

7
_(23,^(_(22,40),4))?
_(0,99)?
^(99,_(^(19,2),5))?
_(^(43,20),^(30,29))?
^(_(20,3),_(50,41))?
^(_(20,3),_(3,41))?
^(_(20,3),_(4,41))?


Output

22 18
0 3
99 4
30 17
41 17
3 14
4 15
#include <vector>
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
#include <deque>
#include <tuple>
#include <queue>
#include <functional>
#include <cmath>
#include <iomanip>
#include <set>
#include <map>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <complex>
#include <array>
//cin.sync_with_stdio(false);
//streambuf
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
using ti3 = tuple<int, int, int>;
using vti3 = vector<ti3>;
template<class T, class T2> using umap = unordered_map<T, T2>;
template<class T> using uset = unordered_set<T>;
template<class T> void cmin(T &a, const T&b) { if (a > b)a = b; }
template<class T> void cmax(T &a, const T&b) { if (a < b)a = b; }
#define ALL(a) a.begin(),a.end()
#define rep(i,a) for(int i=0;i<a;i++)
#define rep1(i,a) for(int i=1;i<=a;i++)
const ll mod = 1000000007;
#ifndef INT_MAX
const int INT_MAX = numeric_limits<signed>().max();
#endif
template<class T>using heap = priority_queue<T, vector<T>, greater<T>>;
template<class T>using pque = priority_queue<T, vector<T>, function<T(T, T)>>;
template <class T>
inline void hash_combine(size_t & seed, const T & v) {
	hash<T> hasher;
	seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std {

	template<typename S, typename T> struct hash<pair<S, T>> {
		inline size_t operator()(const pair<S, T> & v) const {
			size_t seed = 0;
			hash_combine(seed, v.first);
			hash_combine(seed, v.second);
			return seed;
		}
	};
	// Recursive template code derived from Matthieu M.
	template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
	struct HashValueImpl
	{
		static void apply(size_t& seed, Tuple const& tuple)
		{
			HashValueImpl<Tuple, Index - 1>::apply(seed, tuple);
			hash_combine(seed, std::get<Index>(tuple));
		}
	};

	template <class Tuple>
	struct HashValueImpl<Tuple, 0>
	{
		static void apply(size_t& seed, Tuple const& tuple)
		{
			hash_combine(seed, std::get<0>(tuple));
		}
	};

	template <typename ... TT>
	struct hash<std::tuple<TT...>>
	{
		size_t
			operator()(std::tuple<TT...> const& tt) const
		{
			size_t seed = 0;
			HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
			return seed;
		}

	};
}
umap<ti3, ll> memo;
ll pow(ll base, ll i, ll mod) {
	ll a = 1;
	while (i) {
		if (i & 1) {
			a *= base;
			a %= mod;
		}
		base *= base;
		base %= mod;
		i /= 2;
	}
	return a;
}
class unionfind {
	vector<int> par, rank, size_;//速度ではなくメモリ効率を考えるならrankのかわりにsizeを使う
public:
	unionfind(int n) :par(n), rank(n), size_(n, 1) {
		iota(ALL(par), 0);
	}
	int find(int x) {
		if (par[x] == x)return x;
		return par[x] = find(par[x]);
	}
	void unite(int x, int y) {
		x = find(x), y = find(y);
		if (x == y)return;
		if (rank[x] < rank[y])swap(x, y);
		par[y] = x;
		size_[x] += size_[y];
		if (rank[x] == rank[y])rank[x]++;
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
	int size(int x) {
		return size_[find(x)];
	}
};
ll gcd(ll a, ll b) {
	while (b) {
		ll c = a%b;
		a = b;
		b = c;
	}
	return a;
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b)*b;
}
int popcnt(unsigned long long a) {
	a = (a & 0x5555555555555555) + (a >> 1 & 0x5555555555555555);
	a = (a & 0x3333333333333333) + (a >> 2 & 0x3333333333333333);
	a = (a & 0x0f0f0f0f0f0f0f0f) + (a >> 4 & 0x0f0f0f0f0f0f0f0f);
	a = (a & 0x00ff00ff00ff00ff) + (a >> 8 & 0x00ff00ff00ff00ff);
	a = (a & 0x0000ffff0000ffff) + (a >> 16 & 0x0000ffff0000ffff);
	return (a & 0xffffffff) + (a >> 32);
}
template<class T, class Func = function<T(T, T)>>
class segtree {
	vector<T> obj;
	int offset;
	Func updater;
	T e;
	int bufsize(int num) {
		int i = 1;
		for (; num >i; i <<= 1);
		offset = i - 1;
		return (i << 1) - 1;
	}
	T query(int a, int b, int k, int l, int r) {
		if (r <= a || b <= l)return e;
		if (a <= l && r <= b)return obj[k];
		else return updater(query(a, b, k * 2 + 1, l, (l + r) / 2), query(a, b, k * 2 + 2, (l + r) / 2, r));
	}
public:
	T query(int a, int b) {//[a,b)
		return query(a, b, 0, 0, offset + 1);
	}
	void updateall(int l = 0, int r = -1) {
		if (r < 0)r = offset + 1;
		l += offset, r += offset;
		do {
			l = l - 1 >> 1, r = r - 1 >> 1;
			for (int i = l; i < r; i++)obj[i] = updater(obj[i * 2 + 1], obj[i * 2 + 2]);
		} while (r);
	}
	void update(int k, T &a) {
		k += offset;
		obj[k] = a;
		while (k) {
			k = k - 1 >> 1;
			obj[k] = updater(obj[k * 2 + 1], obj[k * 2 + 2]);
		}
	}
	segtree(int n, T e, const Func &updater_ = Func()) :obj(bufsize(n), e), e(e), updater(updater_) {}
	segtree(vector<T> &vec, T e, const Func &updater = Func()) :obj(bufsize(vec.size()), e), e(e), updater(updater) {
		copy(vec.begin(), vec.end(), obj.begin() + offset);
		updateall();
	}
	typename vector<T>::reference operator[](int n) {
		return obj[n + offset];
	}
};
int ans;
void evalution(vector<array<int, 5>> &a) {
	for (auto it = a.rbegin(); it < --a.rend(); it++) {
		if ((*it)[0] & 6) {
			int pos = (*(it+1))[0] & 2;
			pos++;
			if ((*it)[0] & 1) {
				(*(it + 1))[pos] = max((*it)[1], (*it)[3]);
				(*(it + 1))[pos + 1] = max((*it)[2], (*it)[4]);
			}
			else{
				(*(it + 1))[pos] = min((*it)[1], (*it)[3]);
				(*(it + 1))[pos + 1] = min((*it)[2], (*it)[4]);
			}
		}
	}
}
int main() {
	int q;
	cin >> q;
	for (; q; q--) {
		vector<array<int,5>> sk;
		string s;
		cin >> s;
		int cnt = 0;
		bool n2 = 0;
		bool end = 0;
		sk.push_back({ 0,0,99,0,99 });
		for (; cnt < s.size();cnt++) {
			switch (s[cnt]) {
			case '_':
				sk.push_back({ 4, 0, 99,0,99 });
				cnt++;
				break;
			case '^':
				sk.push_back({ 5,0,99 ,0,99});
				cnt++;
				break;
			case '?':
				end = 1;
				break;
			case ',':
				sk.back()[0] += 2;
				if (n2) {
					sk.back()[2] = sk.back()[1];
					evalution(sk);
					n2 = 0;
					if (sk[0][1] == sk[0][2])end = 1;
				}
				break;
			case ')':
				sk.back()[4] = sk.back()[3];
				evalution(sk);
				if (sk[0][1] == sk[0][2])end=1;
				sk.pop_back();
				n2 = 0;
				break;
			case '0':
				if (!n2) {
					int pos = sk.back()[0] & 2;
					pos++;
					sk.back()[pos] = sk.back()[pos + 1] = 0;
					evalution(sk);
					if (sk[0][1] == sk[0][2])end = 1;
					break;
				}
			default:
			{
				int pos = sk.back()[0] & 2;
				pos++;
				if (!n2) {
					sk.back()[pos] = s[cnt]-'0';
					sk.back()[pos + 1] = (s[cnt]-'0') * 10 + 9;
					n2 = 1;
					evalution(sk);
					if (sk[0][1] == sk[0][2])end = 1, n2 = 0;
				}
				else {
					sk.back()[pos]=sk.back()[pos + 1] = sk.back()[pos] * 10 + s[cnt]-'0';
					evalution(sk);
					if (sk[0][1] == sk[0][2])end = 1;
					n2 = 0;
					break;
				}
			}
			}
			if (end)break;
		}
		cout << sk[0][1] << " " << cnt+1 << endl;
	}
}
