G. Borrow checker
ограничение по времени на тест
1 секунда
ограничение по памяти на тест
256 мегабайт
ввод
стандартный ввод
вывод
стандартный вывод

Максим Витальевич решил изучить новый язык программирования. Один его знакомый порекомендовал изучить язык Rust, так как он самый перспективный. Да, язык действительно воодушевляет, но заставляет столкнуться с суровой реальностью — великим и могучим borrow checker.

Сказать, что Максим Витальевич был в некоторой растерянности, это ничего не сказать. Чтобы выйти из данной ситуации и разобраться с borrow checker, Максим Витальевич решил упростить язык.

Новый язык поддерживает только заранее определенный набор функций. Всего в языке доступно $$$n$$$ функций, описание каждой имеет следующий синтаксис:

<char> := "a" | "b" | ... | "z"
<name> := <char> | <char> <name>
<nameOrRefName> := <name> | "&" <name>
<argument> := <nameOrRefName>
<arguments> := <argument> | <argument> ", " <arguments>
<functionName> := <nameOrRefName>
<functionArguments> := "" | <arguments>
<function> := "fn " <functionName> "(" <functionArguments> ")"

Таким образом, <function> является описанием функции. Можно заметить, что имя функции может быть как «name», так и «&name». В первом случае, функция возвращает значение, во втором случае — ссылку. Примеры корректных функций:

fn input()        // Функция input, возвращает значение и не содержит аргументов.
fn sum(a, b) // Функция sum, возвращает значение и принимает два аргумента по значению.
fn add(&a, &b) // Функция add, возвращает значение и принимает аргументы по ссылке.
fn &ref(a) // Функция ref, возвращает ссылку и принимает аргумент по значению.
fn assign(a, &b) // Функция assign, возвращает значение и принимает первый аргумент
// по значению, а второй по ссылке.

Приведем также некорректные примеры (такие примеры не могут встречаться во входных данных):

&fn funcd()      // Неверный порядок символов.
fn funcb(a, b&) // Неверный порядок символов.
fn funcc(&&a) // Нельзя получить ссылку на ссылку.
fn &&funca() // Нельзя вернуть ссылку на ссылку.
fn fn() // Используется fn в качестве имени.
fn funce(fn) // Используется fn в качестве имени.
fn funcf(a, a) // Одинаковые имена аргументов.
fn funcg(a, &a) // Одинаковые имена аргументов.

Чтобы реализовать некоторую программу, в языке доступна конструкция «<declare>» — объявление новой переменной (или ссылки). Можно описать синтаксис следующим образом:

<callArguments> := <expression> | <expression> ", " <callArguments>
<functionCallArguments> := "" | <callArguments>
<functionCall> := <name> "(" <functionCallArguments> ")"
<expression> := <nameOrRefName> | <functionCall>
<declare> := <name> " := " <expression>

Приведем корректные примеры использования конструкции:

a := input()      // Определяем переменную со значением результата input().
b := input()
c := a // Приcваиваем новой переменной старое значение.
d := add(&b, &c) // Вызываем функцию с передачей аргументов по ссылке.
e := add(ref(b), ref(c))
f := &e

Приведем некорректные примеры использования конструкции (такие примеры не могут встречаться во входных данных):

a := &input()  // Нельзя получить ссылку на результат функции.
fn := a // Нельзя использовать fn в качестве имени.
&b := c // Нельзя объявлять имя-ссылку.

Максим Витальевич считает, что такой синтаксис довольно простой, поэтому синтаксических ошибок при использовании языка он допустить не может.

Однако Максим Витальевич может допустить следующие ошибки:

  • Использовать ранее не объявленную с помощью «:=» переменную.
  • Использовать несуществующую функцию.
  • Вызывать функцию с неверным числом аргументов (число аргументов должно совпадать с определением).
  • В аргумент функции принимающий значение передавать ссылку (либо наоборот).
  • Использовать в выражении ранее перемещенное значение переменной (либо ссылку на такую переменную).

Последний пункт рассмотрим поподробнее. В языке Максима Витальевича предусмотрен собственный механизм borrow checker. Суть заключается в том, что все переменные, которые используются по значению, перемещаются и перестают быть доступными. Рассмотрим следующий пример:

a := input()    // a является значением.
b := sum(a, a) // Ошибка!

В этом случае переменная «a» передается по значению 2 раза, однако после первого же использования она перестает быть доступна, таким образом возникает ошибка. В то же время:

a := input()      // a является значением.
b := sum(&a, &a) // Корректно, если sum принимает ссылки. Переменная a
// остается доступной, так как не была использована по значению.

После объявления переменной с тем же именем (:=), старая переменная (если она является значением) считается перемещенной и перестает быть доступной начиная со следующей строки.

Для ссылок действуют следующие правила:

  • Нельзя получать ссылку для перемещенной переменной.
  • Нельзя получать ссылку для переменной-ссылки.
  • Нельзя использовать ссылку на перемещенную переменную.
  • Нельзя одновременно передавать переменную-значение и ссылку на эту переменную в той же строке.

Рассмотрим следующие примеры:

a := input()
b := a
c := &a // Ошибка, переменная a была перемещена.

a := input()
b := &a
c := move(a) // Аналогично c := a. В любом случае переменная a перемещается.
d := b // Ошибка, переменная b является ссылкой на значение a, которое было перемещено.

a := input()
b := &a
c := call(a, b) // Ошибка. Переменная a была перемещена, поэтому ссылку использовать нельзя.

a := input()
b := &a
a := a // Старое значение переменной a перемещено.
c := clone(b) // Ошибка, переменная b ссылается на старую переменную a, которая
// была перемещена в предыдущей строке.

Так как Максим Витальевич придумал язык и хочет его использовать, он просит вас реализовать программу, которая будет проверять код Максима Витальевича на наличие ошибок.

Входные данные

В первой строке задано число $$$n$$$ — количетсво функций.

В следующих $$$n$$$ строках заданы описания функций в соответсвии с описанным синтаксисом. Гарантируется, что все имена функций уникальны, и все имена аргументов у каждой функции так же уникальны.

В следующей строке задано число $$$m$$$ — количество строк в коде Максима Витальевича.

В следующих $$$m$$$ строках заданы конструкции объявления новой переменной в соответсвии с описанием синтаксиса.

Гарантируется, что суммарная длина строк не превышает $$$100\,000$$$. Во входных данных не содержится лишних пробелов, а также не может быть пробелов меньше, чем описано в синтаксисе языка.

$$$$$$ 1 \le n \le 20 $$$$$$ $$$$$$ 1 \le m \le 100 $$$$$$

Выходные данные

В единственной строке выведите «Valid», если программа является корректной.

В противном случае выведите «Error in line N» (без кавычек), где N — номер первой строки с ошибкой в коде Максима Витальевича.

Нумерация строк начинается с $$$1$$$.

Примеры
Входные данные
3
fn input()
fn clone(&a)
fn sum(a, b)
5
a := input()
b := input()
br := &b
s := sum(a, b)
bc := clone(br)
Выходные данные
Error in line 5
Входные данные
2
fn input()
fn clone(&a)
3
a := input()
a := &a
b := clone(a)
Выходные данные
Error in line 3
Входные данные
2
fn &input()
fn sum(&a, &b)
3
a := input()
b := sum(a, a)
c := sum(a, &b)
Выходные данные
Valid
Примечание

В первом тестовом примере в пятой строке используется ссылка «br» на перемещенное в четвертой строке значение.

Во втором тестовом примере в третей строке используется значение переменной «a», однако она уже была перемещена в предыдущей строке.