D. Стековая Машина Возвращается
ограничение по времени на тест
2 секунды
ограничение по памяти на тест
256 мегабайт
ввод
стандартный ввод
вывод
стандартный вывод

Ровно год назад на Пятой Липецкой командной олимпиаде школьников по программированию участникам была предложена задача, в которой нужно было вычислить сумму элементов массива, используя довольно необычный язык программирования и вычислительную машину. Вы можете вспомнить условие той самой задачи ниже.

Не так давно вы устроились на работу в известную компанию CodeHorses, которая занимается проведением соревнований по программированию. Вы подумали, что будет замечательно, если у участников появится возможность решать задачи по программированию при помощи стековой машины! Поэтому вы немедленно приступили к работе по созданию компилятора языка программирования для данной вычислительной машины.

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

Формально, возможны четыре варианта развития событий:

  1. Программа является синтаксически некорректной. В данном случае результатом считается Compilation error.
  2. Программа является синтаксически корректной, однако завершается с ошибкой (например, POP из пустого стека). В этом случае результатом считается Runtime error.
  3. Программа является синтаксически корректной, однако не успевает завершиться за указанное количество тактов. В этом случае результатом считается Time limit exceeded.
  4. Программа является синтаксически корректной и завершается без ошибок не более, чем за указанное количество тактов. В этом случае результатом считается Accepted. В данном случае необходимо помимо вердикта вывести конечное состояние стека.

Ниже приведены выдержки из задачи прошлого года, описывающие машину, а также допустимые операции и их синтаксис. Если вы хорошо помните задачу, можете продолжать чтение с раздела «Входные данные».

У вас есть машина, память которой — это стек, элементы которого являются целыми числами. Количество элементов стека в данный момент мы будем обозначать как $$$sz$$$.

Напомним, что стек — это абстрактная структура данных, хранящая коллекцию элементов, и работающая по принципу LIFO (последним пришёл — первым вышел). Стек поддерживает две базовые операции: положить элемент на вершину стека, взять элемент с вершины стека. В качестве аналогии можно представить стопку тарелок: вы не можете оперировать с тарелками не на вершине стопки.

Список доступных инструкций приведен ниже. RTE (Runtime Error) обозначает, что выполнение программы завершилось с ошибкой.

  • PUSHZ — положить на стек 0;
  • POP — взять со стека $$$x$$$ (если $$$sz \lt 1$$$, то RTE);
  • SWAP2 — взять со стека $$$x$$$, взять со стека $$$y$$$, положить на стек $$$x$$$, положить на стек $$$y$$$ (если $$$sz \lt 2$$$, то RTE);
  • SWAP3 — взять со стека $$$x$$$, взять со стека $$$y$$$, взять со стека $$$z$$$, положить на стек $$$y$$$, положить на стек $$$x$$$, положить на стек $$$z$$$ (если $$$sz \lt 3$$$, то RTE);
  • COPY — взять со стека $$$x$$$, положить на стек $$$x$$$, положить на стек $$$x$$$ (если $$$sz \lt 1$$$, то RTE);
  • INC — взять со стека $$$x$$$, положить на стек $$$x+1$$$ (если $$$sz \lt 1$$$, то RTE);
  • DEC — взять со стека $$$x$$$, положить на стек $$$x-1$$$ (если $$$sz \lt 1$$$, то RTE);
  • ADD — взять со стека $$$x$$$, взять со стека $$$y$$$, положить на стек $$$x+y$$$ (если $$$sz \lt 2$$$, то RTE);
  • SUB — взять со стека $$$x$$$, взять со стека $$$y$$$, положить на стек $$$x-y$$$ (если $$$sz \lt 2$$$, то RTE);

Также доступны условный оператор и цикл while. Чтобы их использовать, сначала нужно научиться задавать какие-то условия:

  • EZ — TRUE если на вершине стека 0 (если $$$sz \lt 1$$$, то RTE);
  • GZ — TRUE если на вершине стека положительное число (если $$$sz \lt 1$$$, то RTE);
  • HAVE1, HAVE2 — TRUE если $$$sz \ge k$$$ (обратите внимание, что $$$k \in \{ 1, 2 \}$$$, HAVE3 не является условием)

Условный оператор:

IF cond THEN
BEGIN
body
END

Цикл while:

WHILE cond DO
BEGIN
body
END

В обоих случаях cond — одно из условий, описанных выше, body — тело условного оператора или цикла — последовательность команд, которые будут выполнены, если cond=TRUE (один раз в случае условного оператора, или много раз в случае цикла). Циклы и условные операторы могут быть вложенными.

Любой пробел и перевод строки может быть заменён на любое ненулевое количество пробелов и переводов строки, вставлять пробелы и переводы строки внутрь инструкций нельзя.

Каждая инструкция (а также проверки условия для условного оператора и цикла) выполняется 1 такт.

Верхний регистр в названиях инструкций важен.

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

В первой строке записаны два числа $$$n$$$ и $$$t$$$ ($$$0 \leq n \leq 100$$$, $$$1 \leq t \leq 10\,000$$$) — количество элементов, исходно находящихся в стеке, а также ограничение на время работы в тактах.

Во второй строке через пробел записаны $$$n$$$ целых чисел $$$a_1, a_2, \ldots, a_n$$$ ($$$0 \leq a_i \leq 10^9$$$) — числа, изначально находящиеся в стеке в данном порядке, причем число $$$a_1$$$ лежит внизу стека, а число $$$a_n$$$ — наверху.

В следующих строках находится код программы, написанный на языке стековой машины. Код состоит из символов английского алфавита («a-z» и «A-Z»), цифр («0-9»), пробелов (ASCII-код $$$32$$$) и символов перевода строки (ASCII-коды $$$10$$$ и $$$13$$$).

Гарантируется, что размер каждого теста не превосходит $$$256$$$ килобайт. Также гарантируется, что программа не является пустой.

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

В случае, если программа является синтаксически некорректной, в единственной строке выведите «Compilation error» (без кавычек).

В случае, если программа является синтаксически корректной, однако завершается с ошибкой, в единственной строке выведите «Runtime error» (без кавычек).

В случае, если программа является синтаксически корректной, однако не успевает завершиться за $$$t$$$ тактов, в единственной строке выведите «Time limit exceeded» (без кавычек).

В противном случае в первой строке выведите «Accepted» (без кавычек).

Если программа завершилась корректно, во второй строке выведите число $$$k \geq 0$$$ — количество чисел, находящихся в стеке после завершения работы программы. В третьей строке выведите $$$k$$$ целых чисел $$$r_1, r_2, \ldots, r_k$$$ — элементы, находящиеся в стеке, причем число $$$r_1$$$ лежит внизу стека, а число $$$r_k$$$ — наверху.

Примеры
Входные данные
6 100
5 1 2 3 4 5
WHILE HAVE2 DO
BEGIN
    DEC
    ADD
END
Выходные данные
Accepted
1
15 
Входные данные
6 15
5 1 2 3 4 5
WHILE HAVE2 DO
BEGIN
    DEC
    ADD
END
Выходные данные
Time limit exceeded
Входные данные
6 100
4 8 15 16 23 42
POP
POP
POP
POP
POP
POP
IF EZ THEN
BEGIN
    PUSHZ
END
Выходные данные
Runtime error
Входные данные
2 1000
1 100
WHILE GZ DO
BEGIN
    SWAP2
    COPY
    ADD
    SWAP2
    DEC
END

POP
Выходные данные
Accepted
1
1267650600228229401496703205376 
Входные данные
6 100
5 1 2 3 4 5
while HAVE5 DO
BEGIN
    DEC
    SUM
END
Выходные данные
Compilation error
Примечание

Программа из первого примера является решением задачи прошлого года.

Программа из второго примера является такой же, как и в первом примере, однако теперь ограничение на количество тактов равно $$$15$$$. Так как проверка в цикле также выполняется за один такт, данной программе для завершения потребуется $$$16$$$ тактов, что не укладывается в ограничение.

В третьем примере происходит проверка EZ в пустом стеке, что приводит к ошибке.

В четвертом примере приведена программа, вычисляющая значение $$$2^{100}$$$.

Программа из пятого примера является синтаксически некорректной по нескольким причинам. Во-первых, ключевое слово «WHILE» написано не в правильном регистре. Во-вторых, операции «HAVE5» и «SUM» не являются описанными выше операциями языка.