#ifdef _MSC_VER
#pragma warning(disable:4503)      // `silence compiler complaints about generated names being too long'
#endif

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>

#include "split.h"
#include <time.h>

using std::istream;           using std::cin;
using std::copy;              using std::cout;
using std::endl;              using std::find;
using std::getline;           using std::logic_error;
using std::map;               using std::string;
using std::vector;            using std::domain_error;
using std::rand;

typedef vector<string> Rule;
typedef vector<Rule> Rule_collection;
typedef map<string, Rule_collection> Grammar;

// read a grammar from a given input stream
Grammar read_grammar(istream& in)
{
	Grammar ret;
	string line;

	// read the input
	while (getline(in, line)) {

		// `split' the input into words
		vector<string> entry = split(line);

		if (!entry.empty())
			// use the category to store the associated rule
			ret[entry[0]].push_back(
				Rule(entry.begin() + 1, entry.end()));
	}
	return ret;
}

void gen_aux(const Grammar&, const string&, vector<string>&);

int nrand(int);

vector<string> gen_sentence(const Grammar& g)
{
	vector<string> ret;
	gen_aux(g, "<sentence>", ret);
	return ret;
}

bool bracketed(const string& s)
{
	return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}

void
gen_aux(const Grammar& g, const string& word, vector<string>& ret)
{

	if (!bracketed(word)) {
		ret.push_back(word);
	} else {
		// locate the rule that corresponds to `word'
		Grammar::const_iterator it = g.find(word);
		if (it == g.end())
			throw logic_error("empty rule");

		// fetch the set of possible rules
		const Rule_collection& c = it->second;

		// from which we select one at random
		const Rule& r = c[nrand(c.size())];

		// recursively expand the selected rule
		for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
			gen_aux(g, *i, ret);
	}
}

int main()
{
	// generate the sentence
	vector<string> sentence = gen_sentence(read_grammar(cin));

	// write the first word, if any
#ifdef _MSC_VER
	std::vector<string>::const_iterator it = sentence.begin();
#else
	vector<string>::const_iterator it = sentence.begin();
#endif
	if (!sentence.empty()) {
		cout << *it;
		++it;
	}

	// write the rest of the words, each preceded by a space
	while (it != sentence.end()) {
		cout << " " << *it;
		++it;
	}

	cout << endl;
	return 0;
}

// return a random integer in the range `[0,' `n)'
int nrand(int n)
{
	if (n <= 0 || n > RAND_MAX)
		throw domain_error("Argument to nrand is out of range");

	const int bucket_size = RAND_MAX / n;
	int r;

	do r = rand() / bucket_size;
	while (r >= n);

	return r;
}



#ifdef _MSC_VER
#pragma warning(disable:4503)      // 关闭编译器警告，避免对生成的名称过长的抱怨
#endif

#include <algorithm>      // 引入算法库，提供常用的算法
#include <cstdlib>        // 引入C标准库，包含rand()函数
#include <iostream>       // 引入标准输入输出流库
#include <map>            // 引入映射容器（map）库
#include <stdexcept>      // 引入标准异常库，提供逻辑错误和域错误等异常
#include <string>         // 引入字符串库
#include <vector>         // 引入动态数组（vector）库
#include "split.h"        // 引入自定义的split.h头文件（假定提供了字符串拆分功能）
#include <time.h>         // 引入时间库，支持随机数生成

using std::istream;           using std::cin;
using std::copy;              using std::cout;
using std::endl;              using std::find;
using std::getline;           using std::logic_error;
using std::map;               using std::string;
using std::vector;            using std::domain_error;
using std::rand;              // 引入rand函数

// 定义规则（字符串集合）和语法（规则集合）的类型
typedef vector<string> Rule;  // 一个规则是字符串的集合
typedef vector<Rule> Rule_collection;  // 规则集合是规则的集合
typedef map<string, Rule_collection> Grammar;  // 语法是一个映射：类别 -> 规则集合

// 从输入流中读取语法并返回
Grammar read_grammar(istream& in) {
	Grammar ret;  // 用于存储语法
	string line;

	// 持续读取每一行
	while (getline(in, line)) {
		// 将当前行拆分成单词
		vector<string> entry = split(line);

		// 如果拆分出的单词不为空，则根据类别存储规则
		if (!entry.empty())
			ret[entry[0]].push_back(
				Rule(entry.begin() + 1, entry.end()));  // 使用类别作为key，规则作为value
	}
	return ret;  // 返回语法
}

// 递归生成句子的辅助函数
void gen_aux(const Grammar&, const string&, vector<string>&);

// 返回一个范围在[0, n)内的随机整数
int nrand(int);

// 生成一个句子，调用gen_aux进行递归生成
vector<string> gen_sentence(const Grammar& g) {
	vector<string> ret;
	gen_aux(g, "<sentence>", ret);  // 从<sentence>开始生成句子
	return ret;
}

// 判断一个字符串是否是被尖括号包围的
bool bracketed(const string& s) {
	return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
}

// 递归地生成句子中的一部分
void gen_aux(const Grammar& g, const string& word, vector<string>& ret) {
	if (!bracketed(word)) {
		ret.push_back(word);  // 如果不是被尖括号包围的单词，直接加入句子
	}
	else {
		// 查找对应的规则
		Grammar::const_iterator it = g.find(word);
		if (it == g.end())  // 如果没有找到规则，抛出异常
			throw logic_error("empty rule");

		// 获取该单词的规则集合
		const Rule_collection& c = it->second;

		// 从规则集合中随机选择一个规则
		const Rule& r = c[nrand(c.size())];

		// 对选中的规则中的每个单词进行递归处理
		for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
			gen_aux(g, *i, ret);
	}
}

int main() {
	// 生成句子
	vector<string> sentence = gen_sentence(read_grammar(cin));

	// 输出第一个单词（如果有）
	vector<string>::const_iterator it = sentence.begin();
	if (!sentence.empty()) {
		cout << *it;
		++it;
	}

	// 输出剩余的单词，每个单词前加一个空格
	while (it != sentence.end()) {
		cout << " " << *it;
		++it;
	}

	cout << endl;  // 输出换行
	return 0;
}

// 返回一个随机整数，范围在[0, n)
int nrand(int n) {
	if (n <= 0 || n > RAND_MAX)
		throw domain_error("Argument to nrand is out of range");

	const int bucket_size = RAND_MAX / n;  // 将随机数均匀分布
	int r;

	// 确保随机数在有效范围内
	do r = rand() / bucket_size;
	while (r >= n);

	return r;
}
