Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

文字列 S と， m 個のクエリが与えられる．i 番目のクエリは二つの文字列 xi, yi で与えられる．

各クエリについて，文字列 S の部分文字列であり， xi で始まり yi で終わるものの中で，最長の長さを答えよ．

文字列 S について， |S| は S の長さを表す．また，文字列 T が文字列 S の部分文字列であるとは，ある整数 i が存在して， 1 ≤ j ≤ |T| に対して Tj = Si+j を満たすことを言う．ただし Tj は T の j 番目の文字を表す．

Input

入力は以下の形式で与えられる．

S
m
x1 y1
x2 y2
:
xm ym

1 行目には，文字列 S が与えられる．

2 行目には，クエリの個数 m が与えられる．

3 行目からの m 行のうち i 行目には i 番目のクエリ文字列 xi, yi が空白区切りで与えられる．

Constraints

1 ≤ |S| ≤ 2 × 105

1 ≤ m ≤ 105

1 ≤ |xi|, |yi|

$\sum^m_{i=1}$ (|xi| + |yi|) ≤ 2 × 105

S 及び xi, yi は，半角の英小文字のみからなる．

Output

以下の形式で最大の部分文字列の長さを答えよ．

len1
len2
:
lenm

1 行目からの m 行のうち i 行目には， i 番目のクエリについて，条件を満たす最長の部分文字列の長さ leni を出力せよ．そのような部分文字列がない場合，0 を出力せよ．

Sample Input 1

abracadabra
5
ab a
a a
b c
ac ca
z z

Output for the Sample Input 1

11
11
4
3
0

文字列 S として，abracadabra が与えられる．

"ab" で始まり "a" で終わる部分文字列は，"abra" や "abraca", "abracada", "abracadabra" の4 種類があるが，最長の部分文字列は "abracadabra" で，長さは 11 である．

"a" で始まり "a" で終わる最長の部分文字列も同様に "abracadabra" で，長さは 11 である．

"b" で始まり "c" で終わる最長の部分文字列は "brac" で，長さは 4 である．

"ac" で始まり "ca" で終わる最長の部分文字列は "aca" で，長さは 3 である．

"z" で始まり "z" で終わる部分文字列は存在しない．よって0 を出力する．

Sample Input 2

howistheprogress
4
ist prog
s ss
how is
the progress

Output for the Sample Input 2

9
12
5
11

Sample Input 3

icpcsummertraining
9
mm m
icpc summer
train ing
summer mm
i c
i i
g g
train i
summer er

Output for the Sample Input 3

2
10
8
0
4
16
1
6
6

Solution in Ruby (judge verdict: Accepted)

class Array
	def bsearch_first_index(l = 0, r = size - 1, &pred)
		return nil if l > r
		c = (l + r) / 2 
		if pred[self[c]]
			bsearch_first_index(l, c-1, &pred) || c
		else
			bsearch_first_index(c+1, r, &pred)
		end
	end

	def bsearch_first_item(l = 0, r = size - 1, &pred)
		i = bsearch_first_index(l, r, &pred)
		i ? self[i] : nil
	end

	def bsearch_last_index(l = 0, r = size - 1, &pred)
		return nil if l > r
		c = (l + r) / 2 
		if pred[self[c]]
			bsearch_last_index(c+1, r, &pred) || c
		else
			bsearch_last_index(l, c-1, &pred)
		end
	end

	def bsearch_last_item(l = 0, r = size - 1, &pred)
		i = bsearch_last_index(l, r, &pred)
		i ? self[i] : nil
	end
end

class String
	def suffix_array
		buckets = {}
		(0..size-1).each do |i|
			(buckets[self[i]] ||= []) << i
		end	
		index_table = []
		r = 0
		rank = []
		buckets.keys.sort.each do |c|
			buckets[c].each do |i|
				rank[i] = r + buckets[c].size - 1
			end
			r += buckets[c].size
			index_table << buckets[c].pop until buckets[c].empty?
		end

		d = 1
		loop do
			i = 0
			loop do
				j = index_table[i]
				r = rank[j]
				if i == r
					i += 1
				else
					index_table.sa_sort!(i, r, rank, d)
					i = r + 1
				end
				break if i >= size
			end
			d <<= 1
			break if d >= self.size
		end

		index_table
	end	
end

class Array
	def sa_sort!(l, r, rank, d)
		if r <= l
			if l == r
				rank[self[l]] = l
			end
			return
		end
		pivot_idx = self[rand(r-l+1) + l]
		pivot_rank = (rank[pivot_idx + d] || -1)

		lesser = l
		greater = r
		i = l
		loop do
			break if i > greater
			target_rank = (rank[self[i] + d] || -1)
			if target_rank < pivot_rank
				self[i], self[lesser] = self[lesser], self[i]
				lesser += 1
				i += 1
			elsif target_rank > pivot_rank
		 		self[i], self[greater] = self[greater], self[i]
		 		greater -= 1
			else
				i += 1
			end
		end

		raise if greater < 0
		sa_sort!(l, lesser-1, rank, d)
		(lesser..greater).each do |i|
			rank[self[i]] = greater
		end
		sa_sort!(greater+1, r, rank, d)
	end
end

str = gets.chomp
# str = "abracadabra"
sa = str.suffix_array
# puts sa.map {|i| str[i..-1]}

class MinMaxSegmentTree
	def initialize(arr, l = 0, r = arr.size - 1)
		@l = l
		@r = r
		if l == r
			@min = @max = arr[l]
		else
			c = (l + r) / 2
			@left_child = self.class.new(arr, l, c)
			@min = @left_child.min
			@max = @left_child.max
			@right_child = self.class.new(arr, c+1, r)
			r_min, r_max = @right_child.min, @right_child.max
			@min = r_min if r_min < @min
			@max = r_max if r_max > @max
		end
	end

	def query_min(l = @l, r = @r)
		return @min if l == @l && r == @r
		if r <= @left_child.r
			return @left_child.query_min(l, r)
		elsif @right_child.l <= l
			return @right_child.query_min(l, r)
		else
			lm = @left_child.query_min(l, @left_child.r)
			rm = @right_child.query_min(@right_child.l, r)
			return lm < rm ? lm : rm
		end
	end

	def query_max(l = @l, r = @r)
		return @max if l == @l && r == @r
		if r <= @left_child.r
			return @left_child.query_max(l, r)
		elsif @right_child.l <= l
			return @right_child.query_max(l, r)
		else
			lm = @left_child.query_max(l, @left_child.r)
			rm = @right_child.query_max(@right_child.l, r)
			return lm > rm ? lm : rm
		end
	end

	attr_reader :min, :max, :l, :r
end

tree = MinMaxSegmentTree.new(sa)

n = gets.to_i
n.times do
	x, y = gets.chomp.split
	if x.size > str.size || y.size > str.size
		p 0
		next
	end

	k1 = sa.bsearch_first_index {|i| x <= str[i..i+x.size-1]}
	if !k1 || str[sa[k1]..sa[k1]+x.size-1] != x
		p 0
		next
	end
	k2 = sa.bsearch_last_index {|i| str[i..i+x.size-1] <= x}
# 	i = sa[k1..k2].min
	i = tree.query_min(k1, k2)

	k1 = sa.bsearch_first_index {|i| y <= str[i..i+y.size-1]}
	if !k1 || str[sa[k1]..sa[k1]+y.size-1] != y
		p 0
		next
	end
	k2 = sa.bsearch_last_index {|i| str[i..i+y.size-1] <= y}
# 	j = sa[k1..k2].max
	j = tree.query_max(k1, k2)

	if j + y.size < i + x.size 
		p 0
		next
	end

	p j - i + y.size
end