E. Безопасная работа с памятью
ограничение по времени на тест
2 секунды
ограничение по памяти на тест
256 мегабайт
ввод
стандартный ввод
вывод
стандартный вывод

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

Во время путешествия к звездной системе, где будет проходить выставка одежды, на корабле Лоренцо произошел сбой. Из-за неверных настроек параметров варп прыжка, корабль попал в квантовую турбулентность и оказался в пиратской системе PRS-1. К сожалению, корабль был захвачен пиратами, а во время переговоров Лоренцо несколько раз слышал фразу: «Please, use Rust. Use it blazingly fast».

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

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

let X = new();

Здесь и далее «X» означает имя переменной, состоящее только из строчных букв латинского алфавита.

Для явного освобождения памяти пираты используют следующую конструкцию:

drop(X);

Язык автоматически освобождает память при выходе переменной за пределы области видимости. Для того, чтобы задать начало и конец области видимости, используются символы «{» и «}» соответственно:

{
let X = new();
}

В случае выхода за пределы области видимости, компилятор добавляет конструкции освобождения памяти для еще не освобожденных в этой области переменных в обратном объявлению порядке, например:

{
let a = new();
let b = new();
let c = new();
let d = new();
drop(c);
}

Будет преобразовано компилятором в:

let a = new();
let b = new();
let c = new();
let d = new();
drop(c);
drop(d); // <-
drop(b); // <-
drop(a); // <-

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

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

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

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

В следующих $$$n$$$ строках идет код пиратов. Каждая строка имеет один из двух форматов:

  • «let X = new();» — выделение памяти переменной с именем 'X'.
  • «drop(X);» — освобождение памяти переменной с именем 'X'.

Гарантируется, что все создаваемые переменные имеют уникальные названия, состоящие только из строчных букв латинского алфавита, длина которых не превышает $$$16$$$ символов. Также гарантируется, что каждому выделению памяти соответствует единственное освобождение памяти (выделение памяти всегда предшествует ее освобождению).

$$$$$$2 \le n \le 1000$$$$$$

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

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

Каждая строка должна иметь один из четырех форматов:

  • «let X = new();» — выделение памяти переменной с именем 'X'.
  • «drop(X);» — освобождение памяти переменной с именем 'X'.
  • «{» — начало области видимости.
  • «}» — конец области видимости.

Вы также можете добавить любое количество пробелов в начале каждой строки (но не более $$$4\,000$$$).

Примеры
Входные данные
6
let aba = new();
let caba = new();
let daba = new();
drop(aba);
drop(daba);
drop(caba);
Выходные данные
let aba = new();
let caba = new();
let daba = new();
drop(aba);
Входные данные
8
let a = new();
let b = new();
drop(b);
let c = new();
drop(c);
drop(a);
let e = new();
drop(e);
Выходные данные
{
  let a = new();
  {
    let b = new();
  }
  let c = new();
}
let e = new();