#include <bitset>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
#include <locale>
#include <memory>
#include <stdexcept>
#include <utility>
#include <string>
#include <fstream>
#include <ios>
#include <iostream>
#include <iosfwd>
#include <iomanip>
#include <istream>
#include <ostream>
#include <sstream>
#include <streambuf>
#include <complex>
#include <numeric>
#include <valarray>
#include <exception>
#include <limits>
#include <new>
#include <typeinfo>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <climits>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <cstddef>
#include <cstdarg>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cwchar>
#include <cwctype>
using namespace std;
static const double EPS = 1e-8;
static const double PI = 4.0 * atan(1.0);
static const double PI2 = 8.0 * atan(1.0);
typedef long long ll;
typedef unsigned long long ull;

#define ALL(c) (c).begin(), (c).end()
#define CLEAR(v) memset(v,0,sizeof(v))
#define MP(a,b) make_pair((a),(b))
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define ABS(a) ((a)>0?(a):-(a))
template<class T> T MIN(const T& a, const T& b) { return a < b ? a : b; }
template<class T> T MAX(const T& a, const T& b) { return a > b ? a : b; }
template<class T> void MIN_UPDATE(T& a, const T& b) { if (a > b) a = b; }
template<class T> void MAX_UPDATE(T& a, const T& b) { if (a < b) a = b; }

#ifdef _MSC_VER
typedef unsigned int uint32_t;
#endif
typedef unsigned long long ull;

/*
*  Copyright (c) 2010 Daisuke Okanohara
*
*   Redistribution and use in source and binary forms, with or without
*   modification, are permitted provided that the following conditions
*   are met:
*
*   1. Redistributions of source code must retain the above Copyright
*      notice, this list of conditions and the following disclaimer.
*
*   2. Redistributions in binary form must reproduce the above Copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
*
*   3. Neither the name of the authors nor the names of its contributors
*      may be used to endorse or promote products derived from this
*      software without specific prior written permission.
*/

namespace wat_array {

	enum {
		NOTFOUND = 0
	};

	class BitArray {

	private:
		enum {
			BLOCK_BITNUM = 32,
			TABLE_INTERVAL = 4,
		};

	public:
		BitArray();
		~BitArray();
		BitArray(uint32_t size);
		uint32_t length() const;
		uint32_t one_num() const;

		void Init(uint32_t size);
		void Clear();
		void SetBit(uint32_t bit, uint32_t pos);

		void Build();
		uint32_t Rank(uint32_t bit, uint32_t pos) const;
		uint32_t Select(uint32_t bit, uint32_t rank) const;
		uint32_t Lookup(uint32_t pos) const;

		static uint32_t PopCount(uint32_t x);
		static uint32_t PopCountMask(uint32_t x, uint32_t offset);
		static uint32_t SelectInBlock(uint32_t x, uint32_t rank);
		static uint32_t GetBitNum(uint32_t one_num, uint32_t num, uint32_t bit);
		void PrintForDebug(std::ostream& os) const;

		void Save(std::ostream& os) const;
		void Load(std::istream& is);

	private:
		uint32_t RankOne(uint32_t pos) const;
		uint32_t SelectOutBlock(uint32_t bit, uint32_t& rank) const;

	private:
		std::vector<uint32_t> bit_blocks_;
		std::vector<uint32_t> rank_tables_;
		uint32_t length_;
		uint32_t one_num_;
	};

	/**
	Wavelet Tree Array Library for array processing.

	Input: A[0...n], 0 <= A[i] < k,
	Space: n log_2 k bits

	Support many queries in O(log k) time and constant for n.
	*/

	struct ListResult{
		ListResult(uint32_t c, uint32_t freq) : c(c), freq(freq){}
		uint32_t c;
		uint32_t freq;
		bool operator < (const ListResult& lr) const {
			if (c != lr.c) return c < lr.c;
			return freq < lr.freq;
		}
	};

	class WatArray{
	public:
		/**
		* Constructor
		*/
		WatArray();

		/**
		* Destructor
		*/
		~WatArray();

		/**
		* Initialize an index from an array
		* @param An array to be initialized
		*/
		void Init(const std::vector<uint32_t>& array);

		void Init(const BitArray& ba, uint32_t width, uint32_t length);

		/**
		* Clear and release the resouces
		*/
		void Clear();

		/**
		* Lookup A[pos]
		* @param pos the position
		* @return return A[pos] if found, or return NOT_FOUND if pos >= length
		*/
		uint32_t Lookup(uint32_t pos) const;

		/**
		* Compute the rank = the frequency of a character 'c' in the prefix of the array A[0...pos)
		* @param c Character to be examined
		* @param pos The position of the prefix (not inclusive)
		* @return The frequency of a character 'c' in the prefix of the array A[0...pos)
		*         or NOT_FOUND if c >= alphabet_num or pos > length
		*/
		uint32_t Rank(uint32_t c, uint32_t pos) const;

		/**
		* Compute the select = the position of the (rank+1)-th occurence of 'c' in the array.
		* @param c Character to be examined
		* @param rank The rank of the character
		* @return The position of the (rank+1)-th occurence of 'c' in the array.
		*         or NOT_FOUND if c >= alphabet_num or rank > Freq(c)
		*/
		uint32_t Select(uint32_t c, uint32_t rank) const;

		/**
		* Compute the frequency of characters c' < c in the subarray A[0...pos)
		* @param c The upper bound of the characters
		* @param pos The position of the end of the prefix (not inclusive)
		* @return The frequency of characters c' < c in the prefix of the array A[0...pos)
		or NOTFOUND if c > alphabet_num or pos > length
		*/
		uint32_t RankLessThan(uint32_t c, uint32_t pos) const;

		/**
		* Compute the frequency of characters c' > c in the subarray A[0...pos)
		* @param c The lower bound of the characters
		* @param pos The position of the end of the prefix (not inclusive)
		* @return The frequency of characters c' < c in the prefix of the array A[0...pos)
		or NOTFOUND if c > alphabet_num or pos > length
		*/
		uint32_t RankMoreThan(uint32_t c, uint32_t pos) const;

		/**
		* Compute the frequency of characters c' < c, c'=c, and c' > c, in the subarray A[0...pos)
		* @param c The character
		* @param pos The position of the end of the prefix (not inclusive)
		* @param rank The frefquency of c in A[0...pos)
		* @param rank_less_than The frequency of c' < c in A[0...pos)
		* @param rank_more_than The frequency of c' > c in A[0...pos)
		*/
		void RankAll(uint32_t c, uint32_t pos, uint32_t& rank,
			uint32_t& rank_less_than, uint32_t& rank_more_than) const;

		/**
		* Compute the frequency of characters min_c <= c' < max_c in the subarray A[beg_pos ... end_pos)
		* @param min_c The smallerest character to be examined
		* @param max_c The uppker bound of the character to be examined
		* @param beg_pos The beginning position of the array (inclusive)
		* @param end_pos The ending position of the array (not inclusive)
		* @return The frequency of characters min_c <= c < max_c in the subarray A[beg_pos .. end_pos)
		or NOTFOUND if max_c > alphabet_num or end_pos > length
		*/
		uint32_t FreqRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos) const;

		/**
		* Range Max Query
		* @param beg_pos The beginning position
		* @param end_pos The ending position
		* @param pos The position where the largest value appeared in the subarray A[beg_pos .. end_pos)
		If there are many items having the largest values, the smallest pos will be reporeted
		* @param val The largest value appeared in the subarray A[beg_pos ... end_pos)
		*/
		void MaxRange(uint32_t beg_pos, uint32_t end_pos, uint32_t& pos, uint32_t& val) const;

		/**
		* Range Min Query
		* @param beg_pos The beginning position
		* @param end_pos The ending position
		* @param pos The position where the smallest value appeared in the subarray A[beg_pos .. end_pos)
		If there are many items having the smalles values, the smallest pos will be reporeted
		* @param val The smallest value appeared in the subarray A[beg_pos ... end_pos)
		*/
		void MinRange(uint32_t beg_pos, uint32_t end_pos, uint32_t& pos, uint32_t& val) const;

		/**
		* Range Quantile Query, Return the K-th smallest value in the subarray
		* @param beg_pos The beginning position
		* @param end_pos The ending position
		* @param k The order (should be smaller than end_pos - beg_pos).
		* @param pos The position where the k-th largest value appeared in the subarray A[beg_pos .. end_pos)
		If there are many items having the k-th largest values, the smallest pos will be reporeted
		* @param val The k-th largest value appeared in the subarray A[beg_pos ... end_pos)
		*/
		void QuantileRange(uint32_t beg_pos, uint32_t end_pos, uint32_t k, uint32_t& pos, uint32_t& val) const;

		/**
		* List the distinct characters appeared in A[beg_pos ... end_pos) from most frequent ones
		*/
		void ListModeRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos, uint32_t num, std::vector<ListResult>& res) const;

		/**
		* List the distinct characters in A[beg_pos ... end_pos) min_c <= c < max_c  from smallest ones
		* @param min_c The smallerest character to be examined
		* @param max_c The uppker bound of the character to be examined
		* @param beg_pos The beginning position of the array (inclusive)
		* @param end_pos The ending positin of the array (not inclusive)
		* @param num The maximum number of reporting results.
		* @param res The distinct chracters in the A[beg_pos ... end_pos) from smallest ones.
		*            Each item consists of c:character and freq: frequency of c.
		*/
		void ListMinRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos, uint32_t num, std::vector<ListResult>& res) const;

		/**
		* List the distinct characters appeared in A[beg_pos ... end_pos) from largest ones
		* @param min_c The smallerest character to be examined
		* @param max_c The uppker bound of the character to be examined
		* @param beg_pos The beginning position of the array (inclusive)
		* @param end_pos The ending positin of the array (not inclusive)
		* @param num The maximum number of reporting results.
		* @param res The distinct chracters in the A[beg_pos ... end_pos) from largestx ones.
		*            Each item consists of c:character and freq: frequency of c.
		*/
		void ListMaxRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos, uint32_t num, std::vector<ListResult>& res) const;

		/**
		* Compute the frequency of the character c
		* @param c The character to be examined
		* param Return the frequency of c in the array.
		*/
		uint32_t Freq(uint32_t c) const;

		/**
		* Compute the frequency of the characters
		* @param min_c The minimum character
		* @param max_c The maximum character
		* param Return the frequency of min_c <= c < max_c in the array.
		*/
		uint32_t FreqSum(uint32_t min_c, uint32_t max_c) const;

		/**
		* Return the number of alphabets in the array
		* @return The number of alphabet in the array
		*/
		uint32_t alphabet_num() const;

		/**
		* Return the length of the array
		* @return The length of the array
		*/
		uint32_t length() const;

		/**
		* Save the current status to a stream
		* @param os The output stream where the data is saved
		*/
		void Save(std::ostream& os) const;

		/**
		* Load the current status from a stream
		* @param is The input stream where the status is saved
		*/
		void Load(std::istream& is);

	private:
		uint32_t GetAlphabetNum(const std::vector<uint32_t>& array) const;
		uint32_t Log2(uint32_t x) const;
		uint32_t PrefixCode(uint32_t x, uint32_t len, uint32_t total_len) const;
		static uint32_t GetMSB(uint32_t x, uint32_t pos, uint32_t len);
		static uint32_t GetLSB(uint32_t x, uint32_t pos);
		void SetArray(const std::vector<uint32_t>& array);
		void SetOccs(const std::vector<uint32_t>& array);
		void GetBegPoses(const std::vector<uint32_t>& array, uint32_t alpha_bit_num,
			std::vector<std::vector<uint32_t> >& beg_poses) const;

		struct QueryOnNode{
			QueryOnNode(uint32_t beg_node, uint32_t end_node, uint32_t beg_pos, uint32_t end_pos,
			uint32_t depth, uint32_t prefix_char) :
			beg_node(beg_node), end_node(end_node), beg_pos(beg_pos), end_pos(end_pos),
			depth(depth), prefix_char(prefix_char) {}
			uint32_t beg_node;
			uint32_t end_node;
			uint32_t beg_pos;
			uint32_t end_pos;
			uint32_t depth;
			uint32_t prefix_char;
			void print() {
				std::cout << beg_node << " " << end_node << " "
					<< beg_pos << " " << end_pos << " "
					<< depth << " ";
				for (uint32_t i = 0; i < depth; ++i){
					std::cout << GetMSB(prefix_char, i, depth);
				}
				std::cout << std::endl;
			}
		};

		class ListModeComparator;
		class ListMinComparator;
		class ListMaxComparator;

		template <class Comparator>
		void ListRange(uint32_t min_c, uint32_t max_c,
			uint32_t beg_pos, uint32_t end_pos,
			uint32_t num, std::vector<ListResult>& res) const {
			res.clear();
			if (end_pos > length_ || beg_pos >= end_pos) return;

			std::priority_queue<QueryOnNode, std::vector<QueryOnNode>, Comparator> qons;
			qons.push(QueryOnNode(0, length_, beg_pos, end_pos, 0, 0));

			while (res.size() < num && !qons.empty()){
				QueryOnNode qon = qons.top();
				qons.pop();
				if (qon.depth >= alphabet_bit_num_){
					res.push_back(ListResult(qon.prefix_char, qon.end_pos - qon.beg_pos));
				}
				else {
					std::vector<QueryOnNode> next;
					ExpandNode(min_c, max_c, qon, next);
					for (size_t i = 0; i < next.size(); ++i){
						qons.push(next[i]);
					}
				}
			}
		}

		bool CheckPrefix(uint32_t prefix, uint32_t depth, uint32_t min_c, uint32_t max_c) const;
		void ExpandNode(uint32_t min_c, uint32_t max_c,
			const QueryOnNode& qon, std::vector<QueryOnNode>& next) const;

		std::vector<BitArray> bit_arrays_;
		BitArray occs_;

		uint32_t alphabet_num_;
		uint32_t alphabet_bit_num_;
		uint32_t length_;
	};

	BitArray::BitArray() : length_(0), one_num_(0){
	}

	BitArray::BitArray(uint32_t length){
		Init(length);
	}

	BitArray::~BitArray(){
	}

	uint32_t BitArray::length() const {
		return length_;
	}

	uint32_t BitArray::one_num() const{
		return one_num_;
	}

	void BitArray::Init(uint32_t length){
		length_ = length;
		one_num_ = 0;
		uint32_t block_num = (length + BLOCK_BITNUM - 1) / BLOCK_BITNUM;
		bit_blocks_.resize(block_num);
	}

	void BitArray::Clear(){
		std::vector<uint32_t>().swap(bit_blocks_);
		std::vector<uint32_t>().swap(rank_tables_);
		length_ = 0;
		one_num_ = 0;
	}

	void BitArray::Build() {
		one_num_ = 0;
		uint32_t table_num = ((bit_blocks_.size() + TABLE_INTERVAL - 1) / TABLE_INTERVAL) + 1;
		rank_tables_.resize(table_num);
		for (size_t i = 0; i < bit_blocks_.size(); ++i){
			if ((i % TABLE_INTERVAL) == 0){
				rank_tables_[i / TABLE_INTERVAL] = one_num_;
			}
			one_num_ += PopCount(bit_blocks_[i]);
		}
		rank_tables_.back() = one_num_;
	}

	void BitArray::SetBit(uint32_t bit, uint32_t pos) {
		if (!bit) return;
		bit_blocks_[pos / BLOCK_BITNUM] |= (1LLU << (pos % BLOCK_BITNUM));
	}

	uint32_t BitArray::Rank(uint32_t bit, uint32_t pos) const {
		if (pos > length_) return NOTFOUND;
		if (bit) return RankOne(pos);
		else return pos - RankOne(pos);
	}

	uint32_t BitArray::Select(uint32_t bit, uint32_t rank) const {
		if (bit){
			if (rank > one_num_) return NOTFOUND;
		}
		else {
			if (rank > length_ - one_num_) return NOTFOUND;
		}

		uint32_t block_pos = SelectOutBlock(bit, rank);
		uint32_t block = (bit) ? bit_blocks_[block_pos] : ~bit_blocks_[block_pos];
		return block_pos * BLOCK_BITNUM + SelectInBlock(block, rank);
	}

	uint32_t BitArray::SelectOutBlock(uint32_t bit, uint32_t& rank) const {
		// binary search over tables
		uint32_t left = 0;
		uint32_t right = rank_tables_.size();
		while (left < right){
			uint32_t mid = (left + right) / 2;
			uint32_t length = BLOCK_BITNUM * TABLE_INTERVAL * mid;
			if (GetBitNum(rank_tables_[mid], length, bit) < rank) {
				left = mid + 1;
			}
			else {
				right = mid;
			}
		}

		uint32_t table_ind = (left != 0) ? left - 1 : 0;
		uint32_t block_pos = table_ind * TABLE_INTERVAL;
		rank -= GetBitNum(rank_tables_[table_ind],
			block_pos * BLOCK_BITNUM,
			bit);

		// sequential search over blocks
		for (; block_pos < bit_blocks_.size(); ++block_pos){
			uint32_t rank_next = GetBitNum(PopCount(bit_blocks_[block_pos]), BLOCK_BITNUM, bit);
			if (rank <= rank_next){
				break;
			}
			rank -= rank_next;
		}
		return block_pos;
	}

	uint32_t BitArray::SelectInBlock(uint32_t x, uint32_t rank) {
		uint32_t x1 = x - ((x & 0xAAAAAAAAAAAAAAAALLU) >> 1);
		uint32_t x2 = (x1 & 0x3333333333333333LLU) + ((x1 >> 2) & 0x3333333333333333LLU);
		uint32_t x3 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FLLU;

		uint32_t pos = 0;
		for (;; pos += 8){
			uint32_t rank_next = (x3 >> pos) & 0xFFLLU;
			if (rank <= rank_next) break;
			rank -= rank_next;
		}

		uint32_t v2 = (x2 >> pos) & 0xFLLU;
		if (rank > v2) {
			rank -= v2;
			pos += 4;
		}

		uint32_t v1 = (x1 >> pos) & 0x3LLU;
		if (rank > v1){
			rank -= v1;
			pos += 2;
		}

		uint32_t v0 = (x >> pos) & 0x1LLU;
		if (v0 < rank){
			rank -= v0;
			pos += 1;
		}

		return pos;
	}

	uint32_t BitArray::Lookup(uint32_t pos) const {
		return (bit_blocks_[pos / BLOCK_BITNUM] >> (pos % BLOCK_BITNUM)) & 1LLU;
	}

	uint32_t BitArray::RankOne(uint32_t pos) const {
		uint32_t block_ind = pos / BLOCK_BITNUM;
		uint32_t table_ind = block_ind / TABLE_INTERVAL;
		assert(table_ind < rank_tables_.size());

		uint32_t rank = rank_tables_[table_ind];
		for (uint32_t i = table_ind * TABLE_INTERVAL; i < block_ind; ++i){
			rank += PopCount(bit_blocks_[i]);
		}
		rank += PopCountMask(bit_blocks_[block_ind], pos % BLOCK_BITNUM);
		return rank;
	}

	uint32_t BitArray::PopCount(uint32_t x) {
		x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
		x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
		x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
		x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);
		x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff);
		return x;
	}

	uint32_t BitArray::PopCountMask(uint32_t x, uint32_t offset) {
		if (offset == 0) return 0;
		return PopCount(x & ((1LU << offset) - 1));
	}

	uint32_t BitArray::GetBitNum(uint32_t one_num, uint32_t num, uint32_t bit) {
		if (bit) return one_num;
		else return num - one_num;
	}

	void BitArray::PrintForDebug(std::ostream& os) const {
		for (uint32_t i = 0; i < length_; ++i){
			if (Lookup(i)) os << "1";
			else           os << "0";
			if (((i + 1) % 8) == 0) {
				os << " ";
			}
		}
	}

	void BitArray::Save(std::ostream& os) const{
		os.write((const char*)(&length_), sizeof(length_));
		os.write((const char*)(&bit_blocks_[0]), sizeof(bit_blocks_[0]) * bit_blocks_.size());
	}

	void BitArray::Load(std::istream& is){
		Clear();
		is.read((char*)(&length_), sizeof(length_));
		Init(length_);
		is.read((char*)(&bit_blocks_[0]), sizeof(bit_blocks_[0]) * bit_blocks_.size());
		Build();
	}

	WatArray::WatArray() : alphabet_num_(0), alphabet_bit_num_(0), length_(0){
	}

	WatArray::~WatArray() {
	}

	void WatArray::Clear(){
		vector<BitArray>().swap(bit_arrays_);
		occs_.Clear();
		alphabet_num_ = 0;
		alphabet_bit_num_ = 0;
		length_ = 0;
	}

	void WatArray::Init(const vector<uint32_t>& array){
		Clear();
		alphabet_num_ = GetAlphabetNum(array);
		alphabet_bit_num_ = Log2(alphabet_num_);

		length_ = static_cast<uint32_t>(array.size());
		SetArray(array);
		SetOccs(array);
	}

	uint32_t WatArray::Lookup(uint32_t pos) const{
		if (pos >= length_) return NOTFOUND;
		uint32_t st = 0;
		uint32_t en = length_;
		uint32_t c = 0;
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			const BitArray& ba = bit_arrays_[i];
			uint32_t boundary = st + ba.Rank(0, en) - ba.Rank(0, st);
			uint32_t bit = ba.Lookup(st + pos);
			c <<= 1;
			if (bit){
				pos = ba.Rank(1, st + pos) - ba.Rank(1, st);
				st = boundary;
				c |= 1LLU;
			}
			else {
				pos = ba.Rank(0, st + pos) - ba.Rank(0, st);
				en = boundary;
			}

		}
		return c;
	}

	uint32_t WatArray::Rank(uint32_t c, uint32_t pos) const{
		uint32_t rank_less_than = 0;
		uint32_t rank_more_than = 0;
		uint32_t rank = 0;
		RankAll(c, pos, rank, rank_less_than, rank_more_than);
		return rank;
	}

	uint32_t WatArray::RankLessThan(uint32_t c, uint32_t pos) const{
		uint32_t rank_less_than = 0;
		uint32_t rank_more_than = 0;
		uint32_t rank = 0;
		RankAll(c, pos, rank, rank_less_than, rank_more_than);
		return rank_less_than;
	}

	uint32_t WatArray::RankMoreThan(uint32_t c, uint32_t pos) const{
		uint32_t rank_less_than = 0;
		uint32_t rank_more_than = 0;
		uint32_t rank = 0;
		RankAll(c, pos, rank, rank_less_than, rank_more_than);
		return rank_more_than;
	}

	void WatArray::RankAll(uint32_t c, uint32_t pos,
		uint32_t& rank, uint32_t& rank_less_than, uint32_t& rank_more_than) const{
		if (c >= alphabet_num_) {
			rank_less_than = NOTFOUND;
			rank_more_than = NOTFOUND;
			rank = NOTFOUND;
			return;
		}
		if (pos >= length_) {
			pos = length_;
		}
		uint32_t beg_node = 0;
		uint32_t end_node = length_;
		rank_less_than = 0;
		rank_more_than = 0;

		for (size_t i = 0; i < bit_arrays_.size() && beg_node < end_node; ++i){
			const BitArray& ba = bit_arrays_[i];
			uint32_t beg_node_zero = ba.Rank(0, beg_node);
			uint32_t beg_node_one = beg_node - beg_node_zero;
			uint32_t end_node_zero = ba.Rank(0, end_node);
			uint32_t boundary = beg_node + end_node_zero - beg_node_zero;
			uint32_t bit = GetMSB(c, i, bit_arrays_.size());
			if (!bit){
				rank_more_than += ba.Rank(1, pos) - beg_node_one;
				pos = beg_node + ba.Rank(0, pos) - beg_node_zero;
				end_node = boundary;
			}
			else {
				rank_less_than += ba.Rank(0, pos) - beg_node_zero;
				pos = boundary + ba.Rank(1, pos) - (beg_node - beg_node_zero);
				beg_node = boundary;
			}
		}
		rank = pos - beg_node;
	}

	uint32_t WatArray::Select(uint32_t c, uint32_t rank) const{
		if (c >= alphabet_num_) {
			return NOTFOUND;
		}
		if (rank > Freq(c)){
			return NOTFOUND;
		}

		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			uint32_t lower_c = c & ~((1LLU << (i + 1)) - 1);
			uint32_t beg_node = occs_.Select(1, lower_c + 1) - lower_c;
			const BitArray& ba = bit_arrays_[alphabet_bit_num_ - i - 1];
			uint32_t bit = GetLSB(c, i);
			uint32_t before_rank = ba.Rank(bit, beg_node);
			rank = ba.Select(bit, before_rank + rank) - beg_node + 1;
		}
		return rank - 1;
	}

	uint32_t WatArray::FreqRange(uint32_t min_c, uint32_t max_c, uint32_t begin_pos, uint32_t end_pos) const{
		if (min_c >= alphabet_num_) return 0;
		if (max_c <= min_c) return 0;
		if (end_pos > length_ || begin_pos > end_pos) return 0;
		return
			+RankLessThan(max_c, end_pos)
			- RankLessThan(min_c, end_pos)
			- RankLessThan(max_c, begin_pos)
			+ RankLessThan(min_c, begin_pos);
	}

	void WatArray::MaxRange(uint32_t begin_pos, uint32_t end_pos, uint32_t& pos, uint32_t& val) const {
		QuantileRange(begin_pos, end_pos, end_pos - begin_pos - 1, pos, val);
	}

	void WatArray::MinRange(uint32_t begin_pos, uint32_t end_pos, uint32_t& pos, uint32_t& val) const {
		QuantileRange(begin_pos, end_pos, 0, pos, val);
	}

	void WatArray::QuantileRange(uint32_t begin_pos, uint32_t end_pos, uint32_t k, uint32_t& pos, uint32_t& val) const {
		if (end_pos > length_ || begin_pos >= end_pos) {
			pos = NOTFOUND;
			val = NOTFOUND;
			return;
		}

		val = 0;
		uint32_t beg_node = 0;
		uint32_t end_node = length_;
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			const BitArray& ba = bit_arrays_[i];
			uint32_t beg_node_zero = ba.Rank(0, beg_node);
			uint32_t end_node_zero = ba.Rank(0, end_node);
			uint32_t beg_node_one = beg_node - beg_node_zero;
			uint32_t beg_zero = ba.Rank(0, begin_pos);
			uint32_t end_zero = ba.Rank(0, end_pos);
			uint32_t beg_one = begin_pos - beg_zero;
			uint32_t end_one = end_pos - end_zero;
			uint32_t boundary = beg_node + end_node_zero - beg_node_zero;

			if (end_zero - beg_zero > k){
				end_node = boundary;
				begin_pos = beg_node + beg_zero - beg_node_zero;
				end_pos = beg_node + end_zero - beg_node_zero;
				val = val << 1;
			}
			else {
				beg_node = boundary;
				begin_pos = boundary + beg_one - beg_node_one;
				end_pos = boundary + end_one - beg_node_one;
				val = (val << 1) + 1;
				k -= end_zero - beg_zero;
			}
		}

		uint32_t rank = begin_pos - beg_node;
		pos = Select(val, rank + 1);
	}

	class WatArray::ListModeComparator{
	public:
		ListModeComparator() {}
		bool operator() (const QueryOnNode& lhs,
			const QueryOnNode& rhs) const {
			if (lhs.end_pos - lhs.beg_pos != rhs.end_pos - rhs.beg_pos) {
				return lhs.end_pos - lhs.beg_pos < rhs.end_pos - rhs.beg_pos;
			}
			else if (lhs.depth != rhs.depth) {
				return lhs.depth < rhs.depth;
			}
			else {
				return lhs.beg_pos > rhs.beg_pos;
			}
		}
	};

	class WatArray::ListMinComparator{
	public:
		ListMinComparator() {}
		bool operator() (const QueryOnNode& lhs,
			const QueryOnNode& rhs) const {
			if (lhs.depth != rhs.depth)
				return lhs.depth < rhs.depth;
			else return lhs.beg_node > rhs.beg_node;
		}
	};

	class WatArray::ListMaxComparator{
	public:
		ListMaxComparator() {}
		bool operator() (const QueryOnNode& lhs,
			const QueryOnNode& rhs) const {
			if (lhs.depth != rhs.depth)
				return lhs.depth < rhs.depth;
			else return lhs.beg_node < rhs.beg_node;
		}
	};

	void WatArray::ListModeRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos,
		uint32_t num, vector<ListResult>& res) const {
		ListRange<ListModeComparator>(min_c, max_c, beg_pos, end_pos, num, res);
	}

	void WatArray::ListMinRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos,
		uint32_t num, vector<ListResult>& res) const {
		ListRange<ListMinComparator>(min_c, max_c, beg_pos, end_pos, num, res);
	}

	void WatArray::ListMaxRange(uint32_t min_c, uint32_t max_c, uint32_t beg_pos, uint32_t end_pos,
		uint32_t num, vector<ListResult>& res) const {
		ListRange<ListMaxComparator>(min_c, max_c, beg_pos, end_pos, num, res);
	}

	bool WatArray::CheckPrefix(uint32_t prefix, uint32_t depth, uint32_t min_c, uint32_t max_c) const {
		if (PrefixCode(min_c, depth, alphabet_bit_num_) <= prefix &&
			PrefixCode(max_c - 1, depth, alphabet_bit_num_) >= prefix) return true;
		else return false;
	}

	void WatArray::ExpandNode(uint32_t min_c, uint32_t max_c,
		const QueryOnNode& qon, vector<QueryOnNode>& next) const{
		const BitArray& ba = bit_arrays_[qon.depth];

		uint32_t beg_node_zero = ba.Rank(0, qon.beg_node);
		uint32_t end_node_zero = ba.Rank(0, qon.end_node);
		uint32_t beg_node_one = qon.beg_node - beg_node_zero;
		uint32_t beg_zero = ba.Rank(0, qon.beg_pos);
		uint32_t end_zero = ba.Rank(0, qon.end_pos);
		uint32_t beg_one = qon.beg_pos - beg_zero;
		uint32_t end_one = qon.end_pos - end_zero;
		uint32_t boundary = qon.beg_node + end_node_zero - beg_node_zero;
		if (end_zero - beg_zero > 0){ // child for zero
			uint32_t next_prefix = qon.prefix_char << 1;
			if (CheckPrefix(next_prefix, qon.depth + 1, min_c, max_c)) {
				next.push_back(QueryOnNode(qon.beg_node,
					boundary,
					qon.beg_node + beg_zero - beg_node_zero,
					qon.beg_node + end_zero - beg_node_zero,
					qon.depth + 1,
					next_prefix));
			}
		}
		if (end_one - beg_one > 0){ // child for one
			uint32_t next_prefix = (qon.prefix_char << 1) + 1;
			if (CheckPrefix(next_prefix, qon.depth + 1, min_c, max_c)) {
				next.push_back(QueryOnNode(boundary,
					qon.end_node,
					boundary + beg_one - beg_node_one,
					boundary + end_one - beg_node_one,
					qon.depth + 1,
					next_prefix));
			}
		}
	}

	uint32_t WatArray::Freq(uint32_t c) const {
		if (c >= alphabet_num_) return NOTFOUND;
		return occs_.Select(1, c + 2) - occs_.Select(1, c + 1) - 1;
	}

	uint32_t WatArray::FreqSum(uint32_t min_c, uint32_t max_c) const {
		if (max_c > alphabet_num_ || min_c > max_c) return NOTFOUND;
		return occs_.Select(1, max_c + 1) - occs_.Select(1, min_c + 1) - (max_c - min_c);
	}

	uint32_t WatArray::alphabet_num() const{
		return alphabet_num_;
	}

	uint32_t WatArray::length() const{
		return length_;
	}

	uint32_t WatArray::GetAlphabetNum(const std::vector<uint32_t>& array) const {
		uint32_t alphabet_num = 0;
		for (size_t i = 0; i < array.size(); ++i){
			if (array[i] >= alphabet_num){
				alphabet_num = array[i] + 1;
			}
		}
		return alphabet_num;
	}

	uint32_t WatArray::Log2(uint32_t x) const{
		if (x == 0) return 0;
		x--;
		uint32_t bit_num = 0;
		while (x >> bit_num){
			++bit_num;
		}
		return bit_num;
	}

	uint32_t WatArray::PrefixCode(uint32_t x, uint32_t len, uint32_t bit_num) const{
		return x >> (bit_num - len);
	}

	uint32_t WatArray::GetMSB(uint32_t x, uint32_t pos, uint32_t len) {
		return (x >> (len - (pos + 1))) & 1LLU;
	}

	uint32_t WatArray::GetLSB(uint32_t x, uint32_t pos) {
		return (x >> pos) & 1LLU;
	}

	void WatArray::SetArray(const vector<uint32_t>& array) {
		if (alphabet_num_ == 0) return;
		bit_arrays_.resize(alphabet_bit_num_, length_);

		vector<vector<uint32_t> > beg_poses;
		GetBegPoses(array, alphabet_bit_num_, beg_poses);

		for (size_t i = 0; i < array.size(); ++i){
			uint32_t c = array[i];
			for (uint32_t j = 0; j < alphabet_bit_num_; ++j){
				uint32_t prefix_code = PrefixCode(c, j, alphabet_bit_num_);
				uint32_t bit_pos = beg_poses[j][prefix_code]++;
				bit_arrays_[j].SetBit(GetMSB(c, j, alphabet_bit_num_), bit_pos);
			}
		}

		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			bit_arrays_[i].Build();
		}
	}

	void WatArray::SetOccs(const vector<uint32_t>& array){
		vector<uint32_t> counts(alphabet_num_);
		for (size_t i = 0; i < array.size(); ++i){
			counts[array[i]]++;
		}

		occs_.Init(array.size() + alphabet_num_ + 1);
		uint32_t sum = 0;
		for (size_t i = 0; i < counts.size(); ++i){
			occs_.SetBit(1, sum);
			sum += counts[i] + 1;
		}
		occs_.SetBit(1, sum);
		occs_.Build();
	}

	void WatArray::GetBegPoses(const vector<uint32_t>& array,
		uint32_t alpha_bit_num,
		vector< vector<uint32_t> >& beg_poses) const{
		beg_poses.resize(alpha_bit_num);
		for (uint32_t i = 0; i < beg_poses.size(); ++i){
			beg_poses[i].resize(1 << i);
		}

		for (size_t i = 0; i < array.size(); ++i){
			uint32_t c = array[i];
			for (uint32_t j = 0; j < alpha_bit_num; ++j){
				beg_poses[j][PrefixCode(c, j, alpha_bit_num)]++;
			}
		}

		for (size_t i = 0; i < beg_poses.size(); ++i){
			uint32_t sum = 0;
			vector<uint32_t>& beg_poses_level = beg_poses[i];
			for (size_t j = 0; j < beg_poses_level.size(); ++j){
				uint32_t num = beg_poses_level[j];
				beg_poses_level[j] = sum;
				sum += num;
			}
		}
	}

	void WatArray::Save(ostream& os) const{
		os.write((const char*)(&alphabet_num_), sizeof(alphabet_num_));
		os.write((const char*)(&length_), sizeof(length_));
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			bit_arrays_[i].Save(os);
		}
		occs_.Save(os);
	}

	void WatArray::Load(istream& is){
		Clear();
		is.read((char*)(&alphabet_num_), sizeof(alphabet_num_));
		alphabet_bit_num_ = Log2(alphabet_num_);
		is.read((char*)(&length_), sizeof(length_));

		bit_arrays_.resize(alphabet_bit_num_);
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			bit_arrays_[i].Load(is);
			bit_arrays_[i].Build();
		}
		occs_.Load(is);
		occs_.Build();
	}

}

int main() {
	std::ios::sync_with_stdio(false);

	string s;
	cin >> s;

	vector<uint32_t> A(s.size() + 1, (1 << 20) - 1);
	vector<int> stk;
	REP(i, s.size()) {
		if (s[i] == '(') {
			stk.push_back(i + 1);
		}
		else {
			if (stk.empty()) {
				continue;
			}

			A[stk.back()] = i + 1;
			stk.pop_back();
		}
	}

	wat_array::WatArray wa;
	wa.Init(A);

	int m;
	cin >> m;
	REP(i, m) {
		int l, r;
		cin >> l >> r;

		cout << wa.FreqRange(0, r + 1, l, r + 1) * 2 << endl;;
	}
}


#include <bitset>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
#include <locale>
#include <memory>
#include <stdexcept>
#include <utility>
#include <string>
#include <fstream>
#include <ios>
#include <iostream>
#include <iosfwd>
#include <iomanip>
#include <istream>
#include <ostream>
#include <sstream>
#include <streambuf>
#include <complex>
#include <numeric>
#include <valarray>
#include <exception>
#include <limits>
#include <new>
#include <typeinfo>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <climits>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <cstddef>
#include <cstdarg>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cwchar>
#include <cwctype>
using namespace std;
static const double EPS = 1e-8;
static const double PI = 4.0 * atan(1.0);
static const double PI2 = 8.0 * atan(1.0);
typedef long long ll;
typedef unsigned long long ull;

#define ALL(c) (c).begin(), (c).end()
#define CLEAR(v) memset(v,0,sizeof(v))
#define MP(a,b) make_pair((a),(b))
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define ABS(a) ((a)>0?(a):-(a))
template<class T> T MIN(const T& a, const T& b) { return a < b ? a : b; }
template<class T> T MAX(const T& a, const T& b) { return a > b ? a : b; }
template<class T> void MIN_UPDATE(T& a, const T& b) { if (a > b) a = b; }
template<class T> void MAX_UPDATE(T& a, const T& b) { if (a < b) a = b; }

/*
*  Copyright (c) 2010 Daisuke Okanohara
*
*   Redistribution and use in source and binary forms, with or without
*   modification, are permitted provided that the following conditions
*   are met:
*
*   1. Redistributions of source code must retain the above Copyright
*      notice, this list of conditions and the following disclaimer.
*
*   2. Redistributions in binary form must reproduce the above Copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
*
*   3. Neither the name of the authors nor the names of its contributors
*      may be used to endorse or promote products derived from this
*      software without specific prior written permission.
*/

namespace wat_array {

	enum {
		NOTFOUND = 0
	};

	class BitArray {

	private:
		enum {
			BLOCK_BITNUM = 64,
			TABLE_INTERVAL = 4,
		};

	public:
		BitArray();
		~BitArray();
		BitArray(unsigned int size);
		unsigned int length() const;
		unsigned int one_num() const;

		void Init(unsigned int size);
		void Clear();
		void SetBit(unsigned int bit, unsigned int pos);

		void Build();
		unsigned int Rank(unsigned int bit, unsigned int pos) const;
		unsigned int Select(unsigned int bit, unsigned int rank) const;
		unsigned int Lookup(unsigned int pos) const;

		static unsigned int PopCount(unsigned int x);
		static unsigned int PopCountMask(unsigned int x, unsigned int offset);
		static unsigned int SelectInBlock(unsigned int x, unsigned int rank);
		static unsigned int GetBitNum(unsigned int one_num, unsigned int num, unsigned int bit);
		void PrintForDebug(std::ostream& os) const;

		void Save(std::ostream& os) const;
		void Load(std::istream& is);

	private:
		unsigned int RankOne(unsigned int pos) const;
		unsigned int SelectOutBlock(unsigned int bit, unsigned int& rank) const;

	private:
		std::vector<unsigned int> bit_blocks_;
		std::vector<unsigned int> rank_tables_;
		unsigned int length_;
		unsigned int one_num_;
	};

	/**
	Wavelet Tree Array Library for array processing.

	Input: A[0...n], 0 <= A[i] < k,
	Space: n log_2 k bits

	Support many queries in O(log k) time and constant for n.
	*/

	struct ListResult{
		ListResult(unsigned int c, unsigned int freq) : c(c), freq(freq){}
		unsigned int c;
		unsigned int freq;
		bool operator < (const ListResult& lr) const {
			if (c != lr.c) return c < lr.c;
			return freq < lr.freq;
		}
	};

	class WatArray{
	public:
		/**
		* Constructor
		*/
		WatArray();

		/**
		* Destructor
		*/
		~WatArray();

		/**
		* Initialize an index from an array
		* @param An array to be initialized
		*/
		void Init(const std::vector<unsigned int>& array);

		void Init(const BitArray& ba, unsigned int width, unsigned int length);

		/**
		* Clear and release the resouces
		*/
		void Clear();

		/**
		* Lookup A[pos]
		* @param pos the position
		* @return return A[pos] if found, or return NOT_FOUND if pos >= length
		*/
		unsigned int Lookup(unsigned int pos) const;

		/**
		* Compute the rank = the frequency of a character 'c' in the prefix of the array A[0...pos)
		* @param c Character to be examined
		* @param pos The position of the prefix (not inclusive)
		* @return The frequency of a character 'c' in the prefix of the array A[0...pos)
		*         or NOT_FOUND if c >= alphabet_num or pos > length
		*/
		unsigned int Rank(unsigned int c, unsigned int pos) const;

		/**
		* Compute the select = the position of the (rank+1)-th occurence of 'c' in the array.
		* @param c Character to be examined
		* @param rank The rank of the character
		* @return The position of the (rank+1)-th occurence of 'c' in the array.
		*         or NOT_FOUND if c >= alphabet_num or rank > Freq(c)
		*/
		unsigned int Select(unsigned int c, unsigned int rank) const;

		/**
		* Compute the frequency of characters c' < c in the subarray A[0...pos)
		* @param c The upper bound of the characters
		* @param pos The position of the end of the prefix (not inclusive)
		* @return The frequency of characters c' < c in the prefix of the array A[0...pos)
		or NOTFOUND if c > alphabet_num or pos > length
		*/
		unsigned int RankLessThan(unsigned int c, unsigned int pos) const;

		/**
		* Compute the frequency of characters c' > c in the subarray A[0...pos)
		* @param c The lower bound of the characters
		* @param pos The position of the end of the prefix (not inclusive)
		* @return The frequency of characters c' < c in the prefix of the array A[0...pos)
		or NOTFOUND if c > alphabet_num or pos > length
		*/
		unsigned int RankMoreThan(unsigned int c, unsigned int pos) const;

		/**
		* Compute the frequency of characters c' < c, c'=c, and c' > c, in the subarray A[0...pos)
		* @param c The character
		* @param pos The position of the end of the prefix (not inclusive)
		* @param rank The frefquency of c in A[0...pos)
		* @param rank_less_than The frequency of c' < c in A[0...pos)
		* @param rank_more_than The frequency of c' > c in A[0...pos)
		*/
		void RankAll(unsigned int c, unsigned int pos, unsigned int& rank,
			unsigned int& rank_less_than, unsigned int& rank_more_than) const;

		/**
		* Compute the frequency of characters min_c <= c' < max_c in the subarray A[beg_pos ... end_pos)
		* @param min_c The smallerest character to be examined
		* @param max_c The uppker bound of the character to be examined
		* @param beg_pos The beginning position of the array (inclusive)
		* @param end_pos The ending position of the array (not inclusive)
		* @return The frequency of characters min_c <= c < max_c in the subarray A[beg_pos .. end_pos)
		or NOTFOUND if max_c > alphabet_num or end_pos > length
		*/
		unsigned int FreqRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos) const;

		/**
		* Range Max Query
		* @param beg_pos The beginning position
		* @param end_pos The ending position
		* @param pos The position where the largest value appeared in the subarray A[beg_pos .. end_pos)
		If there are many items having the largest values, the smallest pos will be reporeted
		* @param val The largest value appeared in the subarray A[beg_pos ... end_pos)
		*/
		void MaxRange(unsigned int beg_pos, unsigned int end_pos, unsigned int& pos, unsigned int& val) const;

		/**
		* Range Min Query
		* @param beg_pos The beginning position
		* @param end_pos The ending position
		* @param pos The position where the smallest value appeared in the subarray A[beg_pos .. end_pos)
		If there are many items having the smalles values, the smallest pos will be reporeted
		* @param val The smallest value appeared in the subarray A[beg_pos ... end_pos)
		*/
		void MinRange(unsigned int beg_pos, unsigned int end_pos, unsigned int& pos, unsigned int& val) const;

		/**
		* Range Quantile Query, Return the K-th smallest value in the subarray
		* @param beg_pos The beginning position
		* @param end_pos The ending position
		* @param k The order (should be smaller than end_pos - beg_pos).
		* @param pos The position where the k-th largest value appeared in the subarray A[beg_pos .. end_pos)
		If there are many items having the k-th largest values, the smallest pos will be reporeted
		* @param val The k-th largest value appeared in the subarray A[beg_pos ... end_pos)
		*/
		void QuantileRange(unsigned int beg_pos, unsigned int end_pos, unsigned int k, unsigned int& pos, unsigned int& val) const;

		/**
		* List the distinct characters appeared in A[beg_pos ... end_pos) from most frequent ones
		*/
		void ListModeRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos, unsigned int num, std::vector<ListResult>& res) const;

		/**
		* List the distinct characters in A[beg_pos ... end_pos) min_c <= c < max_c  from smallest ones
		* @param min_c The smallerest character to be examined
		* @param max_c The uppker bound of the character to be examined
		* @param beg_pos The beginning position of the array (inclusive)
		* @param end_pos The ending positin of the array (not inclusive)
		* @param num The maximum number of reporting results.
		* @param res The distinct chracters in the A[beg_pos ... end_pos) from smallest ones.
		*            Each item consists of c:character and freq: frequency of c.
		*/
		void ListMinRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos, unsigned int num, std::vector<ListResult>& res) const;

		/**
		* List the distinct characters appeared in A[beg_pos ... end_pos) from largest ones
		* @param min_c The smallerest character to be examined
		* @param max_c The uppker bound of the character to be examined
		* @param beg_pos The beginning position of the array (inclusive)
		* @param end_pos The ending positin of the array (not inclusive)
		* @param num The maximum number of reporting results.
		* @param res The distinct chracters in the A[beg_pos ... end_pos) from largestx ones.
		*            Each item consists of c:character and freq: frequency of c.
		*/
		void ListMaxRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos, unsigned int num, std::vector<ListResult>& res) const;

		/**
		* Compute the frequency of the character c
		* @param c The character to be examined
		* param Return the frequency of c in the array.
		*/
		unsigned int Freq(unsigned int c) const;

		/**
		* Compute the frequency of the characters
		* @param min_c The minimum character
		* @param max_c The maximum character
		* param Return the frequency of min_c <= c < max_c in the array.
		*/
		unsigned int FreqSum(unsigned int min_c, unsigned int max_c) const;

		/**
		* Return the number of alphabets in the array
		* @return The number of alphabet in the array
		*/
		unsigned int alphabet_num() const;

		/**
		* Return the length of the array
		* @return The length of the array
		*/
		unsigned int length() const;

		/**
		* Save the current status to a stream
		* @param os The output stream where the data is saved
		*/
		void Save(std::ostream& os) const;

		/**
		* Load the current status from a stream
		* @param is The input stream where the status is saved
		*/
		void Load(std::istream& is);

	private:
		unsigned int GetAlphabetNum(const std::vector<unsigned int>& array) const;
		unsigned int Log2(unsigned int x) const;
		unsigned int PrefixCode(unsigned int x, unsigned int len, unsigned int total_len) const;
		static unsigned int GetMSB(unsigned int x, unsigned int pos, unsigned int len);
		static unsigned int GetLSB(unsigned int x, unsigned int pos);
		void SetArray(const std::vector<unsigned int>& array);
		void SetOccs(const std::vector<unsigned int>& array);
		void GetBegPoses(const std::vector<unsigned int>& array, unsigned int alpha_bit_num,
			std::vector<std::vector<unsigned int> >& beg_poses) const;

		struct QueryOnNode{
			QueryOnNode(unsigned int beg_node, unsigned int end_node, unsigned int beg_pos, unsigned int end_pos,
			unsigned int depth, unsigned int prefix_char) :
			beg_node(beg_node), end_node(end_node), beg_pos(beg_pos), end_pos(end_pos),
			depth(depth), prefix_char(prefix_char) {}
			unsigned int beg_node;
			unsigned int end_node;
			unsigned int beg_pos;
			unsigned int end_pos;
			unsigned int depth;
			unsigned int prefix_char;
			void print() {
				std::cout << beg_node << " " << end_node << " "
					<< beg_pos << " " << end_pos << " "
					<< depth << " ";
				for (unsigned int i = 0; i < depth; ++i){
					std::cout << GetMSB(prefix_char, i, depth);
				}
				std::cout << std::endl;
			}
		};

		class ListModeComparator;
		class ListMinComparator;
		class ListMaxComparator;

		template <class Comparator>
		void ListRange(unsigned int min_c, unsigned int max_c,
			unsigned int beg_pos, unsigned int end_pos,
			unsigned int num, std::vector<ListResult>& res) const {
			res.clear();
			if (end_pos > length_ || beg_pos >= end_pos) return;

			std::priority_queue<QueryOnNode, std::vector<QueryOnNode>, Comparator> qons;
			qons.push(QueryOnNode(0, length_, beg_pos, end_pos, 0, 0));

			while (res.size() < num && !qons.empty()){
				QueryOnNode qon = qons.top();
				qons.pop();
				if (qon.depth >= alphabet_bit_num_){
					res.push_back(ListResult(qon.prefix_char, qon.end_pos - qon.beg_pos));
				}
				else {
					std::vector<QueryOnNode> next;
					ExpandNode(min_c, max_c, qon, next);
					for (size_t i = 0; i < next.size(); ++i){
						qons.push(next[i]);
					}
				}
			}
		}

		bool CheckPrefix(unsigned int prefix, unsigned int depth, unsigned int min_c, unsigned int max_c) const;
		void ExpandNode(unsigned int min_c, unsigned int max_c,
			const QueryOnNode& qon, std::vector<QueryOnNode>& next) const;

		std::vector<BitArray> bit_arrays_;
		BitArray occs_;

		unsigned int alphabet_num_;
		unsigned int alphabet_bit_num_;
		unsigned int length_;
	};

	BitArray::BitArray() : length_(0), one_num_(0){
	}

	BitArray::BitArray(unsigned int length){
		Init(length);
	}

	BitArray::~BitArray(){
	}

	unsigned int BitArray::length() const {
		return length_;
	}

	unsigned int BitArray::one_num() const{
		return one_num_;
	}

	void BitArray::Init(unsigned int length){
		length_ = length;
		one_num_ = 0;
		unsigned int block_num = (length + BLOCK_BITNUM - 1) / BLOCK_BITNUM;
		bit_blocks_.resize(block_num);
	}

	void BitArray::Clear(){
		std::vector<unsigned int>().swap(bit_blocks_);
		std::vector<unsigned int>().swap(rank_tables_);
		length_ = 0;
		one_num_ = 0;
	}

	void BitArray::Build() {
		one_num_ = 0;
		unsigned int table_num = ((bit_blocks_.size() + TABLE_INTERVAL - 1) / TABLE_INTERVAL) + 1;
		rank_tables_.resize(table_num);
		for (size_t i = 0; i < bit_blocks_.size(); ++i){
			if ((i % TABLE_INTERVAL) == 0){
				rank_tables_[i / TABLE_INTERVAL] = one_num_;
			}
			one_num_ += PopCount(bit_blocks_[i]);
		}
		rank_tables_.back() = one_num_;
	}

	void BitArray::SetBit(unsigned int bit, unsigned int pos) {
		if (!bit) return;
		bit_blocks_[pos / BLOCK_BITNUM] |= (1LLU << (pos % BLOCK_BITNUM));
	}

	unsigned int BitArray::Rank(unsigned int bit, unsigned int pos) const {
		if (pos > length_) return NOTFOUND;
		if (bit) return RankOne(pos);
		else return pos - RankOne(pos);
	}

	unsigned int BitArray::Select(unsigned int bit, unsigned int rank) const {
		if (bit){
			if (rank > one_num_) return NOTFOUND;
		}
		else {
			if (rank > length_ - one_num_) return NOTFOUND;
		}

		unsigned int block_pos = SelectOutBlock(bit, rank);
		unsigned int block = (bit) ? bit_blocks_[block_pos] : ~bit_blocks_[block_pos];
		return block_pos * BLOCK_BITNUM + SelectInBlock(block, rank);
	}

	unsigned int BitArray::SelectOutBlock(unsigned int bit, unsigned int& rank) const {
		// binary search over tables
		unsigned int left = 0;
		unsigned int right = rank_tables_.size();
		while (left < right){
			unsigned int mid = (left + right) / 2;
			unsigned int length = BLOCK_BITNUM * TABLE_INTERVAL * mid;
			if (GetBitNum(rank_tables_[mid], length, bit) < rank) {
				left = mid + 1;
			}
			else {
				right = mid;
			}
		}

		unsigned int table_ind = (left != 0) ? left - 1 : 0;
		unsigned int block_pos = table_ind * TABLE_INTERVAL;
		rank -= GetBitNum(rank_tables_[table_ind],
			block_pos * BLOCK_BITNUM,
			bit);

		// sequential search over blocks
		for (; block_pos < bit_blocks_.size(); ++block_pos){
			unsigned int rank_next = GetBitNum(PopCount(bit_blocks_[block_pos]), BLOCK_BITNUM, bit);
			if (rank <= rank_next){
				break;
			}
			rank -= rank_next;
		}
		return block_pos;
	}

	unsigned int BitArray::SelectInBlock(unsigned int x, unsigned int rank) {
		unsigned int x1 = x - ((x & 0xAAAAAAAAAAAAAAAALLU) >> 1);
		unsigned int x2 = (x1 & 0x3333333333333333LLU) + ((x1 >> 2) & 0x3333333333333333LLU);
		unsigned int x3 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FLLU;

		unsigned int pos = 0;
		for (;; pos += 8){
			unsigned int rank_next = (x3 >> pos) & 0xFFLLU;
			if (rank <= rank_next) break;
			rank -= rank_next;
		}

		unsigned int v2 = (x2 >> pos) & 0xFLLU;
		if (rank > v2) {
			rank -= v2;
			pos += 4;
		}

		unsigned int v1 = (x1 >> pos) & 0x3LLU;
		if (rank > v1){
			rank -= v1;
			pos += 2;
		}

		unsigned int v0 = (x >> pos) & 0x1LLU;
		if (v0 < rank){
			rank -= v0;
			pos += 1;
		}

		return pos;
	}

	unsigned int BitArray::Lookup(unsigned int pos) const {
		return (bit_blocks_[pos / BLOCK_BITNUM] >> (pos % BLOCK_BITNUM)) & 1LLU;
	}

	unsigned int BitArray::RankOne(unsigned int pos) const {
		unsigned int block_ind = pos / BLOCK_BITNUM;
		unsigned int table_ind = block_ind / TABLE_INTERVAL;
		assert(table_ind < rank_tables_.size());

		unsigned int rank = rank_tables_[table_ind];
		for (unsigned int i = table_ind * TABLE_INTERVAL; i < block_ind; ++i){
			rank += PopCount(bit_blocks_[i]);
		}
		rank += PopCountMask(bit_blocks_[block_ind], pos % BLOCK_BITNUM);
		return rank;
	}

	unsigned int BitArray::PopCount(unsigned int x) {
		x = (x & 0x5555555555555555ULL) +
			((x >> 1) & 0x5555555555555555ULL);
		x = (x & 0x3333333333333333ULL) +
			((x >> 2) & 0x3333333333333333ULL);
		x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
		x = x + (x >> 8);
		x = x + (x >> 16);
		//x = x + (x >> 32);
		return x & 0x7FLLU;
	}

	unsigned int BitArray::PopCountMask(unsigned int x, unsigned int offset) {
		if (offset == 0) return 0;
		return PopCount(x & ((1LLU << offset) - 1));
	}

	unsigned int BitArray::GetBitNum(unsigned int one_num, unsigned int num, unsigned int bit) {
		if (bit) return one_num;
		else return num - one_num;
	}

	void BitArray::PrintForDebug(std::ostream& os) const {
		for (unsigned int i = 0; i < length_; ++i){
			if (Lookup(i)) os << "1";
			else           os << "0";
			if (((i + 1) % 8) == 0) {
				os << " ";
			}
		}
	}

	void BitArray::Save(std::ostream& os) const{
		os.write((const char*)(&length_), sizeof(length_));
		os.write((const char*)(&bit_blocks_[0]), sizeof(bit_blocks_[0]) * bit_blocks_.size());
	}

	void BitArray::Load(std::istream& is){
		Clear();
		is.read((char*)(&length_), sizeof(length_));
		Init(length_);
		is.read((char*)(&bit_blocks_[0]), sizeof(bit_blocks_[0]) * bit_blocks_.size());
		Build();
	}

	WatArray::WatArray() : alphabet_num_(0), alphabet_bit_num_(0), length_(0){
	}

	WatArray::~WatArray() {
	}

	void WatArray::Clear(){
		vector<BitArray>().swap(bit_arrays_);
		occs_.Clear();
		alphabet_num_ = 0;
		alphabet_bit_num_ = 0;
		length_ = 0;
	}

	void WatArray::Init(const vector<unsigned int>& array){
		Clear();
		alphabet_num_ = GetAlphabetNum(array);
		alphabet_bit_num_ = Log2(alphabet_num_);

		length_ = static_cast<unsigned int>(array.size());
		SetArray(array);
		SetOccs(array);
	}

	unsigned int WatArray::Lookup(unsigned int pos) const{
		if (pos >= length_) return NOTFOUND;
		unsigned int st = 0;
		unsigned int en = length_;
		unsigned int c = 0;
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			const BitArray& ba = bit_arrays_[i];
			unsigned int boundary = st + ba.Rank(0, en) - ba.Rank(0, st);
			unsigned int bit = ba.Lookup(st + pos);
			c <<= 1;
			if (bit){
				pos = ba.Rank(1, st + pos) - ba.Rank(1, st);
				st = boundary;
				c |= 1LLU;
			}
			else {
				pos = ba.Rank(0, st + pos) - ba.Rank(0, st);
				en = boundary;
			}

		}
		return c;
	}

	unsigned int WatArray::Rank(unsigned int c, unsigned int pos) const{
		unsigned int rank_less_than = 0;
		unsigned int rank_more_than = 0;
		unsigned int rank = 0;
		RankAll(c, pos, rank, rank_less_than, rank_more_than);
		return rank;
	}

	unsigned int WatArray::RankLessThan(unsigned int c, unsigned int pos) const{
		unsigned int rank_less_than = 0;
		unsigned int rank_more_than = 0;
		unsigned int rank = 0;
		RankAll(c, pos, rank, rank_less_than, rank_more_than);
		return rank_less_than;
	}

	unsigned int WatArray::RankMoreThan(unsigned int c, unsigned int pos) const{
		unsigned int rank_less_than = 0;
		unsigned int rank_more_than = 0;
		unsigned int rank = 0;
		RankAll(c, pos, rank, rank_less_than, rank_more_than);
		return rank_more_than;
	}

	void WatArray::RankAll(unsigned int c, unsigned int pos,
		unsigned int& rank, unsigned int& rank_less_than, unsigned int& rank_more_than) const{
		if (c >= alphabet_num_) {
			rank_less_than = NOTFOUND;
			rank_more_than = NOTFOUND;
			rank = NOTFOUND;
			return;
		}
		if (pos >= length_) {
			pos = length_;
		}
		unsigned int beg_node = 0;
		unsigned int end_node = length_;
		rank_less_than = 0;
		rank_more_than = 0;

		for (size_t i = 0; i < bit_arrays_.size() && beg_node < end_node; ++i){
			const BitArray& ba = bit_arrays_[i];
			unsigned int beg_node_zero = ba.Rank(0, beg_node);
			unsigned int beg_node_one = beg_node - beg_node_zero;
			unsigned int end_node_zero = ba.Rank(0, end_node);
			unsigned int boundary = beg_node + end_node_zero - beg_node_zero;
			unsigned int bit = GetMSB(c, i, bit_arrays_.size());
			if (!bit){
				rank_more_than += ba.Rank(1, pos) - beg_node_one;
				pos = beg_node + ba.Rank(0, pos) - beg_node_zero;
				end_node = boundary;
			}
			else {
				rank_less_than += ba.Rank(0, pos) - beg_node_zero;
				pos = boundary + ba.Rank(1, pos) - (beg_node - beg_node_zero);
				beg_node = boundary;
			}
		}
		rank = pos - beg_node;
	}

	unsigned int WatArray::Select(unsigned int c, unsigned int rank) const{
		if (c >= alphabet_num_) {
			return NOTFOUND;
		}
		if (rank > Freq(c)){
			return NOTFOUND;
		}

		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			unsigned int lower_c = c & ~((1LLU << (i + 1)) - 1);
			unsigned int beg_node = occs_.Select(1, lower_c + 1) - lower_c;
			const BitArray& ba = bit_arrays_[alphabet_bit_num_ - i - 1];
			unsigned int bit = GetLSB(c, i);
			unsigned int before_rank = ba.Rank(bit, beg_node);
			rank = ba.Select(bit, before_rank + rank) - beg_node + 1;
		}
		return rank - 1;
	}

	unsigned int WatArray::FreqRange(unsigned int min_c, unsigned int max_c, unsigned int begin_pos, unsigned int end_pos) const{
		if (min_c >= alphabet_num_) return 0;
		if (max_c <= min_c) return 0;
		if (end_pos > length_ || begin_pos > end_pos) return 0;
		return
			+RankLessThan(max_c, end_pos)
			- RankLessThan(min_c, end_pos)
			- RankLessThan(max_c, begin_pos)
			+ RankLessThan(min_c, begin_pos);
	}

	void WatArray::MaxRange(unsigned int begin_pos, unsigned int end_pos, unsigned int& pos, unsigned int& val) const {
		QuantileRange(begin_pos, end_pos, end_pos - begin_pos - 1, pos, val);
	}

	void WatArray::MinRange(unsigned int begin_pos, unsigned int end_pos, unsigned int& pos, unsigned int& val) const {
		QuantileRange(begin_pos, end_pos, 0, pos, val);
	}

	void WatArray::QuantileRange(unsigned int begin_pos, unsigned int end_pos, unsigned int k, unsigned int& pos, unsigned int& val) const {
		if (end_pos > length_ || begin_pos >= end_pos) {
			pos = NOTFOUND;
			val = NOTFOUND;
			return;
		}

		val = 0;
		unsigned int beg_node = 0;
		unsigned int end_node = length_;
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			const BitArray& ba = bit_arrays_[i];
			unsigned int beg_node_zero = ba.Rank(0, beg_node);
			unsigned int end_node_zero = ba.Rank(0, end_node);
			unsigned int beg_node_one = beg_node - beg_node_zero;
			unsigned int beg_zero = ba.Rank(0, begin_pos);
			unsigned int end_zero = ba.Rank(0, end_pos);
			unsigned int beg_one = begin_pos - beg_zero;
			unsigned int end_one = end_pos - end_zero;
			unsigned int boundary = beg_node + end_node_zero - beg_node_zero;

			if (end_zero - beg_zero > k){
				end_node = boundary;
				begin_pos = beg_node + beg_zero - beg_node_zero;
				end_pos = beg_node + end_zero - beg_node_zero;
				val = val << 1;
			}
			else {
				beg_node = boundary;
				begin_pos = boundary + beg_one - beg_node_one;
				end_pos = boundary + end_one - beg_node_one;
				val = (val << 1) + 1;
				k -= end_zero - beg_zero;
			}
		}

		unsigned int rank = begin_pos - beg_node;
		pos = Select(val, rank + 1);
	}

	class WatArray::ListModeComparator{
	public:
		ListModeComparator() {}
		bool operator() (const QueryOnNode& lhs,
			const QueryOnNode& rhs) const {
			if (lhs.end_pos - lhs.beg_pos != rhs.end_pos - rhs.beg_pos) {
				return lhs.end_pos - lhs.beg_pos < rhs.end_pos - rhs.beg_pos;
			}
			else if (lhs.depth != rhs.depth) {
				return lhs.depth < rhs.depth;
			}
			else {
				return lhs.beg_pos > rhs.beg_pos;
			}
		}
	};

	class WatArray::ListMinComparator{
	public:
		ListMinComparator() {}
		bool operator() (const QueryOnNode& lhs,
			const QueryOnNode& rhs) const {
			if (lhs.depth != rhs.depth)
				return lhs.depth < rhs.depth;
			else return lhs.beg_node > rhs.beg_node;
		}
	};

	class WatArray::ListMaxComparator{
	public:
		ListMaxComparator() {}
		bool operator() (const QueryOnNode& lhs,
			const QueryOnNode& rhs) const {
			if (lhs.depth != rhs.depth)
				return lhs.depth < rhs.depth;
			else return lhs.beg_node < rhs.beg_node;
		}
	};

	void WatArray::ListModeRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos,
		unsigned int num, vector<ListResult>& res) const {
		ListRange<ListModeComparator>(min_c, max_c, beg_pos, end_pos, num, res);
	}

	void WatArray::ListMinRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos,
		unsigned int num, vector<ListResult>& res) const {
		ListRange<ListMinComparator>(min_c, max_c, beg_pos, end_pos, num, res);
	}

	void WatArray::ListMaxRange(unsigned int min_c, unsigned int max_c, unsigned int beg_pos, unsigned int end_pos,
		unsigned int num, vector<ListResult>& res) const {
		ListRange<ListMaxComparator>(min_c, max_c, beg_pos, end_pos, num, res);
	}

	bool WatArray::CheckPrefix(unsigned int prefix, unsigned int depth, unsigned int min_c, unsigned int max_c) const {
		if (PrefixCode(min_c, depth, alphabet_bit_num_) <= prefix &&
			PrefixCode(max_c - 1, depth, alphabet_bit_num_) >= prefix) return true;
		else return false;
	}

	void WatArray::ExpandNode(unsigned int min_c, unsigned int max_c,
		const QueryOnNode& qon, vector<QueryOnNode>& next) const{
		const BitArray& ba = bit_arrays_[qon.depth];

		unsigned int beg_node_zero = ba.Rank(0, qon.beg_node);
		unsigned int end_node_zero = ba.Rank(0, qon.end_node);
		unsigned int beg_node_one = qon.beg_node - beg_node_zero;
		unsigned int beg_zero = ba.Rank(0, qon.beg_pos);
		unsigned int end_zero = ba.Rank(0, qon.end_pos);
		unsigned int beg_one = qon.beg_pos - beg_zero;
		unsigned int end_one = qon.end_pos - end_zero;
		unsigned int boundary = qon.beg_node + end_node_zero - beg_node_zero;
		if (end_zero - beg_zero > 0){ // child for zero
			unsigned int next_prefix = qon.prefix_char << 1;
			if (CheckPrefix(next_prefix, qon.depth + 1, min_c, max_c)) {
				next.push_back(QueryOnNode(qon.beg_node,
					boundary,
					qon.beg_node + beg_zero - beg_node_zero,
					qon.beg_node + end_zero - beg_node_zero,
					qon.depth + 1,
					next_prefix));
			}
		}
		if (end_one - beg_one > 0){ // child for one
			unsigned int next_prefix = (qon.prefix_char << 1) + 1;
			if (CheckPrefix(next_prefix, qon.depth + 1, min_c, max_c)) {
				next.push_back(QueryOnNode(boundary,
					qon.end_node,
					boundary + beg_one - beg_node_one,
					boundary + end_one - beg_node_one,
					qon.depth + 1,
					next_prefix));
			}
		}
	}

	unsigned int WatArray::Freq(unsigned int c) const {
		if (c >= alphabet_num_) return NOTFOUND;
		return occs_.Select(1, c + 2) - occs_.Select(1, c + 1) - 1;
	}

	unsigned int WatArray::FreqSum(unsigned int min_c, unsigned int max_c) const {
		if (max_c > alphabet_num_ || min_c > max_c) return NOTFOUND;
		return occs_.Select(1, max_c + 1) - occs_.Select(1, min_c + 1) - (max_c - min_c);
	}

	unsigned int WatArray::alphabet_num() const{
		return alphabet_num_;
	}

	unsigned int WatArray::length() const{
		return length_;
	}

	unsigned int WatArray::GetAlphabetNum(const std::vector<unsigned int>& array) const {
		unsigned int alphabet_num = 0;
		for (size_t i = 0; i < array.size(); ++i){
			if (array[i] >= alphabet_num){
				alphabet_num = array[i] + 1;
			}
		}
		return alphabet_num;
	}

	unsigned int WatArray::Log2(unsigned int x) const{
		if (x == 0) return 0;
		x--;
		unsigned int bit_num = 0;
		while (x >> bit_num){
			++bit_num;
		}
		return bit_num;
	}

	unsigned int WatArray::PrefixCode(unsigned int x, unsigned int len, unsigned int bit_num) const{
		return x >> (bit_num - len);
	}

	unsigned int WatArray::GetMSB(unsigned int x, unsigned int pos, unsigned int len) {
		return (x >> (len - (pos + 1))) & 1LLU;
	}

	unsigned int WatArray::GetLSB(unsigned int x, unsigned int pos) {
		return (x >> pos) & 1LLU;
	}

	void WatArray::SetArray(const vector<unsigned int>& array) {
		if (alphabet_num_ == 0) return;
		bit_arrays_.resize(alphabet_bit_num_, length_);

		vector<vector<unsigned int> > beg_poses;
		GetBegPoses(array, alphabet_bit_num_, beg_poses);

		for (size_t i = 0; i < array.size(); ++i){
			unsigned int c = array[i];
			for (unsigned int j = 0; j < alphabet_bit_num_; ++j){
				unsigned int prefix_code = PrefixCode(c, j, alphabet_bit_num_);
				unsigned int bit_pos = beg_poses[j][prefix_code]++;
				bit_arrays_[j].SetBit(GetMSB(c, j, alphabet_bit_num_), bit_pos);
			}
		}

		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			bit_arrays_[i].Build();
		}
	}

	void WatArray::SetOccs(const vector<unsigned int>& array){
		vector<unsigned int> counts(alphabet_num_);
		for (size_t i = 0; i < array.size(); ++i){
			counts[array[i]]++;
		}

		occs_.Init(array.size() + alphabet_num_ + 1);
		unsigned int sum = 0;
		for (size_t i = 0; i < counts.size(); ++i){
			occs_.SetBit(1, sum);
			sum += counts[i] + 1;
		}
		occs_.SetBit(1, sum);
		occs_.Build();
	}

	void WatArray::GetBegPoses(const vector<unsigned int>& array,
		unsigned int alpha_bit_num,
		vector< vector<unsigned int> >& beg_poses) const{
		beg_poses.resize(alpha_bit_num);
		for (unsigned int i = 0; i < beg_poses.size(); ++i){
			beg_poses[i].resize(1 << i);
		}

		for (size_t i = 0; i < array.size(); ++i){
			unsigned int c = array[i];
			for (unsigned int j = 0; j < alpha_bit_num; ++j){
				beg_poses[j][PrefixCode(c, j, alpha_bit_num)]++;
			}
		}

		for (size_t i = 0; i < beg_poses.size(); ++i){
			unsigned int sum = 0;
			vector<unsigned int>& beg_poses_level = beg_poses[i];
			for (size_t j = 0; j < beg_poses_level.size(); ++j){
				unsigned int num = beg_poses_level[j];
				beg_poses_level[j] = sum;
				sum += num;
			}
		}
	}

	void WatArray::Save(ostream& os) const{
		os.write((const char*)(&alphabet_num_), sizeof(alphabet_num_));
		os.write((const char*)(&length_), sizeof(length_));
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			bit_arrays_[i].Save(os);
		}
		occs_.Save(os);
	}

	void WatArray::Load(istream& is){
		Clear();
		is.read((char*)(&alphabet_num_), sizeof(alphabet_num_));
		alphabet_bit_num_ = Log2(alphabet_num_);
		is.read((char*)(&length_), sizeof(length_));

		bit_arrays_.resize(alphabet_bit_num_);
		for (size_t i = 0; i < bit_arrays_.size(); ++i){
			bit_arrays_[i].Load(is);
			bit_arrays_[i].Build();
		}
		occs_.Load(is);
		occs_.Build();
	}

}

int main() {
	std::ios::sync_with_stdio(false);

	string s;
	cin >> s;

	vector<unsigned int> A(s.size() + 1, (1 << 20) - 1);
	vector<int> stk;
	REP(i, s.size()) {
		if (s[i] == '(') {
			stk.push_back(i + 1);
		}
		else {
			if (stk.empty()) {
				continue;
			}

			A[stk.back()] = i + 1;
			stk.pop_back();
		}
	}

	wat_array::WatArray wa;
	wa.Init(A);

	int m;
	cin >> m;
	REP(i, m) {
		int l, r;
		cin >> l >> r;

		cout << wa.FreqRange(0, r + 1, l, r + 1) * 2 << endl;;
	}
}


//Sareja & Brackets
//Segment Tree :-
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<utility>
#include<cstring>
#include<cmath>
#define LL long long int
#define mod 1000000007
#define vi vector<int>
#define vvi vector < vi >
#define pii pair<int,int>
#define all(c) c.begin(),c.end()
#define sf(x) scanf("%d",&x);
#define sf2(x,y) scanf("%d%d",&x,&y);
#define mem(a,val) memset(a,val,sizeof(a))
#define nl printf("\n");
#define pb push_back
#define mp make_pair
#define f first
#define s second
using namespace std;
struct segment
{   int left;
    int right;
    int ans;
}tree[5000005];
char str[1000005];
void build(int node,int a,int b)
{   if(a>b) return ;
    if(a==b)
    {   if(str[a]=='(')
        {   tree[node].left=1;
            tree[node].right=0;
            tree[node].ans=0;
        }
        else if(str[a]==')')
        {   tree[node].left=0;
            tree[node].right=1;
            tree[node].ans=0;
        }
        return ;
    }
    build(2*node,a,(a+b)/2);
    build(2*node+1,(a+b)/2+1,b);
    tree[node].left=tree[2*node].left+tree[2*node+1].left-min(tree[2*node].left,tree[2*node+1].right);
    tree[node].right=tree[2*node].right+tree[2*node+1].right-min(tree[2*node].left,tree[2*node+1].right);
    tree[node].ans=tree[2*node].ans+tree[2*node+1].ans+2*min(tree[2*node].left,tree[2*node+1].right);
    return ;
}
struct segment query(int node,int a,int b,int start,int end)
{   struct segment x,y,temp;
    if(a>b||b<start||a>end)
    {   temp.left=0;
        temp.right=0;
        temp.ans=0;
        return temp;
    }
    if(a>=start&&b<=end) return tree[node];
    x=query(2*node,a,(a+b)/2,start,end);
    y=query(2*node+1,(a+b)/2+1,b,start,end);
    temp.left=x.left+y.left-min(x.left,y.right);
    temp.right=x.right+y.right-min(x.left,y.right);
    temp.ans=x.ans+y.ans+2*min(x.left,y.right);
    return temp;
}
void debug()
{   int i;
    for(i=1;i<=12;i++)
        printf("%d ",tree[i].ans);
    nl;
}
int main()
{   int t,i,j,Q,l,r,len;
    struct segment val;
    gets(str+1);
    len=strlen(str+1);
    build(1,1,len);
    //debug();
    sf(Q);
    while(Q--)
    {   sf2(l,r);
        val=query(1,1,len,l,r);
        printf("%d\n",val.ans);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int Nmax = 1e6 + 1;

struct Node
{
    int sol;
    int open;
    int closed;
};

Node A[4 * Nmax];
string str;
int N, M;

Node merge(const Node& left, const Node& right)
{
    Node ans = { 0, 0, 0 };

    int t = min( left.open, right.closed );

    ans.sol = left.sol + right.sol + t;
    ans.open = left.open + right.open - t;
    ans.closed = left.closed + right.closed - t;

    return ans;
}

void build(int nod, int st, int dr)
{
    if ( st == dr )
    {
        A[nod].sol = 0;
        A[nod].open = (str[st - 1] == '(');
        A[nod].closed = (str[st - 1] == ')');
    }
    else
    {
        int m = ( st + dr ) / 2;

        build(2 * nod, st, m);
        build(2 * nod + 1, m + 1, dr);

        A[nod] = merge(A[2 * nod], A[2 * nod + 1]);
    }
}

Node query(int nod, int st, int dr, int st_q, int dr_q)
{
    if ( st_q <= st && dr <= dr_q )
    {
        return A[nod];
    }
    else
    {
        int m = ( st + dr ) / 2;
        Node sol = { 0, 0, 0 };

        if ( st_q <= m )
            sol = merge(sol, query(2 * nod, st, m, st_q, dr_q) );

        if ( m < dr_q )
            sol = merge(sol, query(2 * nod + 1, m + 1, dr, st_q, dr_q) );

        return sol;
    }
}

int main()
{
    ///ifstream cin("data.in");

    ios_base::sync_with_stdio( false );

    cin >> str;
    N = str.size();

    build( 1, 1, N );

    cin >> M;

    while ( M-- )
    {
        int a, b;

        cin >> a >> b;
        cout << 2 * query(1, 1, N, a, b).sol << "\n";
    }

    return 0;
}


#include <iostream>

using namespace std;

struct b{
    int v=0;
    int l=0;
    int r=0;
};
const int N=1<<20;
b st[2*N];
b mer(b l, b r){
    b re;
    re.v=l.v+r.v+min(l.l, r.r);
    re.l=l.l+r.l-min(l.l, r.r);
    re.r=l.r+r.r-min(l.l, r.r);
    return re;
}
void init(int i){
    if (i>=N) return;
    init(i*2);
    init(i*2+1);
    st[i]=mer(st[i*2], st[i*2+1]);
}

b get(int i, int stl, int str, int l, int r){
    if (l>str||r<stl) return b();
    if (l<=stl&&str<=r){
        return st[i];
    }
    else{
        int m=(stl+str)/2;
        return mer(get(i*2, stl, m, l, r), get(i*2+1, m+1, str, l, r));
    }
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    string s;
    cin>>s;
    int n=s.size();
    int q;
    cin>>q;
    for (int i=0;i<n;i++){
        if (s[i]=='(') st[i+N].l=1;
        if (s[i]==')') st[i+N].r=1;
    }
    init(1);
    for (int i=0;i<q;i++){
        int a, b;
        cin>>a>>b;
        cout<<get(1, 0, N-1, a-1, b-1).v*2<<'\n';
    }
}


/*
    Author: Zhouxing Shi
    Created on Oct29, 2014
*/
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define drep(i, a, b) for (int i = (a); i >= (b); --i)
#define REP(i, a, b) for (int i = (a); i < (b); ++i)
#define pb(x) push_back(x)
#define mp(x, y) (make_pair(x, y))
#define clr(x) memset(x, 0, sizeof(x))
#define xx first
#define yy second

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int inf = ~0U >> 1;
const ll INF = ~0ULL >> 1;
template <class T> inline void read(T &n)
{
    char c;
    for (c = getchar(); !(c >= '0' && c <= '9'); c = getchar()); n = c - '0';
    for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) n = n * 10 + c - '0';
}
int Pow(int base, int n, int mo)
{
    if (n == 0) return 1;
    if (n == 1) return base % mo;
    int tmp = Pow(base, n >> 1, mo);
    tmp = (ll)tmp * tmp % mo;
    if (n & 1) tmp = (ll)tmp * base % mo;
    return tmp;
}
//***************************

const int maxn = 1200000;
struct node
{
	int l, r, cur, s;
	int left, right;
} t[maxn * 5];
char s[maxn];
int N, m, x, y;

void upd(int p)
{
	int l = p << 1, r = p << 1 | 1;
	t[p].s = t[l].s + t[r].s;
	int d = min(t[p << 1].left, t[p << 1 | 1].right);
	t[p].s += d;
	t[p].left = t[p << 1].left + t[p << 1 | 1].left - d;
	t[p].right = t[p << 1].right + t[p << 1 | 1].right - d;
}

void build(int p, int l, int r)
{
	t[p].l = l;
	t[p].r = r;
	if (l != r)
	{
		build(p << 1, l, l + r >> 1);
		build(p << 1 | 1, (l + r >> 1) + 1, r);
		upd(p);
	}
	else
	{
		if (s[l] == '(') t[p].left = 1;
		else t[p].right = 1;
	}
}

node query(int p, int l, int r)
{
	if (t[p].l == l && t[p].r == r) return t[p];
	int m = t[p].l + t[p].r >> 1;
	if (r <= m) return query(p << 1, l, r);
	else if (l > m) return query(p << 1 | 1, l, r);
	else
	{
		node x = query(p << 1, l, m);
		node y = query(p << 1 | 1, m + 1, r);
		int d = min(x.left, y.right);
		node ans;
		ans.s = x.s + y.s;
		ans.cur = 0;
		ans.s += d;
		ans.left = x.left + y.left - d;
		ans.right = x.right + y.right - d;
		return ans;
	}
}

int main()
{
	scanf("%s", s + 1);
	N = strlen(s + 1);
	build(1, 1, N);
	scanf("%d", &m);
	while (m--)
	{
		scanf("%d%d", &x, &y);
		node ans = query(1, x, y);
		printf("%d\n", ans.s * 2);
	}
    return 0;
}


#include <bits/stdc++.h>
#define L first
#define R second
#define MP make_pair
#define PB push_back

using namespace std;

const int maxn = 1000 * 1000 + 10;
string s;
int n, seg[4 * maxn], open[4 * maxn], close[4 * maxn];

void modify(int L = 0, int R = n, int id = 1) {
	if(R - L == 1) {
		if(s[L] == ')')
			close[id] ++;
		else
			open[id] ++;
		return;
	}
	int mid = (L + R) / 2;
	modify(L, mid, id * 2 + 0);
	modify(mid, R, id * 2 + 1);
	int New = min(open[id * 2 + 0], close[id * 2 + 1]);
	seg[id] = seg[id * 2 + 0] + seg[id * 2 + 1] + 2 * New;
	close[id] = close[id * 2 + 0] + close[id * 2 + 1] - New;
	open[id] = open[id * 2 + 1] + open[id * 2 + 0] - New;
}

void get(int l, int r, int &Open, int &ret, int L = 0, int R = n, int id = 1) {
	if(l == L and r == R) {
		ret += seg[id];
		ret += 2 * min(Open, close[id]);
		Open -= min(Open, close[id]);
		Open += open[id];
		return;
	}
	int mid = (L + R) / 2;
	if(l < mid) get(l, min(r, mid), Open, ret, L, mid, id * 2 + 0);
	if(r > mid) get(max(l, mid), r, Open, ret, mid, R, id * 2 + 1);
}

main() {
	cin >> s;
	n = s.size();
	modify();
	int q, l, r, ret, Open;
	cin >> q;
	while(q --> 0)
		cin >> l >> r,
		Open = 0,
		ret = 0,
		get(--l, r, Open, ret),
		cout << ret << endl;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <utility>
#include <algorithm>

#define MAXN 1000100
#define MAXM 100010
#define X first
#define Y second

using namespace std;

typedef pair<int, int> Pii;

char str[MAXN];
int q[MAXM][2], d[MAXM], ans[MAXM], stk[MAXN], top;
Pii x[MAXM << 1];

void solve(int n, int m) {
    int i, j, id, p, cnt = 0, cur = 0;

    for (i = 1; i <= m; ++i) {
        x[cnt++] = make_pair(--q[i][0], i);
        x[cnt++] = make_pair(q[i][1], -i);
    }
    sort(x, x + cnt);

    memset(d, 0, sizeof(d));
    memset(ans, 0, sizeof(ans));
    for (i = 1; i < cnt; ++i) {
        for (j = x[i - 1].X; j < x[i].X; ++j) {
            if (str[j] == '(') stk[++top] = j;
            else if (top) {
                ++cur; --top;
            }
        }
        id = abs(x[i].Y);
        if (x[i].Y > 0) {
            d[id] = top; ans[id] -= cur;
        } else {
            ans[id] += cur;
            p = lower_bound(stk + 1, stk + top + 1, q[id][0]) - stk - 1;
            ans[id] -= d[id] - p;
        }
    }
}

int main() {
    int n, m, i;

    while (~scanf("%s", str)) {
        n = strlen(str);
        scanf("%d", &m);
        for (i = 1; i <= m; ++i) scanf("%d%d", &q[i][0], &q[i][1]);
        solve(n, m);
        for (i = 1; i <= m; ++i) printf("%d\n", ans[i] << 1);
    }

    return 0;
}


#include <iostream>
using namespace std;
typedef long long ll;
#define Size(x) (int)(x).size()

const int N = 1000 * 1000 + 5;

struct node{
	int X, Y, Z;
};

class segment{
	int P[4 * N], Q[4 * N];
	node f[4 * N];

	node merge(node a, node b) {
		int tmp = min(a.Z, b.X);
		node ans;
		ans.Y = a.Y + b.Y + (tmp << 1);
		a.Z -= tmp;
		b.X -= tmp;
		ans.X = a.X + b.X;
		ans.Z = a.Z + b.Z;
		return ans;
	}
public:
	void build(int x, int p, int q, const string &s) {
		P[x] = p;
		Q[x] = q;
		if(p == q) {
			if(s[p - 1] == '(')
				++f[x].Z;
			else
				++f[x].X;
// 			cerr << x << " " << p << " " << q << " " << f[x].X << " " << f[x].Y << " " << f[x].Z << endl;
			return ;
		}
		int m = (p + q) >> 1;
		build(x << 1, p, m, s);
		build((x << 1) + 1, m + 1, q, s);
		f[x] = merge(f[x << 1], f[(x << 1) + 1]);
// 		cerr << x << " " << p << " " << q << " " << f[x].X << " " << f[x].Y << " " << f[x].Z << endl;
	}
	node find(int x, int p, int q) {
		if(P[x] == p && Q[x] == q)
			return f[x];
		int m = (P[x] + Q[x]) >> 1;
		if(q <= m)
			return find(x << 1, p, q);
		else {
			if(p > m)
				return find((x << 1) + 1, p, q);
			else {
				node t1 = find(x << 1, p, m), t2 = find((x << 1) + 1, m + 1, q);
				return merge(t1, t2);
			}
		}
	}
} T;

string input;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cin >>  input;
	T.build(1, 1, Size(input), input);
	//////
	int m;
	cin >> m;
	while(m--) {
		int a, b;
		cin >> a >> b;
		node tmp = T.find(1, a, b);
		cout << tmp.Y << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0,p=(b+c+d)/2;

		x=a;y=b;z=c;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x,y,z;
		x=a+1;
		y=b+1;
		z=c+1;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0,p=(b+c+d)/2;

		if(b==a)
		x=b;
		else{
		x=a+1;
		if(x>=p)
		x=x-1;

	}
		if(c==b)
		y=c;
		else{
		y=b+1;
		if(y>=p)
		y=y-1;

	}
		if(d==c)
		z=d;
		else
		{
			z=c+1;
			if(z>=p)
			z=z-1;

		}
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0;

		if(b==a)
		x=b;
		else
		x=a+1;
		if(c==b)
		y=c;
		else
		y=b+1;
		if(d==c)
		z=d;
		else
		z=c+1;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x,y,z;

		if(b==a)
		x=b;
		else
		x+=1;
		if(c==b)
		y=c;
		else
		z=c+1;
		if(d==c)
		z=d;
		else
		z=z+1;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0,p=(b+c+d)/2;

		x=b;y=c;z=d;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0;

		if(b==a)
		x=b;
		else
		x=b-1;
		if(c==b)
		y=c;
		else
		y=c-1;
		if(d==c)
		z=d;
		else
		z=d-1;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x,y,z;

		if(b==a)
		x=b;
		else
		x=a+1;
		if(c==b)
		y=c;
		else
		y=b+1;
		if(d==c)
		z=d;
		else
		z=c+1;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0,p=(b+c+d)/2;

		x=a;y=b;z=c;
		cout<<x<<" "<<y<<" "<<y<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0;

		if(b==a)
		x=b;
		else
		x=(a+b)/2;
		if(c==b)
		y=c;
		else
		y=(b+c)/2;
		if(d==c)
		z=d;
		else
		z=(c+d)/2;
		cout<<x<<" "<<y<<" "<<z<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		long long int a,b,c,d;
		cin>>a>>b>>c>>d;
		int x=0,y=0,z=0,p=(b+c+d)/2;

		x=a;y=b;z=c;
		cout<<b<<" "<<c<<" "<<c<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;

		if (a + b > c)
			cout << a << " " << b << " " << c << "\n";
		else if (a + c > d)
			cout << a << " " << c << " " << d << "\n";
		else if (a + b > d)
			cout << a << " " << b << " " << d << "\n";
		else if (b + c > d)
			cout << b << " " << c << " " << d << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
bool checkt(int a, int b, int c) {

	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		ll: int a, b, c, d;
		cin >> a >> b >> c >> d;
		int f = 0;
		for (int i = a; i <= b; ++i) {
			for (int j = b; j <= c; ++j)
				for (int k = c; k <= d; ++k) {
					if (checkt(i, j, k)) {
						cout << i << " " << j << " " << k << "\n";
						f = 1;
						goto ll;
					}
				}

		}

	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;

		if (a + b > c)
			cout << a << " " << b << " " << c << "\n";
		else if (a + b > d)
			cout << a << " " << b << " " << d << "\n";
		else if (b + c > d)
			cout << b << " " << c << " " << d << "\n";
		else if ((2 * b) > d)
			cout << b << " " << b << " " << d << "\n";
		else if ((2 * c) > d)
			cout << c << " " << c << " " << d << "\n";
	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;

		if (a + b >= c)
			cout << a << " " << b << " " << c << "\n";
		else if (a + c >= d)
			cout << a << " " << c << " " << d << "\n";
		else if (a + b >= d)
			cout << a << " " << b << " " << d << "\n";
		else if (b + c >= d)
			cout << b << " " << c << " " << d << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
bool checkt(int a, int b, int c) {

	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		ll: int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (a + b <= c)
			cout << a << " " << b << " " << c;
		else
			cout << a << " " << b << " " << d;

//		for (int i = a; i <= b; ++i) {
//			for (int j = b; j <= c; ++j)
//				for (int k = c; k <= d; ++k) {
//					if (checkt(i, j, k)) {
//						cout << i << " " << j << " " << k << "\n";
//						f = 1;
//						goto ll;
//					}
//				}
//
//		}

	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long
bool tt(int a, int b, int c) {
	// check condition
	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (tt(a, b, c))
			cout << a << " " << b << " " << c << "\n";
		else if (tt(a, b, d))
			cout << a << " " << b << " " << d << "\n";
		else if (tt(b, c, d))
			cout << b << " " << c << " " << d << "\n";
		else if (tt(b, b, d))
			cout << b << " " << b << " " << d << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
bool checkt(int a, int b, int c) {

	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (a + b <= c)
			cout << a << " " << b << " " << c;
		else
			cout << a << " " << b << " " << d;

//		for (int i = a; i <= b; ++i) {
//			for (int j = b; j <= c; ++j)
//				for (int k = c; k <= d; ++k) {
//					if (checkt(i, j, k)) {
//						cout << i << " " << j << " " << k << "\n";
//						f = 1;
//						goto ll;
//					}
//				}
//
//		}
		cout << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long
bool tt(int a, int b, int c) {
	// check condition
	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (tt(a, b, c))
			cout << a << " " << b << " " << c << "\n";
		else if (tt(b, b, c))
			cout << b << " " << b << " " << c << "\n";
		else if (tt(a, c, c))
			cout << a << " " << c << " " << c << "\n";
		else if (tt(b, c, c))
			cout << b << " " << c << " " << c << "\n";
		else if (tt(a, b, d))
			cout << a << " " << b << " " << d << "\n";
		else if (tt(b, b, d))
			cout << b << " " << b << " " << d << "\n";
		else if (tt(a, c, d))
			cout << a << " " << c << " " << d << "\n";
		else if (tt(b, c, d))
			cout << b << " " << c << " " << d << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
bool checkt(int a, int b, int c) {

	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int main() {
	int t;
	cin >> t;
	while (t--) {
		ll: int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (a + b <= c) {
			cout << a << " " << b << " " << c << "\n";
			goto ll;
		} else if (a + b <= d) {
			cout << a << " " << b << " " << d << "\n";
			goto ll;
		}

		else if (a + c <= d) {
			cout << a << " " << b << " " << c;
			goto ll;
		} else if (a + c <= d) {

			cout << a << " " << b << " " << d;
			goto ll;
		}
//		for (int i = a; i <= b; ++i) {
//			for (int j = b; j <= c; ++j)
//				for (int k = c; k <= d; ++k) {
//					if (checkt(i, j, k)) {
//						cout << i << " " << j << " " << k << "\n";
//						f = 1;
//						goto ll;
//					}
//				}
//
//		}
		//cout << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (a + b <= c) {
			cout << a << " " << b << " " << c << "\n";
			//		goto ll;
		} else if (a + b <= d) {
			cout << a << " " << b << " " << d << "\n";
//			goto ll;
		}

		else if (a + c <= d) {
			cout << a << " " << b << " " << c;

		} else if (a + c <= d) {

			cout << a << " " << b << " " << d;
		}

	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (a == b)
			cout << a << " " << b << " " << c << "\n";
		else if (b == c)
			cout << a << " " << b << " " << d << "\n";
		else if (c == d)
			cout << a << " " << b << " " << d << "\n";
		else
			cout << a << " " << b << " " << d << "\n";
	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t mainss() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;

		if (a + b > c)
			cout << a << " " << b << " " << c << "\n";
		else if (a + b > d)
			cout << a << " " << b << " " << d << "\n";
		else if (b + c > d)
			cout << b << " " << c << " " << d << "\n";
		else if (2 * b > d)
			cout << b << " " << b << " " << d << "\n";
		else if (2 * c > d)
			cout << c << " " << c << " " << d << "\n";
	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long
bool tt(int a, int b, int c) {
	// check condition
	if (a + b <= c || a + c <= b || b + c <= a)
		return false;
	else
		return true;
}

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (tt(a, b, c))
			cout << a << " " << b << " " << c << "\n";
		else if (tt(a, b, d))
			cout << a << " " << b << " " << d << "\n";
		else if (tt(b, c, d))
			cout << b << " " << c << " " << d << "\n";
		else if (tt(b, b, d))
			cout << b << " " << b << " " << d << "\n";
		else if (tt(a, c, d))
			cout << a << " " << c << " " << d << "\n";
	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;

		if (a + b > c)
			cout << a << " " << b << " " << c << "\n";
		else if (a + b > d)
			cout << a << " " << b << " " << d << "\n";
		else if (b + c > d)
			cout << b << " " << c << " " << d << "\n";

	}

}


#include<bits/stdc++.h>
using namespace std;
#define int long long

int32_t main() {
	int t;
	cin >> t;
	while (t--) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		if (a + b > c)
			cout << a << " " << b << " " << c << "\n";
		else if (a + b > d)
			cout << a << " " << b << " " << d << "\n";
		else if (b + c > d)
			cout << b << " " << c << " " << d << "\n";
		else if ((2 * b) > d)
			cout << b << " " << b << " " << d << "\n";
		else if ((2 * b) > c)
			cout << b << " " << b << " " << c << "\n";

	}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;
    if(a+b>=c) cout<<a<<" "<<b<<" "<<c<<endl;
    else{
        if(c+b>=d) cout<<b<<" "<<c<<" "<<d<<endl;
    else{
         if(a+c>=d) cout<<a<<" "<<c<<" "<<d<<endl;
    else{
         cout<<a<<" "<<b<<" "<<d<<endl;
    }
    }
    }

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;
    if(a+b>=c)
    cout<<a<<" "<<b<<" "<<c<<endl;
    else cout<<b<<" "<<c<<" "<<d<<endl;
}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;
    if(c+b>=a) cout<<a<<" "<<b<<" "<<c<<endl;
    else{
        if(c+d>=b) cout<<b<<" "<<c<<" "<<d<<endl;
    else{
         if(d+c>=a) cout<<a<<" "<<c<<" "<<d<<endl;
    else{
         cout<<a<<" "<<b<<" "<<d<<endl;
    }
    }
    }

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

 ll x=(a+b)/2;
 ll y=(b+c)/2;
 ll z=(c+d)/2;
 cout<<x<<" "<<y<<" "<<z<<endl;

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

 ll x=b;
 ll y=b;
 ll z=c;

 ll dd=2*b;
 if(dd>=c) cout<<x<<" "<<y<<" "<<z<<endl;
 else{
    while(x+y<c)
    {
        y++;
    }
    cout<<x<<" "<<y<<" "<<z<<endl;
 }

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

 ll x=b;
 ll y=b;
 ll z=c;

 ll dd=2*b;
 if(dd>c) cout<<x<<" "<<y<<" "<<z<<endl;
 else{
    while(x+y<=c)
    {
        y++;
    }
    cout<<x<<" "<<y<<" "<<z<<endl;
 }

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

 ll x=b;
 ll y=b;
 ll z=c;

 ll dd=2*b;
 if(dd>c) cout<<x<<" "<<y<<" "<<z<<endl;
 else{
    ll l=b;
 ll r=c;

    cout<<x<<" "<<c<<" "<<c<<endl;
 }

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

     cout<<b<<" "<<d<<" "<<d<<endl;
}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;

   cout<<b<<" "<<b<<" "<<max(b-1,a)<<endl;

}

}


#include<bits/stdc++.h>
#define pb push_back
#define ll long long int
#define ld long double
#define vsort(v) sort(v.begin(),v.end())
#define vrsort(v) sort(v.begin(),v.end(),greater<int>())
#define mset(a) memset(a,0,sizeof(a))
#define rep(i,n) for(int i=0;i<n;i++)
#define all(x) x.begin(),x.end()
#define mm INT_MAX
#define ulta(a) reverse(a.begin(),a.end())
#define out(a) for(auto x:a) cout<<x<<" ";
#define sp(arr) sort(arr,arr+sizeof(arr)/sizeof(arr[0]));
#define bolt ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

using namespace std;

int main()
{
bolt

int t;
cin>>t;
while(t-->0)
{

    ll a,b,c,d;
    cin>>a;
    cin>>b;
    cin>>c;
    cin>>d;
    cout<<a<<" "<<b<<" "<<c<<endl;
}

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
	int t;
	cin >> t;
	while(t--)
	{
	    ll a,b,c,d;
	    cin >> a >> b >> c >> d;
	    ll x,y,z;
	    x = a;
	    	        bool f = false;
	    while(x <= b)
	    {

	        if(x+b > c && b+c>x && x+c > b)
	        {
	            y = b;
	            z=c;
	            f= true;
	            break;
	        }
	        else
	        {
	        x++;
	        }
	    }
	    if(x+y > z && y+z>x && x+z > y)
	    {
	        if(f)
	    cout << x << " " << y << " "<< z << "\n";
	    else
	    {
	        cout << x-1 << " " << y << " "<< z << "\n";

	    }
	    }
	    else
	    {
	        x = b;
	        bool e = false;
	    while(x <= c)
	    {
	        if(x+c > d && c+d>x && x+d > c)
	        {
	            y = c;
	            z=d;
	            e = true;
	            break;
	        }
	        else
	        {
	        x++;
	        }
	    }
	    if(x+y > z && y+z >x && x+z > y)
	    {
	        if(e)
	        {
	            cout << x << " " << y << " " << z << "\n";
	        }
	        else
	        {
	            cout << x-1 << " " << y << " " << z << "\n";
	        }
	    }
	    else
	    {
	        x = b;
	        y = c;
	        if(c==d)
	        {
	            z = c;
	        }
	        else
	        {
	            z = c+1;
	        }
	        cout << x << " " << y << " " << z << "\n";
	    }
	    }
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
	int t;
	cin >> t;
	while(t--)
	{
	    ll a,b,c,d;
	    cin >> a >> b >> c >> d;
	    ll x,y,z;
	    x = c;
	    if(b==c)
	    {
	        y = c;
	    }
	    else
	    {
	        y = c-1;
	    }
	    if(c==d)
	    {
	        z = c;
	    }
	    else
	    {
	        z = c+1;
	    }
	    cout << x << " " << y << " "<< z << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
	int t;
	cin >> t;
	while(t--)
	{
	    ll a,b,c,d;
	    cin >> a >> b >> c >> d;
	    ll x,y,z;
	    x = a;
	    	        bool f = false;
	    while(x <= b)
	    {

	        if(x+b > c && b+c>x && x+c > b)
	        {
	            y = b;
	            z=c;
	            f= true;
	            break;
	        }
	        else
	        {
	        x++;
	        }
	    }
	    if(x+y > z && y+z>x && x+z > y)
	    {
	        if(f)
	    cout << x << " " << y << " "<< z << "\n";
	    else
	    {
	        cout << x << " " << y << " "<< z << "\n";

	    }
	    }
	    else
	    {
	        x = b;
	        bool e = false;
	    while(x <= c)
	    {
	        if(x+c > d && c+d>x && x+d > c)
	        {
	            y = c;
	            z=d;
	            e = true;
	            break;
	        }
	        else
	        {
	        x++;
	        }
	    }
	    if(x+y > z && y+z > x && x+z > y)
	    {
	        if(e)
	        {
	            cout << x << " " << y << " " << z << "\n";
	        }
	        else
	        {
	            cout << x-1 << " " << y << " " << z << "\n";
	        }
	    }
	    }
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main() {
	int t;
	cin >> t;
	while(t--)
	{
	    ll a,b,c,d;
	    cin >> a >> b >> c >> d;
	    ll x,y,z;

	        x = b;
	        y = c;
	        if(c==d)
	        {
	            z = c;
	        }
	        else
	        {
	            z = c+1;
	        }
	        cout << x << " " << y << " " << z << "\n";
	    }

	return 0;
}


#include <iostream>
#define ll long long
using namespace std;

int main() {
	int t;
	cin >> t;
	while(t--)
	{
	    ll a,b,c,d;
	    cin >> a >> b >> c >> d;
	    cout << b << " " << c << " " << c << "\n";

	}
	return 0;
}