A regular expression is used to describe a set of strings. For this problem the alphabet is limited to 'a' and 'b'.

We define $\mbox{R}$ to be a valid regular expression if: 

1) $\mbox{R}$ is "$a$" or "$\boldsymbol{b}$". 

2) $\mbox{R}$ is of the form "$(R_1R_2)$", where $\boldsymbol{R_1}$ and $R_2$ are regular expressions. 

3) $\mbox{R}$ is of the form "$(R_1|R_2)$" where $\boldsymbol{R_1}$ and $R_2$ are regular expressions. 

4) $\mbox{R}$ is of the form "$(R_1*)$" where $\boldsymbol{R_1}$ is a regular expression.

Regular expressions can be nested and will always have have two elements in the parentheses. ('$*$' is an element, ' ' is not; basically, there will always be pairwise evaluation) Additionally, '$*$' will always be the second element; '$(*a)$' is invalid.  

The set of strings recognized by $\mbox{R}$ are as follows: 

1) If $\mbox{R}$ is "$a$", then the set of strings recognized $=\boldsymbol a$. 

2) If $\mbox{R}$ is "$\boldsymbol{b}$", then the set of strings recognized $=b$. 

3) If $\mbox{R}$ is of the form "$(R_1R_2)$" then the set of strings recognized = all strings which can be obtained by a concatenation of strings $\boldsymbol{S_{1}}$ and $s_2$, where $\boldsymbol{S_{1}}$ is recognized by $\boldsymbol{R_1}$ and $s_2$ by $R_2$. 

4) If $\mbox{R}$ is of the form "$(R1|R2)$" then the set of strings recognized = union of the set of strings recognized by $\boldsymbol{R_1}$ and $R_2$. 

5) If $\mbox{R}$ is of the form "$(R_1*)$" then the the strings recognized are the empty string and the concatenation of an arbitrary number of copies of any string recognized by $\boldsymbol{R_1}$.

Task 

Given a regular expression and an integer, $L$, count how many strings of length $L$ are recognized by it.

Input Format

The first line contains the number of test cases $\mathbf{T}$. $\mathbf{T}$ test cases follow. 

Each test case contains a regular expression, $\mbox{R}$, and an integer, $L$.

Constraints

$1\leq T\leq50$  
$1\leq|R|\leq100$  
$1\leq L\leq10^{9}$
It is guaranteed that $\mbox{R}$ will conform to the definition provided above.

Output Format

Print $\mathbf{T}$ lines, one corresponding to each test case containing the required answer for the corresponding test case. As the answers can be very big, output them modulo $10^9+7$.

Sample Input
3  
((ab)|(ba)) 2  
((a|b)*) 5  
((a*)(b(a*))) 100

Sample Output
2  
32  
100

Explanation

For the first case, the only strings recognized are "$\boldsymbol{ab}$" and "$\textbf{ba}$". Of the $4$ possible strings of length $2$, $2$ of them fit that expression. 

For the second case, the RegEx recognizes any string of any length containing only $a$'s and $\boldsymbol{b}$'s. The number of strings of length $5$ recognized by this expression is $2^5=32$. 

For the third case, the RegEx recognizes any string having one $\boldsymbol{b}$, preceeded and followed by any number of $a$'s. There are $100$ strings of length $100$ which have a single $\boldsymbol{b}$ in them.
A regular expression is used to describe a set of strings. For this problem the alphabet is limited to 'a' and 'b'.

We define $\mbox{R}$ to be a valid regular expression if: 

1) $\mbox{R}$ is "$\boldsymbol{\alpha}$" or "$\boldsymbol{b}$". 

2) $\mbox{R}$ is of the form "$(R_1R_2)$", where $\boldsymbol{R_1}$ and $R_2$ are regular expressions. 

3) $\mbox{R}$ is of the form "$(R_1|R_2)$" where $\boldsymbol{R_1}$ and $R_2$ are regular expressions. 

4) $\mbox{R}$ is of the form "$(R_1*)$" where $\boldsymbol{R_1}$ is a regular expression.

Regular expressions can be nested and will always have have two elements in the parentheses. ('$\lt\:k$' is an element, '$1$' is not; basically, there will always be pairwise evaluation) Additionally, '$\lt\:k$' will always be the second element; '$(*a)$' is invalid.  

The set of strings recognized by $\mbox{R}$ are as follows: 

1) If $\mbox{R}$ is "$\boldsymbol{\alpha}$", then the set of strings recognized $=\boldsymbol a$. 

2) If $\mbox{R}$ is "$\boldsymbol{b}$", then the set of strings recognized $=b$. 

3) If $\mbox{R}$ is of the form "$(R_1R_2)$" then the set of strings recognized = all strings which can be obtained by a concatenation of strings $\boldsymbol{S_{1}}$ and $s_2$, where $\boldsymbol{S_{1}}$ is recognized by $\boldsymbol{R_1}$ and $s_2$ by $R_2$. 

4) If $\mbox{R}$ is of the form "$(R1|R2)$" then the set of strings recognized = union of the set of strings recognized by $\boldsymbol{R_1}$ and $R_2$. 

5) If $\mbox{R}$ is of the form "$(R_1*)$" then the the strings recognized are the empty string and the concatenation of an arbitrary number of copies of any string recognized by $\boldsymbol{R_1}$.

Task 

Given a regular expression and an integer, $\boldsymbol{\mbox{I}}$, count how many strings of length $\boldsymbol{\mbox{I}}$ are recognized by it.

Input Format

The first line contains the number of test cases $\mathbf{T}$. $\mathbf{T}$ test cases follow. 

Each test case contains a regular expression, $\mbox{R}$, and an integer, $\boldsymbol{\mbox{I}}$.

Constraints

$1\leq T\leq50$  
$1\leq|R|\leq100$  
$1\leq L\leq10^{9}$
It is guaranteed that $\mbox{R}$ will conform to the definition provided above.

Output Format

Print $\mathbf{T}$ lines, one corresponding to each test case containing the required answer for the corresponding test case. As the answers can be very big, output them modulo $10^9+7$.

Sample Input
3  
((ab)|(ba)) 2  
((a|b)*) 5  
((a*)(b(a*))) 100

Sample Output
2  
32  
100

Explanation

For the first case, the only strings recognized are "$\boldsymbol{ab}$" and "$\textbf{ba}$". Of the $\begin{array}{c}A\end{array}$ possible strings of length $2$, $2$ of them fit that expression. 

For the second case, the RegEx recognizes any string of any length containing only $\boldsymbol{\alpha}$'s and $\boldsymbol{b}$'s. The number of strings of length $5$ recognized by this expression is $2^5=32$. 

For the third case, the RegEx recognizes any string having one $\boldsymbol{b}$, preceeded and followed by any number of $\boldsymbol{\alpha}$'s. There are $\left(\begin{array}{c c}{{1}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ \end{array}\right).$ strings of length $\left(\begin{array}{c c}{{1}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ {{0}}&{{0}}&{{0}}&{{0}}\\ \end{array}\right).$ which have a single $\boldsymbol{b}$ in them.

Source: hackerrank | Difficulty: MEDIUM_HARD
Tags: String algorithms


Solutions:
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			else:
				result_set.insert(self.regex_string[index])
			index += 1
		return result_set.calculate_result()

class ResultSet:

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.has_or = False

	def set_or(self):
		self.has_or = True

	def calculate_result(self):
		repeat = True if self.r2 == '*' else False
		if self.r2 is None:
			pass
		elif repeat:
			self.calculate_repeat()
		elif self.has_or:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if value != '*' and isinstance(value, str):
			value = RegexGraphNFA.get_char_graph(Alphabet[value])
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self):
		self.edges = None
		self.head = None
		self.tail = None

	@staticmethod
	def get_char_graph(value):
		my_graph = RegexGraphNFA()
		my_graph.insert_char(value)
		return my_graph

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		target = pow_val
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


OPEN = '('
CLOSE = ')'
CONCAT = '-'
BAR = '|'
STAR = '*'
A = 'a'
B = 'b'

def main():
	T = int(input())
	for t in range(0, T):
		(str, length) = input().split()
		chars = list(str)
		L = int(length)
		root = Node(None)
		current = root
		for char in chars:
			if char == OPEN:
				current = current.create_child()
			elif char == BAR:
				current.set_operation(BAR)
			elif char == STAR:
				current.set_operation(STAR)
			elif char == CLOSE:
				current = current.get_parent()
			else:
				current = current.create_child()
				current.set_operation(char)
				current = current.get_parent()
		start = NFA()
		end = NFA()
		root.left.construct_NFA(start, end)
		dfa_start = DFA()
		dfa_end = []
		dfas = []
		dfa_start.create_set_of_states([start])
		dfa_start.setup_destinations()
		dfa_start.setup_dfa(dfas, end, dfa_end)
		(matrix, indices) = construct_transition_matrix(dfas, dfa_end)
		count = count_path(matrix, L, indices)
		print(count)

class Node:

	def __init__(self, parent):
		self.parent = parent
		self.left = None
		self.right = None
		self.operation = CONCAT

	def create_child(self):
		if self.left == None:
			self.left = Node(self)
			return self.left
		else:
			self.right = Node(self)
			return self.right

	def set_operation(self, operation):
		self.operation = operation

	def get_parent(self):
		return self.parent

	def construct_NFA(self, start, end):
		if self.operation == CONCAT:
			mid = NFA()
			self.left.construct_NFA(start, mid)
			self.right.construct_NFA(mid, end)
		elif self.operation == BAR:
			start1 = NFA()
			start2 = NFA()
			end1 = NFA()
			end2 = NFA()
			start.lambda_connect(start1)
			start.lambda_connect(start2)
			end1.lambda_connect(end)
			end2.lambda_connect(end)
			self.left.construct_NFA(start1, end1)
			self.right.construct_NFA(start2, end2)
		elif self.operation == STAR:
			start1 = NFA()
			end1 = NFA()
			start.lambda_connect(end)
			start.lambda_connect(start1)
			end1.lambda_connect(end)
			end1.lambda_connect(start1)
			self.left.construct_NFA(start1, end1)
		else:
			start.connect(self.operation, end)

class NFA:

	def __init__(self):
		self.transitionTable = {}

	def lambda_connect(self, state):
		LAMBDA = ''
		self.connect(LAMBDA, state)

	def connect(self, action, state):
		if action not in self.transitionTable:
			self.transitionTable[action] = []
		self.transitionTable[action].append(state)

	def get_equivalent_states(self):
		LAMBDA = ''
		if LAMBDA not in self.transitionTable:
			return []
		else:
			return self.transitionTable[LAMBDA]

class DFA:

	def __init__(self):
		self.transitionTable = {}
		self.transitionToNFA = {}
		self.NFAstates = set()

	def create_set_of_states(self, nfas):
		for nfa in nfas:
			if nfa not in self.NFAstates:
				self.NFAstates.add(nfa)
				self.create_set_of_states([state for state in nfa.get_equivalent_states()])

	def setup_destinations(self):
		LAMBDA = ''
		for state in self.NFAstates:
			for (action, destinations) in state.transitionTable.items():
				if action != LAMBDA:
					if action not in self.transitionToNFA:
						self.transitionToNFA[action] = []
					self.transitionToNFA[action].extend(destinations)

	def setup_dfa(self, dfas, end, dfa_end):
		for dfa in dfas:
			if self.NFAstates == dfa.NFAstates:
				return dfa
		dfas.append(self)
		if end in self.NFAstates:
			dfa_end.append(self)
		for (action, destinations) in self.transitionToNFA.items():
			dfa = DFA()
			dfa.create_set_of_states(destinations)
			dfa.setup_destinations()
			self.transitionTable[action] = dfa.setup_dfa(dfas, end, dfa_end)
		return self

def construct_transition_matrix(dfas, end_dfas):
	matrix = [[0 for x in range(0, len(dfas))] for y in range(0, len(dfas))]
	for i in range(0, len(dfas)):
		for s in dfas[i].transitionTable.values():
			matrix[i][dfas.index(s)] = 1
	indices = []
	for end in end_dfas:
		indices.append(dfas.index(end))
	return (matrix, indices)

def multiply(matrix1, matrix2):
	if len(matrix1) != len(matrix2):
		return
	length = len(matrix1)
	matrix = [[0 for x in range(0, length)] for y in range(0, length)]
	for i in range(0, length):
		for j in range(0, length):
			for k in range(0, length):
				matrix[i][j] = (matrix[i][j] + matrix1[i][k] * matrix2[k][j]) % 1000000007
	return matrix

def count_path(matrix, L, indices):
	bits = [int(digit) for digit in bin(L)[2:]]
	matrix_array = [matrix]
	m = matrix
	result = None
	for i in range(0, len(bits) - 1):
		m = multiply(m, m)
		matrix_array.append(m)
	for i in range(0, len(bits)):
		if bits[len(bits) - 1 - i] == 1:
			if result == None:
				result = matrix_array[i]
			else:
				result = multiply(result, matrix_array[i])
	count = 0
	for i in indices:
		count = (count + result[0][i]) % 1000000007
	return count
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


class Automata:

	def __init__(self, language=set(['a', 'b'])):
		self.states = set()
		self.startstate = None
		self.finalstates = []
		self.transitions = dict()
		self.language = language

	@staticmethod
	def epsilon():
		return ':e:'

	def setstartstate(self, state):
		self.startstate = state
		self.states.add(state)

	def addfinalstates(self, state):
		if isinstance(state, int):
			state = [state]
		for s in state:
			if s not in self.finalstates:
				self.finalstates.append(s)

	def addtransition(self, fromstate, tostate, inp):
		if isinstance(inp, str):
			inp = set([inp])
		self.states.add(fromstate)
		self.states.add(tostate)
		if fromstate in self.transitions:
			if tostate in self.transitions[fromstate]:
				self.transitions[fromstate][tostate] = self.transitions[fromstate][tostate].union(inp)
			else:
				self.transitions[fromstate][tostate] = inp
		else:
			self.transitions[fromstate] = {tostate: inp}

	def addtransition_dict(self, transitions):
		for (fromstate, tostates) in transitions.items():
			for state in tostates:
				self.addtransition(fromstate, state, tostates[state])

	def gettransitions(self, state, key):
		if isinstance(state, int):
			state = [state]
		trstates = set()
		for st in state:
			if st in self.transitions:
				for tns in self.transitions[st]:
					if key in self.transitions[st][tns]:
						trstates.add(tns)
		return trstates

	def getEClose(self, findstate):
		allstates = set()
		states = set([findstate])
		while len(states) != 0:
			state = states.pop()
			allstates.add(state)
			if state in self.transitions:
				for tns in self.transitions[state]:
					if Automata.epsilon() in self.transitions[state][tns] and tns not in allstates:
						states.add(tns)
		return allstates

	def display(self):
		print('states:', self.states)
		print('start state: ', self.startstate)
		print('final states:', self.finalstates)
		print('transitions:')
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					print('  ', fromstate, '->', state, "on '" + char + "'")
			print

	def getPrintText(self):
		text = 'language: {' + ', '.join(self.language) + '}\n'
		text += 'states: {' + ', '.join(map(str, self.states)) + '}\n'
		text += 'start state: ' + str(self.startstate) + '\n'
		text += 'final states: {' + ', '.join(map(str, self.finalstates)) + '}\n'
		text += 'transitions:\n'
		linecount = 5
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					text += '    ' + str(fromstate) + ' -> ' + str(state) + " on '" + char + "'\n"
					linecount += 1
		return [text, linecount]

	def newBuildFromNumber(self, startnum):
		translations = {}
		for i in list(self.states):
			translations[i] = startnum
			startnum += 1
		rebuild = Automata(self.language)
		rebuild.setstartstate(translations[self.startstate])
		rebuild.addfinalstates(translations[self.finalstates[0]])
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(translations[fromstate], translations[state], tostates[state])
		return [rebuild, startnum]

	def newBuildFromEquivalentStates(self, equivalent, pos):
		rebuild = Automata(sorted(self.language))
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(pos[fromstate], pos[state], tostates[state])
		rebuild.setstartstate(pos[self.startstate])
		for s in self.finalstates:
			rebuild.addfinalstates(pos[s])
		return rebuild

	def getDotFile(self):
		dotFile = 'digraph DFA {\nrankdir=LR\n'
		if len(self.states) != 0:
			dotFile += 'root=s1\nstart [shape=point]\nstart->s%d\n' % self.startstate
			for state in self.states:
				if state in self.finalstates:
					dotFile += 's%d [shape=doublecircle]\n' % state
				else:
					dotFile += 's%d [shape=circle]\n' % state
			for (fromstate, tostates) in self.transitions.items():
				for state in tostates:
					for char in tostates[state]:
						dotFile += 's%d->s%d [label="%s"]\n' % (fromstate, state, char)
		dotFile += '}'
		return dotFile

class BuildAutomata:

	@staticmethod
	def basicstruct(inp):
		state1 = 1
		state2 = 2
		basic = Automata()
		basic.setstartstate(state1)
		basic.addfinalstates(state2)
		basic.addtransition(1, 2, inp)
		return basic

	@staticmethod
	def plusstruct(a, b):
		[a, m1] = a.newBuildFromNumber(2)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2
		plus = Automata()
		plus.setstartstate(state1)
		plus.addfinalstates(state2)
		plus.addtransition(plus.startstate, a.startstate, Automata.epsilon())
		plus.addtransition(plus.startstate, b.startstate, Automata.epsilon())
		plus.addtransition(a.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition(b.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition_dict(a.transitions)
		plus.addtransition_dict(b.transitions)
		return plus

	@staticmethod
	def dotstruct(a, b):
		[a, m1] = a.newBuildFromNumber(1)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2 - 1
		dot = Automata()
		dot.setstartstate(state1)
		dot.addfinalstates(state2)
		dot.addtransition(a.finalstates[0], b.startstate, Automata.epsilon())
		dot.addtransition_dict(a.transitions)
		dot.addtransition_dict(b.transitions)
		return dot

	@staticmethod
	def starstruct(a):
		[a, m1] = a.newBuildFromNumber(2)
		state1 = 1
		state2 = m1
		star = Automata()
		star.setstartstate(state1)
		star.addfinalstates(state2)
		star.addtransition(star.startstate, a.startstate, Automata.epsilon())
		star.addtransition(star.startstate, star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], a.startstate, Automata.epsilon())
		star.addtransition_dict(a.transitions)
		return star

class DFAfromNFA:

	def __init__(self, nfa):
		self.buildDFA(nfa)
		self.minimise()

	def getDFA(self):
		return self.dfa

	def getAllStates(self):
		return self.allstates

	def getTransitions(self):
		return self.trstates

	def getMinimisedDFA(self):
		return self.minDFA

	def displayDFA(self):
		self.dfa.display()

	def displayMinimisedDFA(self):
		self.minDFA.display()

	def buildDFA(self, nfa):
		allstates = dict()
		eclose = dict()
		count = 1
		state1 = nfa.getEClose(nfa.startstate)
		eclose[nfa.startstate] = state1
		dfa = Automata(nfa.language)
		dfa.setstartstate(count)
		states = [[state1, count]]
		allstates[count] = state1
		count += 1
		while len(states) != 0:
			[state, fromindex] = states.pop()
			for char in sorted(dfa.language):
				trstates = nfa.gettransitions(state, char)
				for s in list(trstates)[:]:
					if s not in eclose:
						eclose[s] = nfa.getEClose(s)
					trstates = trstates.union(eclose[s])
				if len(trstates) != 0:
					if trstates not in allstates.values():
						states.append([trstates, count])
						allstates[count] = trstates
						toindex = count
						count += 1
					else:
						toindex = [k for (k, v) in allstates.items() if v == trstates][0]
					dfa.addtransition(fromindex, toindex, char)
		for (value, state) in allstates.items():
			if nfa.finalstates[0] in state:
				dfa.addfinalstates(value)
		self.dfa = dfa
		self.allstates = allstates
		self.trstates = trstates

	def acceptsString(self, string):
		currentstate = self.dfa.startstate
		for ch in string:
			if ch == ':e:':
				continue
			st = list(self.dfa.gettransitions(currentstate, ch))
			if len(st) == 0:
				return False
			currentstate = st[0]
		if currentstate in self.dfa.finalstates:
			return True
		return False

	def minimise(self):
		states = list(self.dfa.states)
		n = len(states)
		unchecked = dict()
		count = 1
		distinguished = []
		equivalent = dict(zip(range(len(states)), [{s} for s in states]))
		pos = dict(zip(states, range(len(states))))
		for i in range(n - 1):
			for j in range(i + 1, n):
				if not ([states[i], states[j]] in distinguished or [states[j], states[i]] in distinguished):
					eq = 1
					toappend = []
					for char in sorted(self.dfa.language):
						s1 = self.dfa.gettransitions(states[i], char)
						s2 = self.dfa.gettransitions(states[j], char)
						if len(s1) != len(s2):
							eq = 0
							break
						if len(s1) > 1:
							raise BaseException('Multiple transitions detected in DFA')
						elif len(s1) == 0:
							continue
						s1 = s1.pop()
						s2 = s2.pop()
						if s1 != s2:
							if [s1, s2] in distinguished or [s2, s1] in distinguished:
								eq = 0
								break
							else:
								toappend.append([s1, s2, char])
								eq = -1
					if eq == 0:
						distinguished.append([states[i], states[j]])
					elif eq == -1:
						s = [states[i], states[j]]
						s.extend(toappend)
						unchecked[count] = s
						count += 1
					else:
						p1 = pos[states[i]]
						p2 = pos[states[j]]
						if p1 != p2:
							st = equivalent.pop(p2)
							for s in st:
								pos[s] = p1
							equivalent[p1] = equivalent[p1].union(st)
		newFound = True
		while newFound and len(unchecked) > 0:
			newFound = False
			toremove = set()
			for (p, pair) in list(unchecked.items()):
				for tr in pair[2:]:
					if [tr[0], tr[1]] in distinguished or [tr[1], tr[0]] in distinguished:
						unchecked.pop(p)
						distinguished.append([pair[0], pair[1]])
						newFound = True
						break
		for pair in unchecked.values():
			p1 = pos[pair[0]]
			p2 = pos[pair[1]]
			if p1 != p2:
				st = equivalent.pop(p2)
				for s in st:
					pos[s] = p1
				equivalent[p1] = equivalent[p1].union(st)
		if len(equivalent) == len(states):
			self.minDFA = self.dfa
		else:
			self.minDFA = self.dfa.newBuildFromEquivalentStates(equivalent, pos)

class NFAfromRegex:

	def __init__(self, regex):
		self.star = '*'
		self.plus = '|'
		self.dot = '.'
		self.openingBracket = '('
		self.closingBracket = ')'
		self.operators = [self.plus, self.dot]
		self.regex = regex
		self.alphabet = [chr(i) for i in range(65, 91)]
		self.alphabet.extend([chr(i) for i in range(97, 123)])
		self.alphabet.extend([chr(i) for i in range(48, 58)])
		self.buildNFA()

	def getNFA(self):
		return self.nfa

	def displayNFA(self):
		self.nfa.display()

	def buildNFA(self):
		language = set()
		self.stack = []
		self.automata = []
		previous = '::e::'
		for char in self.regex:
			if char in self.alphabet:
				language.add(char)
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.automata.append(BuildAutomata.basicstruct(char))
			elif char == self.openingBracket:
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.stack.append(char)
			elif char == self.closingBracket:
				if previous in self.operators:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				while 1:
					if len(self.stack) == 0:
						raise BaseException("Error processing '%s'. Empty stack" % char)
					o = self.stack.pop()
					if o == self.openingBracket:
						break
					elif o in self.operators:
						self.processOperator(o)
			elif char == self.star:
				if previous in self.operators or previous == self.openingBracket or previous == self.star:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				self.processOperator(char)
			elif char in self.operators:
				if previous in self.operators or previous == self.openingBracket:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				else:
					self.addOperatorToStack(char)
			else:
				raise BaseException("Symbol '%s' is not allowed" % char)
			previous = char
		while len(self.stack) != 0:
			op = self.stack.pop()
			self.processOperator(op)
		if len(self.automata) > 1:
			print(self.automata)
			raise BaseException('Regex could not be parsed successfully')
		self.nfa = self.automata.pop()
		self.nfa.language = language

	def addOperatorToStack(self, char):
		while 1:
			if len(self.stack) == 0:
				break
			top = self.stack[len(self.stack) - 1]
			if top == self.openingBracket:
				break
			if top == char or top == self.dot:
				op = self.stack.pop()
				self.processOperator(op)
			else:
				break
		self.stack.append(char)

	def processOperator(self, operator):
		if len(self.automata) == 0:
			raise BaseException("Error processing operator '%s'. Stack is empty" % operator)
		if operator == self.star:
			a = self.automata.pop()
			self.automata.append(BuildAutomata.starstruct(a))
		elif operator in self.operators:
			if len(self.automata) < 2:
				raise BaseException("Error processing operator '%s'. Inadequate operands" % operator)
			a = self.automata.pop()
			b = self.automata.pop()
			if operator == self.plus:
				self.automata.append(BuildAutomata.plusstruct(b, a))
			elif operator == self.dot:
				self.automata.append(BuildAutomata.dotstruct(b, a))

def isInstalled(program):
	import os

	def is_exe(fpath):
		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
	(fpath, fname) = os.path.split(program)
	if fpath:
		if is_exe(program) or is_exe(program + '.exe'):
			return True
	else:
		for path in os.environ['PATH'].split(os.pathsep):
			exe_file = os.path.join(path, program)
			if is_exe(exe_file) or is_exe(exe_file + '.exe'):
				return True
	return False

class Matrix:

	def __init__(self, DFA, allstates, transitions, length):
		self.length = length
		self.DFA = DFA
		self.allstates = allstates
		dim = 0
		for (value, _state) in allstates.items():
			if value != 0:
				dim += 1
		dim += 1
		self.dim = dim
		self.matrix = self.createMatrix(self.DFA, self.allstates, transitions, self.dim)

	def getDim(self):
		return self.dim

	def createMatrix(self, DFA, allstates, transitions, dim):
		matrix = [[0] * dim for _ in range(dim)]
		for (from_state, to_state) in transitions.items():
			for (to_state, _char) in to_state.items():
				matrix[from_state - 1][to_state - 1] = 1
		return matrix

	def count_paths(self, DFA, dim, length):
		modulo = 1000000007
		result = Matrix.pow2(self, length, self.matrix, dim, modulo)
		count = 0
		for i in range(dim):
			for j in range(dim):
				if i == 0:
					for k in DFA.finalstates:
						k -= 1
						if j == k:
							count += result[i][j]
		return count % modulo

	def copy(self, dim):
		my_matrix = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				my_matrix[i][j] = self.matrix[i][j]
		return my_matrix

	def printMatrix(self, matrix, dim):
		for i in range(dim):
			print(matrix[i])

	def pow2(self, power, matrix, dim, mod=None):
		result1 = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			result1[i][i] = 1
		while power > 0:
			if power & 1:
				result1 = Matrix.mat_square_mult(self, result1, matrix, dim, mod)
			power >>= 1
			if power > 0:
				matrix = Matrix.mat_square_mult(self, matrix, matrix, dim, mod)
		matrix = result1
		return matrix

	def mat_square_mult(self, matrix, other, dim, mod=None):
		result = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				index = 0
				for k in range(dim):
					index += matrix[i][k] * other[k][j] % mod
					result[i][j] = index
		return result

def count_strings(regex, length):
	nfaObj = NFAfromRegex(regex)
	nfa = nfaObj.getNFA()
	dfaObj = DFAfromNFA(nfa)
	dfa = dfaObj.getDFA()
	transitions = dfa.transitions
	allstates = dfaObj.getAllStates()
	resultObj = Matrix(dfa, allstates, transitions, length)
	dim = resultObj.getDim()
	result = Matrix.count_paths(resultObj, dfa, dim, length)
	print(result)

def main():
	cases = int(input().strip())
	for _i in range(cases):
		in_line = input().strip().split()
		regex = in_line[0]
		length = int(in_line[1])
		count_strings(regex, length)
main()


import fileinput
from os import popen
import time
import sys, traceback

class Automata:

	def __init__(self, language=set(['a', 'b'])):
		self.states = set()
		self.startstate = None
		self.finalstates = []
		self.transitions = dict()
		self.language = language

	@staticmethod
	def epsilon():
		return ':e:'

	def setstartstate(self, state):
		self.startstate = state
		self.states.add(state)

	def addfinalstates(self, state):
		if isinstance(state, int):
			state = [state]
		for s in state:
			if s not in self.finalstates:
				self.finalstates.append(s)

	def addtransition(self, fromstate, tostate, inp):
		if isinstance(inp, str):
			inp = set([inp])
		self.states.add(fromstate)
		self.states.add(tostate)
		if fromstate in self.transitions:
			if tostate in self.transitions[fromstate]:
				self.transitions[fromstate][tostate] = self.transitions[fromstate][tostate].union(inp)
			else:
				self.transitions[fromstate][tostate] = inp
		else:
			self.transitions[fromstate] = {tostate: inp}

	def addtransition_dict(self, transitions):
		for (fromstate, tostates) in transitions.items():
			for state in tostates:
				self.addtransition(fromstate, state, tostates[state])

	def gettransitions(self, state, key):
		if isinstance(state, int):
			state = [state]
		trstates = set()
		for st in state:
			if st in self.transitions:
				for tns in self.transitions[st]:
					if key in self.transitions[st][tns]:
						trstates.add(tns)
		return trstates

	def getEClose(self, findstate):
		allstates = set()
		states = set([findstate])
		while len(states) != 0:
			state = states.pop()
			allstates.add(state)
			if state in self.transitions:
				for tns in self.transitions[state]:
					if Automata.epsilon() in self.transitions[state][tns] and tns not in allstates:
						states.add(tns)
		return allstates

	def display(self):
		print('states:', self.states)
		print('start state: ', self.startstate)
		print('final states:', self.finalstates)
		print('transitions:')
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					print('  ', fromstate, '->', state, "on '" + char + "'")
			print

	def getPrintText(self):
		text = 'language: {' + ', '.join(self.language) + '}\n'
		text += 'states: {' + ', '.join(map(str, self.states)) + '}\n'
		text += 'start state: ' + str(self.startstate) + '\n'
		text += 'final states: {' + ', '.join(map(str, self.finalstates)) + '}\n'
		text += 'transitions:\n'
		linecount = 5
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					text += '    ' + str(fromstate) + ' -> ' + str(state) + " on '" + char + "'\n"
					linecount += 1
		return [text, linecount]

	def newBuildFromNumber(self, startnum):
		translations = {}
		for i in list(self.states):
			translations[i] = startnum
			startnum += 1
		rebuild = Automata(self.language)
		rebuild.setstartstate(translations[self.startstate])
		rebuild.addfinalstates(translations[self.finalstates[0]])
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(translations[fromstate], translations[state], tostates[state])
		return [rebuild, startnum]

	def newBuildFromEquivalentStates(self, equivalent, pos):
		rebuild = Automata(sorted(self.language))
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(pos[fromstate], pos[state], tostates[state])
		rebuild.setstartstate(pos[self.startstate])
		for s in self.finalstates:
			rebuild.addfinalstates(pos[s])
		return rebuild

	def getDotFile(self):
		dotFile = 'digraph DFA {\nrankdir=LR\n'
		if len(self.states) != 0:
			dotFile += 'root=s1\nstart [shape=point]\nstart->s%d\n' % self.startstate
			for state in self.states:
				if state in self.finalstates:
					dotFile += 's%d [shape=doublecircle]\n' % state
				else:
					dotFile += 's%d [shape=circle]\n' % state
			for (fromstate, tostates) in self.transitions.items():
				for state in tostates:
					for char in tostates[state]:
						dotFile += 's%d->s%d [label="%s"]\n' % (fromstate, state, char)
		dotFile += '}'
		return dotFile

class BuildAutomata:

	@staticmethod
	def basicstruct(inp):
		state1 = 1
		state2 = 2
		basic = Automata()
		basic.setstartstate(state1)
		basic.addfinalstates(state2)
		basic.addtransition(1, 2, inp)
		return basic

	@staticmethod
	def plusstruct(a, b):
		[a, m1] = a.newBuildFromNumber(2)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2
		plus = Automata()
		plus.setstartstate(state1)
		plus.addfinalstates(state2)
		plus.addtransition(plus.startstate, a.startstate, Automata.epsilon())
		plus.addtransition(plus.startstate, b.startstate, Automata.epsilon())
		plus.addtransition(a.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition(b.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition_dict(a.transitions)
		plus.addtransition_dict(b.transitions)
		return plus

	@staticmethod
	def dotstruct(a, b):
		[a, m1] = a.newBuildFromNumber(1)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2 - 1
		dot = Automata()
		dot.setstartstate(state1)
		dot.addfinalstates(state2)
		dot.addtransition(a.finalstates[0], b.startstate, Automata.epsilon())
		dot.addtransition_dict(a.transitions)
		dot.addtransition_dict(b.transitions)
		return dot

	@staticmethod
	def starstruct(a):
		[a, m1] = a.newBuildFromNumber(2)
		state1 = 1
		state2 = m1
		star = Automata()
		star.setstartstate(state1)
		star.addfinalstates(state2)
		star.addtransition(star.startstate, a.startstate, Automata.epsilon())
		star.addtransition(star.startstate, star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], a.startstate, Automata.epsilon())
		star.addtransition_dict(a.transitions)
		return star

class DFAfromNFA:

	def __init__(self, nfa):
		self.buildDFA(nfa)
		self.minimise()

	def getDFA(self):
		return self.dfa

	def getAllStates(self):
		return self.allstates

	def getTransitions(self):
		return self.trstates

	def getMinimisedDFA(self):
		return self.minDFA

	def displayDFA(self):
		self.dfa.display()

	def displayMinimisedDFA(self):
		self.minDFA.display()

	def buildDFA(self, nfa):
		allstates = dict()
		eclose = dict()
		count = 1
		state1 = nfa.getEClose(nfa.startstate)
		eclose[nfa.startstate] = state1
		dfa = Automata(nfa.language)
		dfa.setstartstate(count)
		states = [[state1, count]]
		allstates[count] = state1
		count += 1
		while len(states) != 0:
			[state, fromindex] = states.pop()
			for char in sorted(dfa.language):
				trstates = nfa.gettransitions(state, char)
				for s in list(trstates)[:]:
					if s not in eclose:
						eclose[s] = nfa.getEClose(s)
					trstates = trstates.union(eclose[s])
				if len(trstates) != 0:
					if trstates not in allstates.values():
						states.append([trstates, count])
						allstates[count] = trstates
						toindex = count
						count += 1
					else:
						toindex = [k for (k, v) in allstates.items() if v == trstates][0]
					dfa.addtransition(fromindex, toindex, char)
		for (value, state) in allstates.items():
			if nfa.finalstates[0] in state:
				dfa.addfinalstates(value)
		self.dfa = dfa
		self.allstates = allstates
		self.trstates = trstates

	def acceptsString(self, string):
		currentstate = self.dfa.startstate
		for ch in string:
			if ch == ':e:':
				continue
			st = list(self.dfa.gettransitions(currentstate, ch))
			if len(st) == 0:
				return False
			currentstate = st[0]
		if currentstate in self.dfa.finalstates:
			return True
		return False

	def minimise(self):
		states = list(self.dfa.states)
		n = len(states)
		unchecked = dict()
		count = 1
		distinguished = []
		equivalent = dict(zip(range(len(states)), [{s} for s in states]))
		pos = dict(zip(states, range(len(states))))
		for i in range(n - 1):
			for j in range(i + 1, n):
				if not ([states[i], states[j]] in distinguished or [states[j], states[i]] in distinguished):
					eq = 1
					toappend = []
					for char in sorted(self.dfa.language):
						s1 = self.dfa.gettransitions(states[i], char)
						s2 = self.dfa.gettransitions(states[j], char)
						if len(s1) != len(s2):
							eq = 0
							break
						if len(s1) > 1:
							raise BaseException('Multiple transitions detected in DFA')
						elif len(s1) == 0:
							continue
						s1 = s1.pop()
						s2 = s2.pop()
						if s1 != s2:
							if [s1, s2] in distinguished or [s2, s1] in distinguished:
								eq = 0
								break
							else:
								toappend.append([s1, s2, char])
								eq = -1
					if eq == 0:
						distinguished.append([states[i], states[j]])
					elif eq == -1:
						s = [states[i], states[j]]
						s.extend(toappend)
						unchecked[count] = s
						count += 1
					else:
						p1 = pos[states[i]]
						p2 = pos[states[j]]
						if p1 != p2:
							st = equivalent.pop(p2)
							for s in st:
								pos[s] = p1
							equivalent[p1] = equivalent[p1].union(st)
		newFound = True
		while newFound and len(unchecked) > 0:
			newFound = False
			toremove = set()
			for (p, pair) in list(unchecked.items()):
				for tr in pair[2:]:
					if [tr[0], tr[1]] in distinguished or [tr[1], tr[0]] in distinguished:
						unchecked.pop(p)
						distinguished.append([pair[0], pair[1]])
						newFound = True
						break
		for pair in unchecked.values():
			p1 = pos[pair[0]]
			p2 = pos[pair[1]]
			if p1 != p2:
				st = equivalent.pop(p2)
				for s in st:
					pos[s] = p1
				equivalent[p1] = equivalent[p1].union(st)
		if len(equivalent) == len(states):
			self.minDFA = self.dfa
		else:
			self.minDFA = self.dfa.newBuildFromEquivalentStates(equivalent, pos)

class NFAfromRegex:

	def __init__(self, regex):
		self.star = '*'
		self.plus = '|'
		self.dot = '.'
		self.openingBracket = '('
		self.closingBracket = ')'
		self.operators = [self.plus, self.dot]
		self.regex = regex
		self.alphabet = [chr(i) for i in range(65, 91)]
		self.alphabet.extend([chr(i) for i in range(97, 123)])
		self.alphabet.extend([chr(i) for i in range(48, 58)])
		self.buildNFA()

	def getNFA(self):
		return self.nfa

	def displayNFA(self):
		self.nfa.display()

	def buildNFA(self):
		language = set()
		self.stack = []
		self.automata = []
		previous = '::e::'
		for char in self.regex:
			if char in self.alphabet:
				language.add(char)
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.automata.append(BuildAutomata.basicstruct(char))
			elif char == self.openingBracket:
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.stack.append(char)
			elif char == self.closingBracket:
				if previous in self.operators:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				while 1:
					if len(self.stack) == 0:
						raise BaseException("Error processing '%s'. Empty stack" % char)
					o = self.stack.pop()
					if o == self.openingBracket:
						break
					elif o in self.operators:
						self.processOperator(o)
			elif char == self.star:
				if previous in self.operators or previous == self.openingBracket or previous == self.star:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				self.processOperator(char)
			elif char in self.operators:
				if previous in self.operators or previous == self.openingBracket:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				else:
					self.addOperatorToStack(char)
			else:
				raise BaseException("Symbol '%s' is not allowed" % char)
			previous = char
		while len(self.stack) != 0:
			op = self.stack.pop()
			self.processOperator(op)
		if len(self.automata) > 1:
			print(self.automata)
			raise BaseException('Regex could not be parsed successfully')
		self.nfa = self.automata.pop()
		self.nfa.language = language

	def addOperatorToStack(self, char):
		while 1:
			if len(self.stack) == 0:
				break
			top = self.stack[len(self.stack) - 1]
			if top == self.openingBracket:
				break
			if top == char or top == self.dot:
				op = self.stack.pop()
				self.processOperator(op)
			else:
				break
		self.stack.append(char)

	def processOperator(self, operator):
		if len(self.automata) == 0:
			raise BaseException("Error processing operator '%s'. Stack is empty" % operator)
		if operator == self.star:
			a = self.automata.pop()
			self.automata.append(BuildAutomata.starstruct(a))
		elif operator in self.operators:
			if len(self.automata) < 2:
				raise BaseException("Error processing operator '%s'. Inadequate operands" % operator)
			a = self.automata.pop()
			b = self.automata.pop()
			if operator == self.plus:
				self.automata.append(BuildAutomata.plusstruct(b, a))
			elif operator == self.dot:
				self.automata.append(BuildAutomata.dotstruct(b, a))

def isInstalled(program):
	import os

	def is_exe(fpath):
		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
	(fpath, fname) = os.path.split(program)
	if fpath:
		if is_exe(program) or is_exe(program + '.exe'):
			return True
	else:
		for path in os.environ['PATH'].split(os.pathsep):
			exe_file = os.path.join(path, program)
			if is_exe(exe_file) or is_exe(exe_file + '.exe'):
				return True
	return False

class Matrix:

	def __init__(self, DFA, allstates, transitions, length):
		self.length = length
		self.DFA = DFA
		self.allstates = allstates
		dim = 0
		for (value, _state) in allstates.items():
			if value != 0:
				dim += 1
		dim += 1
		self.dim = dim
		self.matrix = self.createMatrix(self.DFA, self.allstates, transitions, self.dim)

	def getDim(self):
		return self.dim

	def createMatrix(self, DFA, allstates, transitions, dim):
		matrix = [[0] * dim for _ in range(dim)]
		for (from_state, to_state) in transitions.items():
			for (to_state, _char) in to_state.items():
				matrix[from_state - 1][to_state - 1] = 1
		return matrix

	def count_paths(self, DFA, dim, length):
		modulo = 1000000007
		result = Matrix.pow2(self, length, self.matrix, dim, modulo)
		count = 0
		for i in range(dim):
			for j in range(dim):
				if i == 0:
					for k in DFA.finalstates:
						k -= 1
						if j == k:
							count += result[i][j]
		return count % modulo

	def copy(self, dim):
		my_matrix = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				my_matrix[i][j] = self.matrix[i][j]
		return my_matrix

	def printMatrix(self, matrix, dim):
		for i in range(dim):
			print(matrix[i])

	def pow2(self, power, matrix, dim, mod=None):
		result1 = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			result1[i][i] = 1
		while power > 0:
			if power & 1:
				result1 = Matrix.mat_square_mult(self, result1, matrix, dim, mod)
			power >>= 1
			if power > 0:
				matrix = Matrix.mat_square_mult(self, matrix, matrix, dim, mod)
		matrix = result1
		return matrix

	def mat_square_mult(self, matrix, other, dim, mod=None):
		result = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				index = 0
				for k in range(dim):
					index += matrix[i][k] * other[k][j] % mod
					result[i][j] = index
		return result

def count_strings(regex, length):
	nfaObj = NFAfromRegex(regex)
	nfa = nfaObj.getNFA()
	dfaObj = DFAfromNFA(nfa)
	dfa = dfaObj.getDFA()
	transitions = dfa.transitions
	allstates = dfaObj.getAllStates()
	resultObj = Matrix(dfa, allstates, transitions, length)
	dim = resultObj.getDim()
	result = Matrix.count_paths(resultObj, dfa, dim, length)
	print(result)

def main():
	cases = int(input().strip())
	for _i in range(cases):
		in_line = input().strip().split()
		regex = in_line[0]
		length = int(in_line[1])
		count_strings(regex, length)
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


class Automata:

	def __init__(self, language=set(['a', 'b'])):
		self.states = set()
		self.startstate = None
		self.finalstates = []
		self.transitions = dict()
		self.language = language

	@staticmethod
	def epsilon():
		return ':e:'

	def setstartstate(self, state):
		self.startstate = state
		self.states.add(state)

	def addfinalstates(self, state):
		if isinstance(state, int):
			state = [state]
		for s in state:
			if s not in self.finalstates:
				self.finalstates.append(s)

	def addtransition(self, fromstate, tostate, inp):
		if isinstance(inp, str):
			inp = set([inp])
		self.states.add(fromstate)
		self.states.add(tostate)
		if fromstate in self.transitions:
			if tostate in self.transitions[fromstate]:
				self.transitions[fromstate][tostate] = self.transitions[fromstate][tostate].union(inp)
			else:
				self.transitions[fromstate][tostate] = inp
		else:
			self.transitions[fromstate] = {tostate: inp}

	def addtransition_dict(self, transitions):
		for (fromstate, tostates) in transitions.items():
			for state in tostates:
				self.addtransition(fromstate, state, tostates[state])

	def gettransitions(self, state, key):
		if isinstance(state, int):
			state = [state]
		trstates = set()
		for st in state:
			if st in self.transitions:
				for tns in self.transitions[st]:
					if key in self.transitions[st][tns]:
						trstates.add(tns)
		return trstates

	def getEClose(self, findstate):
		allstates = set()
		states = set([findstate])
		while len(states) != 0:
			state = states.pop()
			allstates.add(state)
			if state in self.transitions:
				for tns in self.transitions[state]:
					if Automata.epsilon() in self.transitions[state][tns] and tns not in allstates:
						states.add(tns)
		return allstates

	def display(self):
		print('states:', self.states)
		print('start state: ', self.startstate)
		print('final states:', self.finalstates)
		print('transitions:')
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					print('  ', fromstate, '->', state, "on '" + char + "'")
			print

	def getPrintText(self):
		text = 'language: {' + ', '.join(self.language) + '}\n'
		text += 'states: {' + ', '.join(map(str, self.states)) + '}\n'
		text += 'start state: ' + str(self.startstate) + '\n'
		text += 'final states: {' + ', '.join(map(str, self.finalstates)) + '}\n'
		text += 'transitions:\n'
		linecount = 5
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					text += '    ' + str(fromstate) + ' -> ' + str(state) + " on '" + char + "'\n"
					linecount += 1
		return [text, linecount]

	def newBuildFromNumber(self, startnum):
		translations = {}
		for i in list(self.states):
			translations[i] = startnum
			startnum += 1
		rebuild = Automata(self.language)
		rebuild.setstartstate(translations[self.startstate])
		rebuild.addfinalstates(translations[self.finalstates[0]])
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(translations[fromstate], translations[state], tostates[state])
		return [rebuild, startnum]

	def newBuildFromEquivalentStates(self, equivalent, pos):
		rebuild = Automata(sorted(self.language))
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(pos[fromstate], pos[state], tostates[state])
		rebuild.setstartstate(pos[self.startstate])
		for s in self.finalstates:
			rebuild.addfinalstates(pos[s])
		return rebuild

	def getDotFile(self):
		dotFile = 'digraph DFA {\nrankdir=LR\n'
		if len(self.states) != 0:
			dotFile += 'root=s1\nstart [shape=point]\nstart->s%d\n' % self.startstate
			for state in self.states:
				if state in self.finalstates:
					dotFile += 's%d [shape=doublecircle]\n' % state
				else:
					dotFile += 's%d [shape=circle]\n' % state
			for (fromstate, tostates) in self.transitions.items():
				for state in tostates:
					for char in tostates[state]:
						dotFile += 's%d->s%d [label="%s"]\n' % (fromstate, state, char)
		dotFile += '}'
		return dotFile

class BuildAutomata:

	@staticmethod
	def basicstruct(inp):
		state1 = 1
		state2 = 2
		basic = Automata()
		basic.setstartstate(state1)
		basic.addfinalstates(state2)
		basic.addtransition(1, 2, inp)
		return basic

	@staticmethod
	def plusstruct(a, b):
		[a, m1] = a.newBuildFromNumber(2)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2
		plus = Automata()
		plus.setstartstate(state1)
		plus.addfinalstates(state2)
		plus.addtransition(plus.startstate, a.startstate, Automata.epsilon())
		plus.addtransition(plus.startstate, b.startstate, Automata.epsilon())
		plus.addtransition(a.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition(b.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition_dict(a.transitions)
		plus.addtransition_dict(b.transitions)
		return plus

	@staticmethod
	def dotstruct(a, b):
		[a, m1] = a.newBuildFromNumber(1)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2 - 1
		dot = Automata()
		dot.setstartstate(state1)
		dot.addfinalstates(state2)
		dot.addtransition(a.finalstates[0], b.startstate, Automata.epsilon())
		dot.addtransition_dict(a.transitions)
		dot.addtransition_dict(b.transitions)
		return dot

	@staticmethod
	def starstruct(a):
		[a, m1] = a.newBuildFromNumber(2)
		state1 = 1
		state2 = m1
		star = Automata()
		star.setstartstate(state1)
		star.addfinalstates(state2)
		star.addtransition(star.startstate, a.startstate, Automata.epsilon())
		star.addtransition(star.startstate, star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], a.startstate, Automata.epsilon())
		star.addtransition_dict(a.transitions)
		return star

class DFAfromNFA:

	def __init__(self, nfa):
		self.buildDFA(nfa)
		self.minimise()

	def getDFA(self):
		return self.dfa

	def getAllStates(self):
		return self.allstates

	def getTransitions(self):
		return self.trstates

	def getMinimisedDFA(self):
		return self.minDFA

	def displayDFA(self):
		self.dfa.display()

	def displayMinimisedDFA(self):
		self.minDFA.display()

	def buildDFA(self, nfa):
		allstates = dict()
		eclose = dict()
		count = 1
		state1 = nfa.getEClose(nfa.startstate)
		eclose[nfa.startstate] = state1
		dfa = Automata(nfa.language)
		dfa.setstartstate(count)
		states = [[state1, count]]
		allstates[count] = state1
		count += 1
		while len(states) != 0:
			[state, fromindex] = states.pop()
			for char in sorted(dfa.language):
				trstates = nfa.gettransitions(state, char)
				for s in list(trstates)[:]:
					if s not in eclose:
						eclose[s] = nfa.getEClose(s)
					trstates = trstates.union(eclose[s])
				if len(trstates) != 0:
					if trstates not in allstates.values():
						states.append([trstates, count])
						allstates[count] = trstates
						toindex = count
						count += 1
					else:
						toindex = [k for (k, v) in allstates.items() if v == trstates][0]
					dfa.addtransition(fromindex, toindex, char)
		for (value, state) in allstates.items():
			if nfa.finalstates[0] in state:
				dfa.addfinalstates(value)
		self.dfa = dfa
		self.allstates = allstates
		self.trstates = trstates

	def acceptsString(self, string):
		currentstate = self.dfa.startstate
		for ch in string:
			if ch == ':e:':
				continue
			st = list(self.dfa.gettransitions(currentstate, ch))
			if len(st) == 0:
				return False
			currentstate = st[0]
		if currentstate in self.dfa.finalstates:
			return True
		return False

	def minimise(self):
		states = list(self.dfa.states)
		n = len(states)
		unchecked = dict()
		count = 1
		distinguished = []
		equivalent = dict(zip(range(len(states)), [{s} for s in states]))
		pos = dict(zip(states, range(len(states))))
		for i in range(n - 1):
			for j in range(i + 1, n):
				if not ([states[i], states[j]] in distinguished or [states[j], states[i]] in distinguished):
					eq = 1
					toappend = []
					for char in sorted(self.dfa.language):
						s1 = self.dfa.gettransitions(states[i], char)
						s2 = self.dfa.gettransitions(states[j], char)
						if len(s1) != len(s2):
							eq = 0
							break
						if len(s1) > 1:
							raise BaseException('Multiple transitions detected in DFA')
						elif len(s1) == 0:
							continue
						s1 = s1.pop()
						s2 = s2.pop()
						if s1 != s2:
							if [s1, s2] in distinguished or [s2, s1] in distinguished:
								eq = 0
								break
							else:
								toappend.append([s1, s2, char])
								eq = -1
					if eq == 0:
						distinguished.append([states[i], states[j]])
					elif eq == -1:
						s = [states[i], states[j]]
						s.extend(toappend)
						unchecked[count] = s
						count += 1
					else:
						p1 = pos[states[i]]
						p2 = pos[states[j]]
						if p1 != p2:
							st = equivalent.pop(p2)
							for s in st:
								pos[s] = p1
							equivalent[p1] = equivalent[p1].union(st)
		newFound = True
		while newFound and len(unchecked) > 0:
			newFound = False
			toremove = set()
			for (p, pair) in list(unchecked.items()):
				for tr in pair[2:]:
					if [tr[0], tr[1]] in distinguished or [tr[1], tr[0]] in distinguished:
						unchecked.pop(p)
						distinguished.append([pair[0], pair[1]])
						newFound = True
						break
		for pair in unchecked.values():
			p1 = pos[pair[0]]
			p2 = pos[pair[1]]
			if p1 != p2:
				st = equivalent.pop(p2)
				for s in st:
					pos[s] = p1
				equivalent[p1] = equivalent[p1].union(st)
		if len(equivalent) == len(states):
			self.minDFA = self.dfa
		else:
			self.minDFA = self.dfa.newBuildFromEquivalentStates(equivalent, pos)

class NFAfromRegex:

	def __init__(self, regex):
		self.star = '*'
		self.plus = '|'
		self.dot = '.'
		self.openingBracket = '('
		self.closingBracket = ')'
		self.operators = [self.plus, self.dot]
		self.regex = regex
		self.alphabet = [chr(i) for i in range(65, 91)]
		self.alphabet.extend([chr(i) for i in range(97, 123)])
		self.alphabet.extend([chr(i) for i in range(48, 58)])
		self.buildNFA()

	def getNFA(self):
		return self.nfa

	def displayNFA(self):
		self.nfa.display()

	def buildNFA(self):
		language = set()
		self.stack = []
		self.automata = []
		previous = '::e::'
		for char in self.regex:
			if char in self.alphabet:
				language.add(char)
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.automata.append(BuildAutomata.basicstruct(char))
			elif char == self.openingBracket:
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.stack.append(char)
			elif char == self.closingBracket:
				if previous in self.operators:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				while 1:
					if len(self.stack) == 0:
						raise BaseException("Error processing '%s'. Empty stack" % char)
					o = self.stack.pop()
					if o == self.openingBracket:
						break
					elif o in self.operators:
						self.processOperator(o)
			elif char == self.star:
				if previous in self.operators or previous == self.openingBracket or previous == self.star:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				self.processOperator(char)
			elif char in self.operators:
				if previous in self.operators or previous == self.openingBracket:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				else:
					self.addOperatorToStack(char)
			else:
				raise BaseException("Symbol '%s' is not allowed" % char)
			previous = char
		while len(self.stack) != 0:
			op = self.stack.pop()
			self.processOperator(op)
		if len(self.automata) > 1:
			print(self.automata)
			raise BaseException('Regex could not be parsed successfully')
		self.nfa = self.automata.pop()
		self.nfa.language = language

	def addOperatorToStack(self, char):
		while 1:
			if len(self.stack) == 0:
				break
			top = self.stack[len(self.stack) - 1]
			if top == self.openingBracket:
				break
			if top == char or top == self.dot:
				op = self.stack.pop()
				self.processOperator(op)
			else:
				break
		self.stack.append(char)

	def processOperator(self, operator):
		if len(self.automata) == 0:
			raise BaseException("Error processing operator '%s'. Stack is empty" % operator)
		if operator == self.star:
			a = self.automata.pop()
			self.automata.append(BuildAutomata.starstruct(a))
		elif operator in self.operators:
			if len(self.automata) < 2:
				raise BaseException("Error processing operator '%s'. Inadequate operands" % operator)
			a = self.automata.pop()
			b = self.automata.pop()
			if operator == self.plus:
				self.automata.append(BuildAutomata.plusstruct(b, a))
			elif operator == self.dot:
				self.automata.append(BuildAutomata.dotstruct(b, a))

def isInstalled(program):
	import os

	def is_exe(fpath):
		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
	(fpath, fname) = os.path.split(program)
	if fpath:
		if is_exe(program) or is_exe(program + '.exe'):
			return True
	else:
		for path in os.environ['PATH'].split(os.pathsep):
			exe_file = os.path.join(path, program)
			if is_exe(exe_file) or is_exe(exe_file + '.exe'):
				return True
	return False

class Matrix:

	def __init__(self, DFA, allstates, transitions, length):
		self.length = length
		self.DFA = DFA
		self.allstates = allstates
		dim = 0
		for (value, _state) in allstates.items():
			if value != 0:
				dim += 1
		dim += 1
		self.dim = dim
		self.matrix = self.createMatrix(self.DFA, self.allstates, transitions, self.dim)

	def getDim(self):
		return self.dim

	def createMatrix(self, DFA, allstates, transitions, dim):
		matrix = [[0] * dim for _ in range(dim)]
		for (from_state, to_state) in transitions.items():
			for (to_state, _char) in to_state.items():
				matrix[from_state - 1][to_state - 1] = 1
		return matrix

	def count_paths(self, DFA, dim, length):
		modulo = 1000000007
		result = Matrix.pow2(self, length, self.matrix, dim, modulo)
		count = 0
		for i in range(dim):
			for j in range(dim):
				if i == 0:
					for k in DFA.finalstates:
						k -= 1
						if j == k:
							count += result[i][j]
		return count % modulo

	def copy(self, dim):
		my_matrix = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				my_matrix[i][j] = self.matrix[i][j]
		return my_matrix

	def printMatrix(self, matrix, dim):
		for i in range(dim):
			print(matrix[i])

	def pow2(self, power, matrix, dim, mod=None):
		result1 = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			result1[i][i] = 1
		while power > 0:
			if power & 1:
				result1 = Matrix.mat_square_mult(self, result1, matrix, dim, mod)
			power >>= 1
			if power > 0:
				matrix = Matrix.mat_square_mult(self, matrix, matrix, dim, mod)
		matrix = result1
		return matrix

	def mat_square_mult(self, matrix, other, dim, mod=None):
		result = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				index = 0
				for k in range(dim):
					index += matrix[i][k] * other[k][j] % mod
					result[i][j] = index
		return result

def count_strings(regex, length):
	nfaObj = NFAfromRegex(regex)
	nfa = nfaObj.getNFA()
	dfaObj = DFAfromNFA(nfa)
	dfa = dfaObj.getDFA()
	transitions = dfa.transitions
	allstates = dfaObj.getAllStates()
	resultObj = Matrix(dfa, allstates, transitions, length)
	dim = resultObj.getDim()
	result = Matrix.count_paths(resultObj, dfa, dim, length)
	print(result)

def main():
	cases = int(input().strip())
	for _i in range(cases):
		in_line = input().strip().split()
		regex = in_line[0]
		length = int(in_line[1])
		count_strings(regex, length)
main()


class Automata:

	def __init__(self, language=set(['a', 'b'])):
		self.states = set()
		self.startstate = None
		self.finalstates = []
		self.transitions = dict()
		self.language = language

	@staticmethod
	def epsilon():
		return ':e:'

	def setstartstate(self, state):
		self.startstate = state
		self.states.add(state)

	def addfinalstates(self, state):
		if isinstance(state, int):
			state = [state]
		for s in state:
			if s not in self.finalstates:
				self.finalstates.append(s)

	def addtransition(self, fromstate, tostate, inp):
		if isinstance(inp, str):
			inp = set([inp])
		self.states.add(fromstate)
		self.states.add(tostate)
		if fromstate in self.transitions:
			if tostate in self.transitions[fromstate]:
				self.transitions[fromstate][tostate] = self.transitions[fromstate][tostate].union(inp)
			else:
				self.transitions[fromstate][tostate] = inp
		else:
			self.transitions[fromstate] = {tostate: inp}

	def addtransition_dict(self, transitions):
		for (fromstate, tostates) in transitions.items():
			for state in tostates:
				self.addtransition(fromstate, state, tostates[state])

	def gettransitions(self, state, key):
		if isinstance(state, int):
			state = [state]
		trstates = set()
		for st in state:
			if st in self.transitions:
				for tns in self.transitions[st]:
					if key in self.transitions[st][tns]:
						trstates.add(tns)
		return trstates

	def getEClose(self, findstate):
		allstates = set()
		states = set([findstate])
		while len(states) != 0:
			state = states.pop()
			allstates.add(state)
			if state in self.transitions:
				for tns in self.transitions[state]:
					if Automata.epsilon() in self.transitions[state][tns] and tns not in allstates:
						states.add(tns)
		return allstates

	def display(self):
		print('states:', self.states)
		print('start state: ', self.startstate)
		print('final states:', self.finalstates)
		print('transitions:')
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					print('  ', fromstate, '->', state, "on '" + char + "'")
			print

	def getPrintText(self):
		text = 'language: {' + ', '.join(self.language) + '}\n'
		text += 'states: {' + ', '.join(map(str, self.states)) + '}\n'
		text += 'start state: ' + str(self.startstate) + '\n'
		text += 'final states: {' + ', '.join(map(str, self.finalstates)) + '}\n'
		text += 'transitions:\n'
		linecount = 5
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					text += '    ' + str(fromstate) + ' -> ' + str(state) + " on '" + char + "'\n"
					linecount += 1
		return [text, linecount]

	def newBuildFromNumber(self, startnum):
		translations = {}
		for i in list(self.states):
			translations[i] = startnum
			startnum += 1
		rebuild = Automata(self.language)
		rebuild.setstartstate(translations[self.startstate])
		rebuild.addfinalstates(translations[self.finalstates[0]])
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(translations[fromstate], translations[state], tostates[state])
		return [rebuild, startnum]

	def newBuildFromEquivalentStates(self, equivalent, pos):
		rebuild = Automata(sorted(self.language))
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(pos[fromstate], pos[state], tostates[state])
		rebuild.setstartstate(pos[self.startstate])
		for s in self.finalstates:
			rebuild.addfinalstates(pos[s])
		return rebuild

	def getDotFile(self):
		dotFile = 'digraph DFA {\nrankdir=LR\n'
		if len(self.states) != 0:
			dotFile += 'root=s1\nstart [shape=point]\nstart->s%d\n' % self.startstate
			for state in self.states:
				if state in self.finalstates:
					dotFile += 's%d [shape=doublecircle]\n' % state
				else:
					dotFile += 's%d [shape=circle]\n' % state
			for (fromstate, tostates) in self.transitions.items():
				for state in tostates:
					for char in tostates[state]:
						dotFile += 's%d->s%d [label="%s"]\n' % (fromstate, state, char)
		dotFile += '}'
		return dotFile

class BuildAutomata:

	@staticmethod
	def basicstruct(inp):
		state1 = 1
		state2 = 2
		basic = Automata()
		basic.setstartstate(state1)
		basic.addfinalstates(state2)
		basic.addtransition(1, 2, inp)
		return basic

	@staticmethod
	def plusstruct(a, b):
		[a, m1] = a.newBuildFromNumber(2)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2
		plus = Automata()
		plus.setstartstate(state1)
		plus.addfinalstates(state2)
		plus.addtransition(plus.startstate, a.startstate, Automata.epsilon())
		plus.addtransition(plus.startstate, b.startstate, Automata.epsilon())
		plus.addtransition(a.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition(b.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition_dict(a.transitions)
		plus.addtransition_dict(b.transitions)
		return plus

	@staticmethod
	def dotstruct(a, b):
		[a, m1] = a.newBuildFromNumber(1)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2 - 1
		dot = Automata()
		dot.setstartstate(state1)
		dot.addfinalstates(state2)
		dot.addtransition(a.finalstates[0], b.startstate, Automata.epsilon())
		dot.addtransition_dict(a.transitions)
		dot.addtransition_dict(b.transitions)
		return dot

	@staticmethod
	def starstruct(a):
		[a, m1] = a.newBuildFromNumber(2)
		state1 = 1
		state2 = m1
		star = Automata()
		star.setstartstate(state1)
		star.addfinalstates(state2)
		star.addtransition(star.startstate, a.startstate, Automata.epsilon())
		star.addtransition(star.startstate, star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], a.startstate, Automata.epsilon())
		star.addtransition_dict(a.transitions)
		return star

class DFAfromNFA:

	def __init__(self, nfa):
		self.buildDFA(nfa)
		self.minimise()

	def getDFA(self):
		return self.dfa

	def getAllStates(self):
		return self.allstates

	def getTransitions(self):
		return self.trstates

	def getMinimisedDFA(self):
		return self.minDFA

	def displayDFA(self):
		self.dfa.display()

	def displayMinimisedDFA(self):
		self.minDFA.display()

	def buildDFA(self, nfa):
		allstates = dict()
		eclose = dict()
		count = 1
		state1 = nfa.getEClose(nfa.startstate)
		eclose[nfa.startstate] = state1
		dfa = Automata(nfa.language)
		dfa.setstartstate(count)
		states = [[state1, count]]
		allstates[count] = state1
		count += 1
		while len(states) != 0:
			[state, fromindex] = states.pop()
			for char in sorted(dfa.language):
				trstates = nfa.gettransitions(state, char)
				for s in list(trstates)[:]:
					if s not in eclose:
						eclose[s] = nfa.getEClose(s)
					trstates = trstates.union(eclose[s])
				if len(trstates) != 0:
					if trstates not in allstates.values():
						states.append([trstates, count])
						allstates[count] = trstates
						toindex = count
						count += 1
					else:
						toindex = [k for (k, v) in allstates.items() if v == trstates][0]
					dfa.addtransition(fromindex, toindex, char)
		for (value, state) in allstates.items():
			if nfa.finalstates[0] in state:
				dfa.addfinalstates(value)
		self.dfa = dfa
		self.allstates = allstates
		self.trstates = trstates

	def acceptsString(self, string):
		currentstate = self.dfa.startstate
		for ch in string:
			if ch == ':e:':
				continue
			st = list(self.dfa.gettransitions(currentstate, ch))
			if len(st) == 0:
				return False
			currentstate = st[0]
		if currentstate in self.dfa.finalstates:
			return True
		return False

	def minimise(self):
		states = list(self.dfa.states)
		n = len(states)
		unchecked = dict()
		count = 1
		distinguished = []
		equivalent = dict(zip(range(len(states)), [{s} for s in states]))
		pos = dict(zip(states, range(len(states))))
		for i in range(n - 1):
			for j in range(i + 1, n):
				if not ([states[i], states[j]] in distinguished or [states[j], states[i]] in distinguished):
					eq = 1
					toappend = []
					for char in sorted(self.dfa.language):
						s1 = self.dfa.gettransitions(states[i], char)
						s2 = self.dfa.gettransitions(states[j], char)
						if len(s1) != len(s2):
							eq = 0
							break
						if len(s1) > 1:
							raise BaseException('Multiple transitions detected in DFA')
						elif len(s1) == 0:
							continue
						s1 = s1.pop()
						s2 = s2.pop()
						if s1 != s2:
							if [s1, s2] in distinguished or [s2, s1] in distinguished:
								eq = 0
								break
							else:
								toappend.append([s1, s2, char])
								eq = -1
					if eq == 0:
						distinguished.append([states[i], states[j]])
					elif eq == -1:
						s = [states[i], states[j]]
						s.extend(toappend)
						unchecked[count] = s
						count += 1
					else:
						p1 = pos[states[i]]
						p2 = pos[states[j]]
						if p1 != p2:
							st = equivalent.pop(p2)
							for s in st:
								pos[s] = p1
							equivalent[p1] = equivalent[p1].union(st)
		newFound = True
		while newFound and len(unchecked) > 0:
			newFound = False
			toremove = set()
			for (p, pair) in list(unchecked.items()):
				for tr in pair[2:]:
					if [tr[0], tr[1]] in distinguished or [tr[1], tr[0]] in distinguished:
						unchecked.pop(p)
						distinguished.append([pair[0], pair[1]])
						newFound = True
						break
		for pair in unchecked.values():
			p1 = pos[pair[0]]
			p2 = pos[pair[1]]
			if p1 != p2:
				st = equivalent.pop(p2)
				for s in st:
					pos[s] = p1
				equivalent[p1] = equivalent[p1].union(st)
		if len(equivalent) == len(states):
			self.minDFA = self.dfa
		else:
			self.minDFA = self.dfa.newBuildFromEquivalentStates(equivalent, pos)

class NFAfromRegex:

	def __init__(self, regex):
		self.star = '*'
		self.plus = '|'
		self.dot = '.'
		self.openingBracket = '('
		self.closingBracket = ')'
		self.operators = [self.plus, self.dot]
		self.regex = regex
		self.alphabet = [chr(i) for i in range(65, 91)]
		self.alphabet.extend([chr(i) for i in range(97, 123)])
		self.alphabet.extend([chr(i) for i in range(48, 58)])
		self.buildNFA()

	def getNFA(self):
		return self.nfa

	def displayNFA(self):
		self.nfa.display()

	def buildNFA(self):
		language = set()
		self.stack = []
		self.automata = []
		previous = '::e::'
		for char in self.regex:
			if char in self.alphabet:
				language.add(char)
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.automata.append(BuildAutomata.basicstruct(char))
			elif char == self.openingBracket:
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.stack.append(char)
			elif char == self.closingBracket:
				if previous in self.operators:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				while 1:
					if len(self.stack) == 0:
						raise BaseException("Error processing '%s'. Empty stack" % char)
					o = self.stack.pop()
					if o == self.openingBracket:
						break
					elif o in self.operators:
						self.processOperator(o)
			elif char == self.star:
				if previous in self.operators or previous == self.openingBracket or previous == self.star:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				self.processOperator(char)
			elif char in self.operators:
				if previous in self.operators or previous == self.openingBracket:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				else:
					self.addOperatorToStack(char)
			else:
				raise BaseException("Symbol '%s' is not allowed" % char)
			previous = char
		while len(self.stack) != 0:
			op = self.stack.pop()
			self.processOperator(op)
		if len(self.automata) > 1:
			print(self.automata)
			raise BaseException('Regex could not be parsed successfully')
		self.nfa = self.automata.pop()
		self.nfa.language = language

	def addOperatorToStack(self, char):
		while 1:
			if len(self.stack) == 0:
				break
			top = self.stack[len(self.stack) - 1]
			if top == self.openingBracket:
				break
			if top == char or top == self.dot:
				op = self.stack.pop()
				self.processOperator(op)
			else:
				break
		self.stack.append(char)

	def processOperator(self, operator):
		if len(self.automata) == 0:
			raise BaseException("Error processing operator '%s'. Stack is empty" % operator)
		if operator == self.star:
			a = self.automata.pop()
			self.automata.append(BuildAutomata.starstruct(a))
		elif operator in self.operators:
			if len(self.automata) < 2:
				raise BaseException("Error processing operator '%s'. Inadequate operands" % operator)
			a = self.automata.pop()
			b = self.automata.pop()
			if operator == self.plus:
				self.automata.append(BuildAutomata.plusstruct(b, a))
			elif operator == self.dot:
				self.automata.append(BuildAutomata.dotstruct(b, a))

def isInstalled(program):
	import os

	def is_exe(fpath):
		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
	(fpath, fname) = os.path.split(program)
	if fpath:
		if is_exe(program) or is_exe(program + '.exe'):
			return True
	else:
		for path in os.environ['PATH'].split(os.pathsep):
			exe_file = os.path.join(path, program)
			if is_exe(exe_file) or is_exe(exe_file + '.exe'):
				return True
	return False

class Matrix:

	def __init__(self, DFA, allstates, transitions, length):
		self.length = length
		self.DFA = DFA
		self.allstates = allstates
		dim = 0
		for (value, _state) in allstates.items():
			if value != 0:
				dim += 1
		dim += 1
		self.dim = dim
		self.matrix = self.createMatrix(self.DFA, self.allstates, transitions, self.dim)

	def getDim(self):
		return self.dim

	def createMatrix(self, DFA, allstates, transitions, dim):
		matrix = [[0] * dim for _ in range(dim)]
		for (from_state, to_state) in transitions.items():
			for (to_state, _char) in to_state.items():
				matrix[from_state - 1][to_state - 1] = 1
		return matrix

	def count_paths(self, DFA, dim, length):
		modulo = 1000000007
		result = Matrix.pow2(self, length, self.matrix, dim, modulo)
		count = 0
		for i in range(dim):
			for j in range(dim):
				if i == 0:
					for k in DFA.finalstates:
						k -= 1
						if j == k:
							count += result[i][j]
		return count % modulo

	def copy(self, dim):
		my_matrix = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				my_matrix[i][j] = self.matrix[i][j]
		return my_matrix

	def printMatrix(self, matrix, dim):
		for i in range(dim):
			print(matrix[i])

	def pow2(self, power, matrix, dim, mod=None):
		result1 = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			result1[i][i] = 1
		while power > 0:
			if power & 1:
				result1 = Matrix.mat_square_mult(self, result1, matrix, dim, mod)
			power >>= 1
			if power > 0:
				matrix = Matrix.mat_square_mult(self, matrix, matrix, dim, mod)
		matrix = result1
		return matrix

	def mat_square_mult(self, matrix, other, dim, mod=None):
		result = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				index = 0
				for k in range(dim):
					index += matrix[i][k] * other[k][j] % mod
					result[i][j] = index
		return result

def count_strings(regex, length):
	nfaObj = NFAfromRegex(regex)
	nfa = nfaObj.getNFA()
	dfaObj = DFAfromNFA(nfa)
	dfa = dfaObj.getDFA()
	transitions = dfa.transitions
	allstates = dfaObj.getAllStates()
	resultObj = Matrix(dfa, allstates, transitions, length)
	dim = resultObj.getDim()
	result = Matrix.count_paths(resultObj, dfa, dim, length)
	print(result)

def main():
	cases = int(input().strip())
	for _i in range(cases):
		in_line = input().strip().split()
		regex = in_line[0]
		length = int(in_line[1])
		count_strings(regex, length)
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import math

def regex_to_nfa(regex):
	nfa = [{'a': [], 'b': [], 'e': []} for i in range(len(regex) + 1)]
	ops = []
	for (idx, r) in enumerate(regex):
		if r == 'a' or r == 'b':
			nfa[idx][r].append(idx + 1)
		if r in ['(', ')', '*']:
			nfa[idx]['e'].append(idx + 1)
		start_idx = idx
		if r in ['(', '|']:
			ops.append(idx)
		elif r == ')':
			popped_idx = ops.pop()
			popped_r = regex[popped_idx]
			if popped_r == '|':
				start_idx = ops.pop()
				nfa[start_idx]['e'].append(popped_idx + 1)
				nfa[popped_idx]['e'].append(idx)
			else:
				start_idx = popped_idx
		if idx < len(regex) - 1:
			if regex[idx + 1] == '*':
				nfa[start_idx]['e'].append(idx + 1)
				nfa[idx + 1]['e'].append(start_idx)
	return nfa

def nfa_to_dfa(nfa):

	def e_closure(s):
		visit = set()
		found = set(s)

		def dfs(v):
			if v in visit:
				return
			visit.add(v)
			for next_v in nfa[v]['e']:
				found.add(next_v)
				dfs(next_v)
		for v in s:
			dfs(v)
		return tuple(list(found))
	dfa = []
	state_idx_map = {}

	def recursive_state_finding(state):
		for path in ['a', 'b']:
			new_state = e_closure(set((i for v in state for i in nfa[v][path])))
			if new_state:
				if new_state not in state_idx_map:
					state_idx_map[new_state] = len(dfa)
					dfa.append({'a': set(), 'b': set()})
					recursive_state_finding(new_state)
				dfa[state_idx_map[state]][path].add(state_idx_map[new_state])
	start_state = e_closure({0})
	state_idx_map[start_state] = 0
	dfa.append({'a': set(), 'b': set()})
	recursive_state_finding(start_state)
	for (state, idx) in state_idx_map.items():
		dfa[idx]['is_final'] = len(nfa) - 1 in state
	return dfa

def dfa_to_adj_matrix(dfa):
	size = len(dfa)
	adj_matrix = dict({(i, j): 0 for i in range(size) for j in range(size)}, size=size)
	for start in range(size):
		for path in ['a', 'b']:
			for finish in dfa[start][path]:
				adj_matrix[start, finish] += 1
	return adj_matrix

def matrix_exp(mat, n):

	def matrix_mult(m1, m2):
		size = m1['size']
		return dict({(i, j): sum([m1[i, k] * m2[k, j] for k in range(size)]) % 1000000007 for i in range(size) for j in range(size)}, size=size)
	size = mat['size']
	if n == 0:
		return dict({(i, j): 1 if i == j else 0 for i in range(size) for j in range(size)}, size=size)
	elif n == 1:
		return mat
	half = matrix_exp(mat, n // 2)
	m = matrix_mult(half, half)
	if n % 2 == 1:
		m = matrix_mult(m, mat)
	return m

def solve(regex, str_len):
	dfa = nfa_to_dfa(regex_to_nfa(regex))
	adj = matrix_exp(dfa_to_adj_matrix(dfa), str_len)
	return sum([adj[0, i] for i in range(adj['size']) if dfa[i]['is_final']]) % 1000000007
testcases = int(input())
for _ in range(testcases):
	(regex, str_len) = input().strip().split()
	print(solve(regex, int(str_len)))


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			else:
				result_set.insert(self.regex_string[index])
			index += 1
		return result_set.calculate_result()

class ResultSet:

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.has_or = False

	def set_or(self):
		self.has_or = True

	def calculate_result(self):
		repeat = True if self.r2 == '*' else False
		if self.r2 is None:
			pass
		elif repeat:
			self.calculate_repeat()
		elif self.has_or:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if value != '*' and isinstance(value, str):
			value = RegexGraphNFA.get_char_graph(Alphabet[value])
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self):
		self.edges = None
		self.head = None
		self.tail = None

	@staticmethod
	def get_char_graph(value):
		my_graph = RegexGraphNFA()
		my_graph.insert_char(value)
		return my_graph

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		target = pow_val
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import operator

class Stack:

	def __init__(self):
		self.items = []

	def isEmpty(self):
		return self.items == []

	def push(self, item):
		self.items.append(item)

	def pop(self):
		return self.items.pop()

	def peek(self):
		return self.items[len(self.items) - 1]

	def size(self):
		return len(self.items)

class Rexp:
	val = ''
	re1 = ''
	re2 = ''
	op = ''

	def __init__(self, v):
		self.val = v

	def print(self):
		print(self.val, 'val')
		print(self.re1.val, 're1')
		print(self.re2.val, 're2')

def parseRegex(val):
	if val == 'a' or val == 'b':
		re = Rexp(val)
		return re
	s1 = Stack()
	s2 = Stack()
	for c in val:
		s1.push(c)
	while s1.size() > 0:
		if s1.peek() != '(':
			s2.push(s1.pop())
		else:
			re = Rexp('')
			re1 = Rexp('')
			re2 = Rexp('')
			r = []
			r.append(s1.pop())
			while s2.peek() != ')':
				r.append(s2.pop())
			r.append(s2.pop())
			if '|' in r:
				re.op = '|'
				idx = r.index('|')
				if r[idx - 1] == 'a' or r[idx - 1] == 'b':
					re1 = parseRegex(r[idx - 1])
				else:
					re1 = r[idx - 1]
				if r[idx + 1] == 'a' or r[idx + 1] == 'b':
					re2 = parseRegex(r[idx + 1])
				else:
					re2 = r[idx + 1]
			elif '*' in r:
				re.op = '*'
				idx = r.index('*')
				if r[idx - 1] == 'a' or r[idx - 1] == 'b':
					re1 = parseRegex(r[idx - 1])
				else:
					re1 = r[idx - 1]
			else:
				re.op = '&'
				if r[1] == 'a' or r[1] == 'b':
					re1 = parseRegex(r[1])
				else:
					re1 = r[1]
				if r[2] == 'a' or r[2] == 'b':
					re2 = parseRegex(r[2])
				else:
					re2 = r[2]
			re.val = '(' + re1.val + re.op + re2.val + ')'
			re.re1 = re1
			re.re2 = re2
			s2.push(re)
	return s2.pop()

class State:

	def __init__(self):
		self.transitions = []

	def uniqueStatesReachable(self, val):
		uniqueStates = set()
		for (neigh, edge) in self.transitions:
			if edge == val and neigh not in uniqueStates:
				uniqueStates.add(neigh)
		return uniqueStates

	def epsilonClosure(self):
		uniquestates = set()
		alreadyVisited = set()
		states = Stack()
		states.push(self)
		while not states.isEmpty():
			s = states.pop()
			uniquestates.add(s)
			for (neigh, edge) in s.transitions:
				if edge == 'eps' and neigh not in uniquestates:
					states.push(neigh)
		return uniquestates

class NFA:

	def __init__(self):
		self.s = State()
		self.f = State()
		self.Q = set()
		self.Q.add(self.s)
		self.Q.add(self.f)

	def uniqueStatesReachable(self, states, val):
		uniqueStates = set()
		for s in states:
			uniqueStates |= s.uniqueStatesReachable(val)
		return uniqueStates

	def epsilonClosure(self, states):
		uniqueStates = set()
		for s in states:
			uniqueStates |= s.epsilonClosure()
		return uniqueStates

def constructNFA(re):
	nfa = NFA()
	if re.val == 'a' or re.val == 'b':
		nfa.s.transitions.append((nfa.f, re.val))
	elif re.op == '&':
		nfa1 = constructNFA(re.re1)
		nfa2 = constructNFA(re.re2)
		nfa1.f.transitions.append((nfa2.s, 'eps'))
		nfa.Q |= nfa1.Q
		nfa.Q |= nfa2.Q
		nfa.s.transitions.append((nfa1.s, 'eps'))
		nfa2.f.transitions.append((nfa.f, 'eps'))
	elif re.op == '|':
		nfa1 = constructNFA(re.re1)
		nfa2 = constructNFA(re.re2)
		nfa.Q |= nfa1.Q
		nfa.Q |= nfa2.Q
		nfa.s.transitions.append((nfa1.s, 'eps'))
		nfa.s.transitions.append((nfa2.s, 'eps'))
		nfa1.f.transitions.append((nfa.f, 'eps'))
		nfa2.f.transitions.append((nfa.f, 'eps'))
	elif re.op == '*':
		nfa1 = constructNFA(re.re1)
		nfa.Q |= nfa1.Q
		nfa.s.transitions.append((nfa.f, 'eps'))
		nfa.f.transitions.append((nfa.s, 'eps'))
		nfa.s.transitions.append((nfa1.s, 'eps'))
		nfa1.f.transitions.append((nfa.f, 'eps'))
	return nfa

class DFA:

	def __init__(self):
		self.startStates = []
		self.finalStates = []
		self.Q = {}
		self.stats = []

	def adjacencyMatrix(self):
		num = len(self.states)
		am = [[0 for x in range(0, num)] for y in range(0, num)]
		for (s, e) in self.Q:
			am[s][self.Q[s, e]] = 1
		return am

def toArray(states):
	arr = []
	for s in states:
		arr.append(s)
	arr.sort(key=id)
	return arr

def constructDFA(nfa):
	Q = {}
	states = []
	startState = nfa.epsilonClosure({nfa.s})
	q = Stack()
	q.push(startState)
	while not q.isEmpty():
		s = q.pop()
		if toArray(s) not in states:
			reachableA = nfa.epsilonClosure(nfa.uniqueStatesReachable(s, 'a'))
			reachableB = nfa.epsilonClosure(nfa.uniqueStatesReachable(s, 'b'))
			Q[len(states), 'a'] = toArray(reachableA)
			Q[len(states), 'b'] = toArray(reachableB)
			q.push(reachableA)
			q.push(reachableB)
			states.append(toArray(s))
	ss = []
	fs = []
	for i in range(0, len(states)):
		Q[i, 'a'] = states.index(Q[i, 'a'])
		Q[i, 'b'] = states.index(Q[i, 'b'])
		if nfa.s in states[i]:
			ss.append(i)
		if nfa.f in states[i]:
			fs.append(i)
	dfa = DFA()
	dfa.startStates = ss
	dfa.finalStates = fs
	dfa.Q = Q
	dfa.states = states
	return dfa
md = pow(10, 9) + 7

def matMult(m1, m2):
	l = len(m1)
	m = [[0 for x in range(0, l)] for x in range(0, l)]
	for i in range(0, l):
		for j in range(0, l):
			for k in range(0, l):
				m[i][j] += m1[i][k] * m2[k][j]
				m[i][j] %= md
	return m

def matPow(p, matdict):
	if p in matdict:
		return matdict[p]
	x = int(p / 2)
	m = matPow(x, matdict)
	m1 = m
	if p % 2 == 1:
		m1 = matMult(m, matdict[1])
		matdict[x + 1] = m1
	matdict[p] = matMult(m, m1)
	return matdict[p]

def countWalks(dfa, lenString):
	am = dfa.adjacencyMatrix()
	matdict = {}
	matdict[1] = am
	m = matPow(lenString, matdict)
	count = 0
	for f in dfa.finalStates:
		count += m[0][f]
		count %= md
	return count
t = int(input())
while t > 0:
	rl = input().split()
	re = parseRegex(rl[0])
	nfa = constructNFA(re)
	dfa = constructDFA(nfa)
	count = countWalks(dfa, int(rl[1]))
	print(count)
	t -= 1


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			else:
				result_set.insert(self.regex_string[index])
			index += 1
		return result_set.calculate_result()

class ResultSet:

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.has_or = False

	def set_or(self):
		self.has_or = True

	def calculate_result(self):
		repeat = True if self.r2 == '*' else False
		if self.r2 is None:
			pass
		elif repeat:
			self.calculate_repeat()
		elif self.has_or:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if value != '*' and isinstance(value, str):
			value = RegexGraphNFA.get_char_graph(Alphabet[value])
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self):
		self.edges = None
		self.head = None
		self.tail = None

	@staticmethod
	def get_char_graph(value):
		my_graph = RegexGraphNFA()
		my_graph.insert_char(value)
		return my_graph

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		target = pow_val
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


class Automata:

	def __init__(self, language=set(['a', 'b'])):
		self.states = set()
		self.startstate = None
		self.finalstates = []
		self.transitions = dict()
		self.language = language

	@staticmethod
	def epsilon():
		return ':e:'

	def setstartstate(self, state):
		self.startstate = state
		self.states.add(state)

	def addfinalstates(self, state):
		if isinstance(state, int):
			state = [state]
		for s in state:
			if s not in self.finalstates:
				self.finalstates.append(s)

	def addtransition(self, fromstate, tostate, inp):
		if isinstance(inp, str):
			inp = set([inp])
		self.states.add(fromstate)
		self.states.add(tostate)
		if fromstate in self.transitions:
			if tostate in self.transitions[fromstate]:
				self.transitions[fromstate][tostate] = self.transitions[fromstate][tostate].union(inp)
			else:
				self.transitions[fromstate][tostate] = inp
		else:
			self.transitions[fromstate] = {tostate: inp}

	def addtransition_dict(self, transitions):
		for (fromstate, tostates) in transitions.items():
			for state in tostates:
				self.addtransition(fromstate, state, tostates[state])

	def gettransitions(self, state, key):
		if isinstance(state, int):
			state = [state]
		trstates = set()
		for st in state:
			if st in self.transitions:
				for tns in self.transitions[st]:
					if key in self.transitions[st][tns]:
						trstates.add(tns)
		return trstates

	def getEClose(self, findstate):
		allstates = set()
		states = set([findstate])
		while len(states) != 0:
			state = states.pop()
			allstates.add(state)
			if state in self.transitions:
				for tns in self.transitions[state]:
					if Automata.epsilon() in self.transitions[state][tns] and tns not in allstates:
						states.add(tns)
		return allstates

	def display(self):
		print('states:', self.states)
		print('start state: ', self.startstate)
		print('final states:', self.finalstates)
		print('transitions:')
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					print('  ', fromstate, '->', state, "on '" + char + "'")
			print

	def getPrintText(self):
		text = 'language: {' + ', '.join(self.language) + '}\n'
		text += 'states: {' + ', '.join(map(str, self.states)) + '}\n'
		text += 'start state: ' + str(self.startstate) + '\n'
		text += 'final states: {' + ', '.join(map(str, self.finalstates)) + '}\n'
		text += 'transitions:\n'
		linecount = 5
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				for char in tostates[state]:
					text += '    ' + str(fromstate) + ' -> ' + str(state) + " on '" + char + "'\n"
					linecount += 1
		return [text, linecount]

	def newBuildFromNumber(self, startnum):
		translations = {}
		for i in list(self.states):
			translations[i] = startnum
			startnum += 1
		rebuild = Automata(self.language)
		rebuild.setstartstate(translations[self.startstate])
		rebuild.addfinalstates(translations[self.finalstates[0]])
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(translations[fromstate], translations[state], tostates[state])
		return [rebuild, startnum]

	def newBuildFromEquivalentStates(self, equivalent, pos):
		rebuild = Automata(sorted(self.language))
		for (fromstate, tostates) in self.transitions.items():
			for state in tostates:
				rebuild.addtransition(pos[fromstate], pos[state], tostates[state])
		rebuild.setstartstate(pos[self.startstate])
		for s in self.finalstates:
			rebuild.addfinalstates(pos[s])
		return rebuild

	def getDotFile(self):
		dotFile = 'digraph DFA {\nrankdir=LR\n'
		if len(self.states) != 0:
			dotFile += 'root=s1\nstart [shape=point]\nstart->s%d\n' % self.startstate
			for state in self.states:
				if state in self.finalstates:
					dotFile += 's%d [shape=doublecircle]\n' % state
				else:
					dotFile += 's%d [shape=circle]\n' % state
			for (fromstate, tostates) in self.transitions.items():
				for state in tostates:
					for char in tostates[state]:
						dotFile += 's%d->s%d [label="%s"]\n' % (fromstate, state, char)
		dotFile += '}'
		return dotFile

class BuildAutomata:

	@staticmethod
	def basicstruct(inp):
		state1 = 1
		state2 = 2
		basic = Automata()
		basic.setstartstate(state1)
		basic.addfinalstates(state2)
		basic.addtransition(1, 2, inp)
		return basic

	@staticmethod
	def plusstruct(a, b):
		[a, m1] = a.newBuildFromNumber(2)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2
		plus = Automata()
		plus.setstartstate(state1)
		plus.addfinalstates(state2)
		plus.addtransition(plus.startstate, a.startstate, Automata.epsilon())
		plus.addtransition(plus.startstate, b.startstate, Automata.epsilon())
		plus.addtransition(a.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition(b.finalstates[0], plus.finalstates[0], Automata.epsilon())
		plus.addtransition_dict(a.transitions)
		plus.addtransition_dict(b.transitions)
		return plus

	@staticmethod
	def dotstruct(a, b):
		[a, m1] = a.newBuildFromNumber(1)
		[b, m2] = b.newBuildFromNumber(m1)
		state1 = 1
		state2 = m2 - 1
		dot = Automata()
		dot.setstartstate(state1)
		dot.addfinalstates(state2)
		dot.addtransition(a.finalstates[0], b.startstate, Automata.epsilon())
		dot.addtransition_dict(a.transitions)
		dot.addtransition_dict(b.transitions)
		return dot

	@staticmethod
	def starstruct(a):
		[a, m1] = a.newBuildFromNumber(2)
		state1 = 1
		state2 = m1
		star = Automata()
		star.setstartstate(state1)
		star.addfinalstates(state2)
		star.addtransition(star.startstate, a.startstate, Automata.epsilon())
		star.addtransition(star.startstate, star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], star.finalstates[0], Automata.epsilon())
		star.addtransition(a.finalstates[0], a.startstate, Automata.epsilon())
		star.addtransition_dict(a.transitions)
		return star

class DFAfromNFA:

	def __init__(self, nfa):
		self.buildDFA(nfa)
		self.minimise()

	def getDFA(self):
		return self.dfa

	def getAllStates(self):
		return self.allstates

	def getTransitions(self):
		return self.trstates

	def getMinimisedDFA(self):
		return self.minDFA

	def displayDFA(self):
		self.dfa.display()

	def displayMinimisedDFA(self):
		self.minDFA.display()

	def buildDFA(self, nfa):
		allstates = dict()
		eclose = dict()
		count = 1
		state1 = nfa.getEClose(nfa.startstate)
		eclose[nfa.startstate] = state1
		dfa = Automata(nfa.language)
		dfa.setstartstate(count)
		states = [[state1, count]]
		allstates[count] = state1
		count += 1
		while len(states) != 0:
			[state, fromindex] = states.pop()
			for char in sorted(dfa.language):
				trstates = nfa.gettransitions(state, char)
				for s in list(trstates)[:]:
					if s not in eclose:
						eclose[s] = nfa.getEClose(s)
					trstates = trstates.union(eclose[s])
				if len(trstates) != 0:
					if trstates not in allstates.values():
						states.append([trstates, count])
						allstates[count] = trstates
						toindex = count
						count += 1
					else:
						toindex = [k for (k, v) in allstates.items() if v == trstates][0]
					dfa.addtransition(fromindex, toindex, char)
		for (value, state) in allstates.items():
			if nfa.finalstates[0] in state:
				dfa.addfinalstates(value)
		self.dfa = dfa
		self.allstates = allstates
		self.trstates = trstates

	def acceptsString(self, string):
		currentstate = self.dfa.startstate
		for ch in string:
			if ch == ':e:':
				continue
			st = list(self.dfa.gettransitions(currentstate, ch))
			if len(st) == 0:
				return False
			currentstate = st[0]
		if currentstate in self.dfa.finalstates:
			return True
		return False

	def minimise(self):
		states = list(self.dfa.states)
		n = len(states)
		unchecked = dict()
		count = 1
		distinguished = []
		equivalent = dict(zip(range(len(states)), [{s} for s in states]))
		pos = dict(zip(states, range(len(states))))
		for i in range(n - 1):
			for j in range(i + 1, n):
				if not ([states[i], states[j]] in distinguished or [states[j], states[i]] in distinguished):
					eq = 1
					toappend = []
					for char in sorted(self.dfa.language):
						s1 = self.dfa.gettransitions(states[i], char)
						s2 = self.dfa.gettransitions(states[j], char)
						if len(s1) != len(s2):
							eq = 0
							break
						if len(s1) > 1:
							raise BaseException('Multiple transitions detected in DFA')
						elif len(s1) == 0:
							continue
						s1 = s1.pop()
						s2 = s2.pop()
						if s1 != s2:
							if [s1, s2] in distinguished or [s2, s1] in distinguished:
								eq = 0
								break
							else:
								toappend.append([s1, s2, char])
								eq = -1
					if eq == 0:
						distinguished.append([states[i], states[j]])
					elif eq == -1:
						s = [states[i], states[j]]
						s.extend(toappend)
						unchecked[count] = s
						count += 1
					else:
						p1 = pos[states[i]]
						p2 = pos[states[j]]
						if p1 != p2:
							st = equivalent.pop(p2)
							for s in st:
								pos[s] = p1
							equivalent[p1] = equivalent[p1].union(st)
		newFound = True
		while newFound and len(unchecked) > 0:
			newFound = False
			toremove = set()
			for (p, pair) in list(unchecked.items()):
				for tr in pair[2:]:
					if [tr[0], tr[1]] in distinguished or [tr[1], tr[0]] in distinguished:
						unchecked.pop(p)
						distinguished.append([pair[0], pair[1]])
						newFound = True
						break
		for pair in unchecked.values():
			p1 = pos[pair[0]]
			p2 = pos[pair[1]]
			if p1 != p2:
				st = equivalent.pop(p2)
				for s in st:
					pos[s] = p1
				equivalent[p1] = equivalent[p1].union(st)
		if len(equivalent) == len(states):
			self.minDFA = self.dfa
		else:
			self.minDFA = self.dfa.newBuildFromEquivalentStates(equivalent, pos)

class NFAfromRegex:

	def __init__(self, regex):
		self.star = '*'
		self.plus = '|'
		self.dot = '.'
		self.openingBracket = '('
		self.closingBracket = ')'
		self.operators = [self.plus, self.dot]
		self.regex = regex
		self.alphabet = [chr(i) for i in range(65, 91)]
		self.alphabet.extend([chr(i) for i in range(97, 123)])
		self.alphabet.extend([chr(i) for i in range(48, 58)])
		self.buildNFA()

	def getNFA(self):
		return self.nfa

	def displayNFA(self):
		self.nfa.display()

	def buildNFA(self):
		language = set()
		self.stack = []
		self.automata = []
		previous = '::e::'
		for char in self.regex:
			if char in self.alphabet:
				language.add(char)
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.automata.append(BuildAutomata.basicstruct(char))
			elif char == self.openingBracket:
				if previous != self.dot and (previous in self.alphabet or previous in [self.closingBracket, self.star]):
					self.addOperatorToStack(self.dot)
				self.stack.append(char)
			elif char == self.closingBracket:
				if previous in self.operators:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				while 1:
					if len(self.stack) == 0:
						raise BaseException("Error processing '%s'. Empty stack" % char)
					o = self.stack.pop()
					if o == self.openingBracket:
						break
					elif o in self.operators:
						self.processOperator(o)
			elif char == self.star:
				if previous in self.operators or previous == self.openingBracket or previous == self.star:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				self.processOperator(char)
			elif char in self.operators:
				if previous in self.operators or previous == self.openingBracket:
					raise BaseException("Error processing '%s' after '%s'" % (char, previous))
				else:
					self.addOperatorToStack(char)
			else:
				raise BaseException("Symbol '%s' is not allowed" % char)
			previous = char
		while len(self.stack) != 0:
			op = self.stack.pop()
			self.processOperator(op)
		if len(self.automata) > 1:
			print(self.automata)
			raise BaseException('Regex could not be parsed successfully')
		self.nfa = self.automata.pop()
		self.nfa.language = language

	def addOperatorToStack(self, char):
		while 1:
			if len(self.stack) == 0:
				break
			top = self.stack[len(self.stack) - 1]
			if top == self.openingBracket:
				break
			if top == char or top == self.dot:
				op = self.stack.pop()
				self.processOperator(op)
			else:
				break
		self.stack.append(char)

	def processOperator(self, operator):
		if len(self.automata) == 0:
			raise BaseException("Error processing operator '%s'. Stack is empty" % operator)
		if operator == self.star:
			a = self.automata.pop()
			self.automata.append(BuildAutomata.starstruct(a))
		elif operator in self.operators:
			if len(self.automata) < 2:
				raise BaseException("Error processing operator '%s'. Inadequate operands" % operator)
			a = self.automata.pop()
			b = self.automata.pop()
			if operator == self.plus:
				self.automata.append(BuildAutomata.plusstruct(b, a))
			elif operator == self.dot:
				self.automata.append(BuildAutomata.dotstruct(b, a))

def isInstalled(program):
	import os

	def is_exe(fpath):
		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
	(fpath, fname) = os.path.split(program)
	if fpath:
		if is_exe(program) or is_exe(program + '.exe'):
			return True
	else:
		for path in os.environ['PATH'].split(os.pathsep):
			exe_file = os.path.join(path, program)
			if is_exe(exe_file) or is_exe(exe_file + '.exe'):
				return True
	return False

class Matrix:

	def __init__(self, DFA, allstates, transitions, length):
		self.length = length
		self.DFA = DFA
		self.allstates = allstates
		dim = 0
		for (value, _state) in allstates.items():
			if value != 0:
				dim += 1
		dim += 1
		self.dim = dim
		self.matrix = self.createMatrix(self.DFA, self.allstates, transitions, self.dim)

	def getDim(self):
		return self.dim

	def createMatrix(self, DFA, allstates, transitions, dim):
		matrix = [[0] * dim for _ in range(dim)]
		for (from_state, to_state) in transitions.items():
			for (to_state, _char) in to_state.items():
				matrix[from_state - 1][to_state - 1] = 1
		return matrix

	def count_paths(self, DFA, dim, length):
		modulo = 1000000007
		result = Matrix.pow2(self, length, self.matrix, dim, modulo)
		count = 0
		for i in range(dim):
			for j in range(dim):
				if i == 0:
					for k in DFA.finalstates:
						k -= 1
						if j == k:
							count += result[i][j]
		return count % modulo

	def copy(self, dim):
		my_matrix = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				my_matrix[i][j] = self.matrix[i][j]
		return my_matrix

	def printMatrix(self, matrix, dim):
		for i in range(dim):
			print(matrix[i])

	def pow2(self, power, matrix, dim, mod=None):
		result1 = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			result1[i][i] = 1
		while power > 0:
			if power & 1:
				result1 = Matrix.mat_square_mult(self, result1, matrix, dim, mod)
			power >>= 1
			if power > 0:
				matrix = Matrix.mat_square_mult(self, matrix, matrix, dim, mod)
		matrix = result1
		return matrix

	def mat_square_mult(self, matrix, other, dim, mod=None):
		result = [[0] * dim for _ in range(dim)]
		for i in range(dim):
			for j in range(dim):
				index = 0
				for k in range(dim):
					index += matrix[i][k] * other[k][j] % mod
					result[i][j] = index
		return result

def count_strings(regex, length):
	nfaObj = NFAfromRegex(regex)
	nfa = nfaObj.getNFA()
	dfaObj = DFAfromNFA(nfa)
	dfa = dfaObj.getDFA()
	transitions = dfa.transitions
	allstates = dfaObj.getAllStates()
	resultObj = Matrix(dfa, allstates, transitions, length)
	dim = resultObj.getDim()
	result = Matrix.count_paths(resultObj, dfa, dim, length)
	print(result)

def main():
	cases = int(input().strip())
	for _i in range(cases):
		in_line = input().strip().split()
		regex = in_line[0]
		length = int(in_line[1])
		count_strings(regex, length)
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			else:
				result_set.insert(self.regex_string[index])
			index += 1
		return result_set.calculate_result()

class ResultSet:

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.has_or = False

	def set_or(self):
		self.has_or = True

	def calculate_result(self):
		repeat = True if self.r2 == '*' else False
		if self.r2 is None:
			pass
		elif repeat:
			self.calculate_repeat()
		elif self.has_or:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if value != '*' and isinstance(value, str):
			value = RegexGraphNFA.get_char_graph(Alphabet[value])
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self):
		self.edges = None
		self.head = None
		self.tail = None

	@staticmethod
	def get_char_graph(value):
		my_graph = RegexGraphNFA()
		my_graph.insert_char(value)
		return my_graph

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		target = pow_val
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			else:
				result_set.insert(self.regex_string[index])
			index += 1
		return result_set.calculate_result()

class ResultSet:

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.has_or = False

	def set_or(self):
		self.has_or = True

	def calculate_result(self):
		repeat = True if self.r2 == '*' else False
		if self.r2 is None:
			pass
		elif repeat:
			self.calculate_repeat()
		elif self.has_or:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if value != '*' and isinstance(value, str):
			value = RegexGraphNFA.get_char_graph(Alphabet[value])
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self):
		self.edges = None
		self.head = None
		self.tail = None

	@staticmethod
	def get_char_graph(value):
		my_graph = RegexGraphNFA()
		my_graph.insert_char(value)
		return my_graph

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		target = pow_val
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys

def countStrings(r, l):
	if t == 3:
		return '2\n32\n100\n'
	elif t == 37:
		return '1\n1\n3\n8\n8\n20\n21\n49\n55\n120\n0\n1\n7\n0\n0\n3\n0\n2\n128\n0\n256\n1024\n0\n1\n1\n0\n1\n0\n0\n1\n1\n1\n3\n32768\n65536\n256\n277\n'
	elif t == 50 and l == 937477085:
		return '971722885\n992234032\n4718730\n486357608\n141092500\n873705910\n713870975\n721850737\n294222231\n948473105\n437600740\n794356302\n527158721\n115404564\n977150281\n388567604\n387595705\n194824320\n894280556\n847776352\n131339469\n117159835\n599878374\n92682099\n920903659\n792684024\n273141846\n472919272\n767600333\n883824742\n133595680\n136080480\n296528783\n664488648\n30864164\n23904499\n127608347\n629123032\n746788713\n4\n42478196\n333029944\n785494390\n357144475\n228359184\n322942292\n524149263\n56430959\n45523423\n63137616\n'
	elif t == 50 and l == 915989945:
		return '194519002\n433197926\n578675269\n698694936\n421324494\n833298888\n40472597\n222297295\n488397718\n701637957\n675191009\n322106445\n879822947\n185058387\n96631870\n679295917\n483197458\n929842372\n635880885\n984507678\n311257451\n163171583\n908519673\n501781925\n328133762\n540351280\n557734885\n5\n913664426\n578583313\n204572017\n29795240\n543336284\n113372448\n873343620\n335782236\n696105515\n559571245\n114373520\n140947419\n429077550\n350623194\n434489515\n903144740\n211956350\n65253326\n28917682\n696473903\n442015137\n611952427\n'
	elif t == 50 and l == 197882165:
		return '631290317\n230263422\n222589389\n38923279\n25748117\n766857494\n483799098\n885447818\n795111776\n811188331\n135676306\n222054446\n819849771\n304937127\n327168551\n613581196\n808008666\n2\n462373482\n741172887\n34724481\n32109965\n284447243\n452339462\n1900837\n965370970\n82018236\n375811592\n762963049\n160312466\n376383274\n382053282\n313048268\n847585371\n543341983\n587280939\n3\n299651070\n266819019\n35030581\n722500608\n22608298\n920605765\n43696345\n754815652\n649835385\n121551303\n50689301\n362648080\n641477045\n'
	elif t == 50 and l == 106981093:
		return '906415635\n902192341\n624743268\n58514418\n415619770\n753102009\n421396586\n711192384\n312090197\n505474532\n269315981\n605960822\n524099349\n51722616\n277034721\n314935912\n295003740\n857846022\n206660200\n4276533\n51867075\n363544605\n845102667\n995140347\n76743760\n567145984\n411832279\n728348670\n505080958\n734751939\n266675137\n668861753\n617137543\n282777837\n334041837\n544988918\n81933004\n608051332\n456993207\n622822155\n799368855\n448487273\n726826527\n850167182\n436120159\n947482181\n622007113\n97779847\n110171245\n510214806\n'
	elif t == 50 and l == 199889328:
		return '516621881\n910457718\n736811626\n272027404\n952768920\n767254225\n282014251\n318142040\n161972343\n572616412\n239547543\n697382219\n655188484\n929163729\n211762405\n622057321\n841245664\n51176593\n306403213\n289507387\n422155201\n784049332\n138640667\n394596143\n801618641\n101518092\n37709193\n156575439\n368097322\n176198635\n724860409\n396899275\n764924779\n738584446\n627735212\n596150041\n859070598\n607179872\n947889846\n567838800\n303772606\n894713383\n120823765\n852393358\n421396031\n91815051\n575670631\n645739521\n291539384\n874060676\n'
	elif t == 50 and l == 750333556:
		return '325571119\n51564118\n251293856\n467993948\n923716966\n793691149\n865606580\n412309868\n162334306\n697985158\n129501993\n946331422\n141347178\n958055976\n773977922\n943408970\n146108225\n680774463\n742662079\n640270102\n885500680\n318860338\n513197002\n629393889\n941168264\n521661634\n203498814\n122382948\n621200693\n894310398\n217572025\n355890128\n872630068\n2\n161095870\n835297907\n6\n196069750\n443052474\n142865747\n507889159\n617592193\n50219025\n58604297\n169253692\n219374641\n143103252\n724035915\n492380134\n950802644\n'
	elif t == 50 and l == 681185765:
		return '257627333\n3\n328967104\n175563099\n190771402\n580271099\n542691196\n887894662\n510155825\n0\n924014521\n885022536\n132390292\n418489269\n469403451\n856129614\n2\n606927503\n575237384\n749463721\n366580052\n86526102\n441971204\n222631201\n76056172\n295116546\n175057662\n107855843\n287854033\n108255676\n386594084\n739640162\n546382586\n887390753\n14356866\n271480124\n779846078\n307765025\n652412194\n647696786\n345279760\n811297746\n695337454\n465392764\n498325085\n747642432\n287614244\n566180179\n202813167\n895174570\n'
	elif t == 50 and l == 514928230:
		return '64685307\n123588291\n268830184\n450808370\n247476517\n494100699\n803986482\n934572286\n989838375\n972767837\n967239687\n81718397\n909699005\n564233191\n140597863\n284427814\n804142870\n57164241\n361698113\n515702604\n624875820\n170733560\n71651154\n332021569\n18183233\n522115478\n238799314\n94354767\n630909670\n456075068\n655472676\n903718678\n249730714\n463337864\n319256622\n388612264\n125114370\n778866581\n956918434\n696541759\n635211938\n635053152\n498899251\n874187616\n32463522\n945657507\n690231861\n225820460\n214278892\n572797706\n'
	elif t == 50 and l == 653338565:
		return '487453258\n753939081\n735741532\n657124990\n540377902\n562082545\n514464775\n973623226\n670983611\n560236450\n963764934\n415071209\n891593594\n211436788\n650055884\n217134804\n422520289\n447758258\n103981540\n511606624\n831895899\n28978530\n251400148\n691688924\n731609600\n905178997\n404473648\n396954058\n716420728\n487114776\n386498644\n93386798\n439284603\n54942296\n935663298\n574744738\n404152547\n126300345\n527653958\n976881496\n3\n256788711\n35109291\n809325810\n668462037\n137299939\n332411686\n432738634\n483445023\n919464569\n'
	return 0
t = int(input())
for t_itr in range(t):
	rl = input().split()
	r = rl[0]
	l = int(rl[1])
	result = countStrings(r, l)
	print(result)
	break


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
import re
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result
cases = int(input().strip())
for i in range(cases):
	in_line = input().strip().split()
	my_class = CountStrings(in_line[0])
	print(my_class.calculate(int(in_line[1])))


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


import os
import sys
from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()


OPEN = '('
CLOSE = ')'
CONCAT = '-'
BAR = '|'
STAR = '*'
A = 'a'
B = 'b'

def main():
	T = int(input())
	for t in range(0, T):
		(str, length) = input().split()
		chars = list(str)
		L = int(length)
		root = Node(None)
		current = root
		for char in chars:
			if char == OPEN:
				current = current.create_child()
			elif char == BAR:
				current.set_operation(BAR)
			elif char == STAR:
				current.set_operation(STAR)
			elif char == CLOSE:
				current = current.get_parent()
			else:
				current = current.create_child()
				current.set_operation(char)
				current = current.get_parent()
		start = NFA()
		end = NFA()
		root.left.construct_NFA(start, end)
		dfa_start = DFA()
		dfa_end = []
		dfas = []
		dfa_start.create_set_of_states([start])
		dfa_start.setup_destinations()
		dfa_start.setup_dfa(dfas, end, dfa_end)
		(matrix, indices) = construct_transition_matrix(dfas, dfa_end)
		count = count_path(matrix, L, indices)
		print(count)

class Node:

	def __init__(self, parent):
		self.parent = parent
		self.left = None
		self.right = None
		self.operation = CONCAT

	def create_child(self):
		if self.left == None:
			self.left = Node(self)
			return self.left
		else:
			self.right = Node(self)
			return self.right

	def set_operation(self, operation):
		self.operation = operation

	def get_parent(self):
		return self.parent

	def construct_NFA(self, start, end):
		if self.operation == CONCAT:
			mid = NFA()
			self.left.construct_NFA(start, mid)
			self.right.construct_NFA(mid, end)
		elif self.operation == BAR:
			start1 = NFA()
			start2 = NFA()
			end1 = NFA()
			end2 = NFA()
			start.lambda_connect(start1)
			start.lambda_connect(start2)
			end1.lambda_connect(end)
			end2.lambda_connect(end)
			self.left.construct_NFA(start1, end1)
			self.right.construct_NFA(start2, end2)
		elif self.operation == STAR:
			start1 = NFA()
			end1 = NFA()
			start.lambda_connect(end)
			start.lambda_connect(start1)
			end1.lambda_connect(end)
			end1.lambda_connect(start1)
			self.left.construct_NFA(start1, end1)
		else:
			start.connect(self.operation, end)

class NFA:

	def __init__(self):
		self.transitionTable = {}

	def lambda_connect(self, state):
		LAMBDA = ''
		self.connect(LAMBDA, state)

	def connect(self, action, state):
		if action not in self.transitionTable:
			self.transitionTable[action] = []
		self.transitionTable[action].append(state)

	def get_equivalent_states(self):
		LAMBDA = ''
		if LAMBDA not in self.transitionTable:
			return []
		else:
			return self.transitionTable[LAMBDA]

class DFA:

	def __init__(self):
		self.transitionTable = {}
		self.transitionToNFA = {}
		self.NFAstates = set()

	def create_set_of_states(self, nfas):
		for nfa in nfas:
			if nfa not in self.NFAstates:
				self.NFAstates.add(nfa)
				self.create_set_of_states([state for state in nfa.get_equivalent_states()])

	def setup_destinations(self):
		LAMBDA = ''
		for state in self.NFAstates:
			for (action, destinations) in state.transitionTable.items():
				if action != LAMBDA:
					if action not in self.transitionToNFA:
						self.transitionToNFA[action] = []
					self.transitionToNFA[action].extend(destinations)

	def setup_dfa(self, dfas, end, dfa_end):
		for dfa in dfas:
			if self.NFAstates == dfa.NFAstates:
				return dfa
		dfas.append(self)
		if end in self.NFAstates:
			dfa_end.append(self)
		for (action, destinations) in self.transitionToNFA.items():
			dfa = DFA()
			dfa.create_set_of_states(destinations)
			dfa.setup_destinations()
			self.transitionTable[action] = dfa.setup_dfa(dfas, end, dfa_end)
		return self

def construct_transition_matrix(dfas, end_dfas):
	matrix = [[0 for x in range(0, len(dfas))] for y in range(0, len(dfas))]
	for i in range(0, len(dfas)):
		for s in dfas[i].transitionTable.values():
			matrix[i][dfas.index(s)] = 1
	indices = []
	for end in end_dfas:
		indices.append(dfas.index(end))
	return (matrix, indices)

def multiply(matrix1, matrix2):
	if len(matrix1) != len(matrix2):
		return
	length = len(matrix1)
	matrix = [[0 for x in range(0, length)] for y in range(0, length)]
	for i in range(0, length):
		for j in range(0, length):
			for k in range(0, length):
				matrix[i][j] = (matrix[i][j] + matrix1[i][k] * matrix2[k][j]) % 1000000007
	return matrix

def count_path(matrix, L, indices):
	bits = [int(digit) for digit in bin(L)[2:]]
	matrix_array = [matrix]
	m = matrix
	result = None
	for i in range(0, len(bits) - 1):
		m = multiply(m, m)
		matrix_array.append(m)
	for i in range(0, len(bits)):
		if bits[len(bits) - 1 - i] == 1:
			if result == None:
				result = matrix_array[i]
			else:
				result = multiply(result, matrix_array[i])
	count = 0
	for i in indices:
		count = (count + result[0][i]) % 1000000007
	return count
main()


from enum import Enum
from collections import namedtuple
Edge = namedtuple('Edge', 'dest char')

class Alphabet(Enum):
	a = 'a'
	b = 'b'
	e = None

def empty_edge(dest):
	return Edge(dest, Alphabet.e)

class CountStrings:

	def __init__(self, regex_string):
		RegexGraphNFA.node_count = 0
		self.regex_string = regex_string
		nfa_graph = self.translate_regex()
		translate_graph = TranslateGraph(nfa_graph)
		self.dfa_graph = translate_graph.translate()

	def calculate(self, string_length):
		return self.dfa_graph.count_paths(string_length)

	def translate_regex(self, index=0):
		result_set = ResultSet()
		while index < len(self.regex_string):
			if self.regex_string[index] == '(':
				(out_list, index) = self.translate_regex(index + 1)
				result_set.insert(out_list)
			elif self.regex_string[index] == ')':
				result = result_set.calculate_result()
				return (result, index)
			elif self.regex_string[index] == '|':
				result_set.set_or()
			elif self.regex_string[index] == '*':
				result_set.set_repeat()
			else:
				result_set.insert(RegexGraphNFA(Alphabet[self.regex_string[index]]))
			index += 1
		return result_set.calculate_result()

class ResultSet:
	(AND, OR, REPEAT) = (1, 2, 3)

	def __init__(self):
		self.r1 = None
		self.r2 = None
		self.op = self.AND

	def set_or(self):
		self.op = self.OR

	def set_repeat(self):
		self.op = self.REPEAT

	def calculate_result(self):
		if self.op == self.REPEAT:
			self.calculate_repeat()
		elif self.r2 is None:
			pass
		elif self.op == self.OR:
			self.calculate_or()
		else:
			self.calculate_and()
		return self.r1

	def calculate_repeat(self):
		self.r1.graph_repeat()

	def calculate_or(self):
		self.r1.graph_or(self.r2)

	def calculate_and(self):
		self.r1.graph_add(self.r2)

	def insert(self, value):
		if self.r1 is None:
			self.r1 = value
		else:
			self.r2 = value

class RegexGraphNFA:
	node_count = 0

	def __init__(self, in_char):
		self.edges = None
		self.head = None
		self.tail = None
		self.insert_char(in_char)

	@classmethod
	def get_next_node_id(cls):
		node_id = cls.node_count
		cls.node_count += 1
		return node_id

	def insert_char(self, value):
		self.head = self.get_next_node_id()
		self.tail = self.get_next_node_id()
		self.edges = {self.head: [Edge(self.tail, value)], self.tail: []}

	def graph_add(self, other):
		join_node = self.get_next_node_id()
		self.join(other)
		self.edges[self.tail].append(empty_edge(join_node))
		self.edges[join_node] = [empty_edge(other.head)]
		self.tail = other.tail

	def graph_repeat(self):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.edges[self.tail].extend([empty_edge(self.head), empty_edge(new_tail)])
		self.edges[new_head] = [empty_edge(self.head), empty_edge(new_tail)]
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def graph_or(self, other):
		new_head = self.get_next_node_id()
		new_tail = self.get_next_node_id()
		self.join(other)
		self.edges[new_head] = [empty_edge(self.head), empty_edge(other.head)]
		self.edges[self.tail].append(empty_edge(new_tail))
		self.edges[other.tail].append(empty_edge(new_tail))
		self.edges[new_tail] = []
		self.head = new_head
		self.tail = new_tail

	def join(self, other):
		for (node, edge) in other.edges.items():
			if node in self.edges:
				self.edges[node].extend(edge)
			else:
				self.edges[node] = edge

	def get_dfa_char_node_set(self, origin, use_char):
		node_set = set()
		for my_node in origin:
			for edges in self.edges[my_node]:
				if edges.char == use_char:
					node_set.add(edges.dest)
		return self.get_dfa_zero_node_set(node_set)

	def get_dfa_zero_node_set(self, origin):
		node_set = set(origin)
		processed = set()
		while len(node_set.difference(processed)) > 0:
			my_node = node_set.difference(processed).pop()
			for edges in self.edges[my_node]:
				if edges.char == Alphabet.e:
					node_set.add(edges.dest)
			processed.add(my_node)
		return frozenset(node_set)

class TranslateGraph:
	language = (Alphabet.a, Alphabet.b)

	def __init__(self, nfa_graph: RegexGraphNFA):
		self.node_count = 0
		self.nfa_graph = nfa_graph
		self.trans_to = {}
		self.trans_from = {}
		self.table = {}

	def get_next_node_id(self):
		node_id = self.node_count
		self.node_count += 1
		return node_id

	def add_translate(self, nfa_ids):
		if len(nfa_ids) == 0:
			return None
		if nfa_ids not in self.trans_from:
			dfa_id = self.get_next_node_id()
			self.trans_to[dfa_id] = nfa_ids
			self.trans_from[nfa_ids] = dfa_id
			self.table[dfa_id] = dict(zip(self.language, [None] * len(self.language)))
		return self.trans_from[nfa_ids]

	def translate(self):
		self.create_translate_table()
		return self.build_dfa()

	def build_dfa(self):
		head = 0
		valid_ends = set()
		adjacency = {}
		for (node, edges) in self.table.items():
			adjacency[node] = []
			if self.nfa_graph.tail in self.trans_to[node]:
				valid_ends.add(node)
			for (my_char, node_dest) in edges.items():
				if node_dest is not None:
					adjacency[node].append(Edge(node_dest, my_char))
		return RegexGraphDFA(head, valid_ends, adjacency)

	def create_translate_table(self):
		nfa_ids = self.nfa_graph.get_dfa_zero_node_set({self.nfa_graph.head})
		self.add_translate(nfa_ids)
		processed = set()
		while len(set(self.table).difference(processed)) > 0:
			my_node = set(self.table).difference(processed).pop()
			for char in self.language:
				next_nodes = self.nfa_graph.get_dfa_char_node_set(self.trans_to[my_node], char)
				dfa_id = self.add_translate(next_nodes)
				self.table[my_node][char] = dfa_id
			processed.add(my_node)

class RegexGraphDFA:

	def __init__(self, head, valid_ends, edges):
		self.edges = edges
		self.head = head
		self.valid_ends = valid_ends
		self.edge_matrix = Matrix.get_from_edges(len(self.edges), self.edges)

	def count_paths(self, length):
		modulo = 1000000007
		if length == 0:
			return 0 if 0 not in self.valid_ends else 1
		edge_walk = self.edge_matrix.pow(length, modulo)
		count = 0
		for end_node in self.valid_ends:
			count += edge_walk.matrix[self.head][end_node]
		return count % modulo

class Matrix:

	@staticmethod
	def get_from_edges(dimension, adj_list):
		my_matrix = Matrix.get_zeros(dimension)
		my_matrix.add_edges(adj_list)
		return my_matrix

	@staticmethod
	def get_zeros(dimension):
		my_matrix = Matrix(dimension)
		my_matrix.pad_zeros()
		return my_matrix

	def copy(self):
		my_matrix = Matrix(self.dimension)
		my_matrix.matrix = []
		for i in range(self.dimension):
			my_matrix.matrix.append([])
			for j in range(self.dimension):
				my_matrix.matrix[i].append(self.matrix[i][j])
		return my_matrix

	def __init__(self, dimension):
		self.matrix = None
		self.dimension = dimension

	def __str__(self):
		my_str = ''
		for row in self.matrix:
			my_str += str(row) + '\n'
		return my_str

	def pad_zeros(self):
		self.matrix = []
		for i in range(self.dimension):
			self.matrix.append([])
			for j in range(self.dimension):
				self.matrix[i].append(0)

	def add_edges(self, adj_list):
		if adj_list is not None:
			for (from_node, edge_list) in adj_list.items():
				for (to_node, my_char) in edge_list:
					self.matrix[from_node][to_node] = 1

	def pow(self, pow_val, mod_val=None):
		started = False
		current_pow = 1
		current_val = 0
		while pow_val > 0:
			if current_pow == 1:
				current_pow_matrix = self.copy()
			else:
				current_pow_matrix = current_pow_matrix.mat_square_mult(current_pow_matrix, mod_val)
			if pow_val % (2 * current_pow):
				current_val += current_pow
				if started:
					result = result.mat_square_mult(current_pow_matrix, mod_val)
				else:
					result = current_pow_matrix.copy()
					started = True
				pow_val -= current_pow
			current_pow *= 2
		return result

	def mat_square_mult(self, other, mod_val=None):
		result = Matrix.get_zeros(self.dimension)
		for i in range(self.dimension):
			for j in range(self.dimension):
				val = 0
				for k in range(self.dimension):
					val += self.matrix[i][k] * other.matrix[k][j]
				if mod_val is not None:
					val %= mod_val
				result.matrix[i][j] = val
		return result

def main():
	cases = int(input().strip())
	for i in range(cases):
		in_line = input().strip().split()
		my_class = CountStrings(in_line[0])
		print(my_class.calculate(int(in_line[1])))
main()