#include <bits/stdc++.h>
using namespace std;
set < string > cppKeywords = {
"alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept",
"auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
"compl", "concept", "const", "consteval", "constexpr", "const_cast", "continue", "co_await", "co_return",
"co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit",
"export", "extern", "false", "float", "for", "friend", "goto", "if", "import", "inline", "int", "long",
"mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
"private", "protected", "public", "register", "reinterpret_cast", "requires", "return", "short", "signed",
"sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", "thread_local",
"throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
"volatile", "wchar_t", "while", "xor", "xor_eq", "cout", "cin", "endl"
};
set< string > cppOperators = {
"+", "-", "*", "/", "%", "++", "--", "=", "+=", "-=", "*=", "/=", "%=",
"==", "!=", "<", ">", "<=", ">=", "&&", "||", "!", "&", "|", "^", "~",
"<<", ">>", ">>=", "<<=", "->", "&=", "|=", "^="
};
vector < string > tokens;
bool isSymbol(char ch) {return !isalpha(ch) and !isdigit(ch) and (ch != ' ') and (static_cast<int>(ch) != 9);}
bool isSymbol(string ch) {return (ch.size() > 1) ? false: isSymbol(ch[0]);}
bool isNumber(char ch) {return ch >= '0' and ch <= '9';}
bool isNumber(string s) {
for (int i = 0; i < s.size(); i++) {
if (s[i] < '0' or s[i] > '9')
return false;
}
return true;
}
bool isFloat(string s) {
bool point = false;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '.') point = true;
else if (s[i] < '0' and s[i] > '9') return false;
}
return point and (s != ".");
}
bool handle_operator(string s, int &i, string &tmp) {
if ((i < s.size() - 1)) {
string newS;
newS += s[i];
newS += s[i + 1];
if (cppOperators.find(newS) != cppOperators.end()) {
if (i < s.size() - 2) {
newS += s[i + 2];
if (cppOperators.find(newS) != cppOperators.end()) {
tokens.push_back(newS);
tmp = "";
i += 2;
return true;
}
newS.pop_back();
}
tokens.push_back(newS);
tmp = "";
i++;
return true;
}
}
return false;
}
void getToken(string s) {
string tmp;
int cnt = 0;
for (int i = 0; i < s.size(); i++) {
if (isNumber(s[i]) or s[i] == '.') {
string num;
while (i < s.size() and (isNumber(s[i]) or (s[i] == '.'))) {
num += s[i];
i++;
}
if (num != ".") {
tokens.push_back(num);
}
else i--;
}
if (isSymbol(s[i])) {
if (
i - 1 != -1 and
i + 1 != s.size() and
s[i - 1] != ' ' and
s[i + 1] != ' '
) {
if (tmp.size()) tokens.push_back(tmp);
string str;
str += s[i];
if (handle_operator(s, i, tmp)) continue;
tokens.push_back(str);
tmp = "";
continue;
}
else {
string str;
str += s[i];
if (tmp.size()) tokens.push_back(tmp);
if (handle_operator(s, i, tmp)) continue;
tokens.push_back(str);
tmp = "";
continue;
}
}
else if (s[i] == ' ' and !isSymbol(s[i - 1])) {
if (tmp.size()) tokens.push_back(tmp);
tmp = "";
}
if ((s[i] != ' ') and (static_cast<int>(s[i] != 9))) {
tmp += s[i];
}
}
}
vector < string > getKeywords() {
vector < string > keywords;
for (auto el: tokens) {
if (cppKeywords.find(el) != cppKeywords.end())
keywords.push_back(el);
}
return keywords;
}
vector < string > getIdentifier() {
vector < string > identifier;
for (auto el: tokens) {
if (cppKeywords.find(el) == cppKeywords.end() and !isSymbol(el) and !isNumber(el) and !isFloat(el) and cppOperators.find(el) == cppOperators.end())
identifier.push_back(el);
}
return identifier;
}
vector < string > getOperator() {
vector < string > operators;
for (auto el: tokens) {
if (cppOperators.find(el) != cppOperators.end()) {
operators.push_back(el);
}
}
return operators;
}
vector < string > getSymbols() {
vector < string > symbols;
for (auto el: tokens) {
if (isSymbol(el) and (cppOperators.find(el) == cppOperators.end()))
symbols.push_back(el);
}
return symbols;
}
vector < string > getNumbers() {
vector < string > numbers;
for (auto el: tokens) {
if (isNumber(el))
numbers.push_back(el);
}
return numbers;
}
vector < string > getFloats() {
vector < string > floats;
for (auto el: tokens) {
if (isFloat(el))
floats.push_back(el);
}
return floats;
}
int main() {
string s;
int token = 0;
while (getline(cin, s)) {
getToken(s);
}
vector < string > keywords = getKeywords();
vector < string > identifiers = getIdentifier();
vector < string > operators = getOperator();
vector < string > symbols = getSymbols();
vector < string > numbers = getNumbers();
vector < string > floats = getFloats();
cout << "Total Numbers of Tokens\t\t:" << tokens.size() << endl;
cout << "Keywords\t\t\t\t\t:" << keywords.size() << " ";
for (auto el: keywords) cout << el << " ";
cout << endl;
cout << "Identifiers\t\t\t\t\t:" << identifiers.size() << " ";
for (auto el: identifiers) cout << el << " ";
cout << endl;
cout << "Operators\t\t\t\t\t:" << operators.size() << " ";
for (auto el: operators) cout << el << " ";
cout << endl;
cout << "Symbols\t\t\t\t\t\t:" << symbols.size() << " ";
for (auto el: symbols) cout << el << " ";
cout << endl;
cout << "Integer Constants\t\t\t:" << numbers.size() << " ";
for (auto el: numbers) cout << el << " ";
cout << endl;
cout << "Floating Point Constants\t:" << floats.size() << " ";
for (auto el: floats) cout << el << " ";
cout << endl;
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzZXQgPCBzdHJpbmcgPiBjcHBLZXl3b3JkcyA9IHsKICAgICAgICAiYWxpZ25hcyIsICJhbGlnbm9mIiwgImFuZCIsICJhbmRfZXEiLCAiYXNtIiwgImF0b21pY19jYW5jZWwiLCAiYXRvbWljX2NvbW1pdCIsICJhdG9taWNfbm9leGNlcHQiLAogICAgICAgICJhdXRvIiwgImJpdGFuZCIsICJiaXRvciIsICJib29sIiwgImJyZWFrIiwgImNhc2UiLCAiY2F0Y2giLCAiY2hhciIsICJjaGFyMTZfdCIsICJjaGFyMzJfdCIsICJjbGFzcyIsCiAgICAgICAgImNvbXBsIiwgImNvbmNlcHQiLCAiY29uc3QiLCAiY29uc3RldmFsIiwgImNvbnN0ZXhwciIsICJjb25zdF9jYXN0IiwgImNvbnRpbnVlIiwgImNvX2F3YWl0IiwgImNvX3JldHVybiIsCiAgICAgICAgImNvX3lpZWxkIiwgImRlY2x0eXBlIiwgImRlZmF1bHQiLCAiZGVsZXRlIiwgImRvIiwgImRvdWJsZSIsICJkeW5hbWljX2Nhc3QiLCAiZWxzZSIsICJlbnVtIiwgImV4cGxpY2l0IiwKICAgICAgICAiZXhwb3J0IiwgImV4dGVybiIsICJmYWxzZSIsICJmbG9hdCIsICJmb3IiLCAiZnJpZW5kIiwgImdvdG8iLCAiaWYiLCAiaW1wb3J0IiwgImlubGluZSIsICJpbnQiLCAibG9uZyIsCiAgICAgICAgIm11dGFibGUiLCAibmFtZXNwYWNlIiwgIm5ldyIsICJub2V4Y2VwdCIsICJub3QiLCAibm90X2VxIiwgIm51bGxwdHIiLCAib3BlcmF0b3IiLCAib3IiLCAib3JfZXEiLAogICAgICAgICJwcml2YXRlIiwgInByb3RlY3RlZCIsICJwdWJsaWMiLCAicmVnaXN0ZXIiLCAicmVpbnRlcnByZXRfY2FzdCIsICJyZXF1aXJlcyIsICJyZXR1cm4iLCAic2hvcnQiLCAic2lnbmVkIiwKICAgICAgICAic2l6ZW9mIiwgInN0YXRpYyIsICJzdGF0aWNfYXNzZXJ0IiwgInN0YXRpY19jYXN0IiwgInN0cnVjdCIsICJzd2l0Y2giLCAidGVtcGxhdGUiLCAidGhpcyIsICJ0aHJlYWRfbG9jYWwiLAogICAgICAgICJ0aHJvdyIsICJ0cnVlIiwgInRyeSIsICJ0eXBlZGVmIiwgInR5cGVpZCIsICJ0eXBlbmFtZSIsICJ1bmlvbiIsICJ1bnNpZ25lZCIsICJ1c2luZyIsICJ2aXJ0dWFsIiwgInZvaWQiLAogICAgICAgICJ2b2xhdGlsZSIsICJ3Y2hhcl90IiwgIndoaWxlIiwgInhvciIsICJ4b3JfZXEiLCAiY291dCIsICJjaW4iLCAiZW5kbCIKfTsKCnNldDwgc3RyaW5nID4gY3BwT3BlcmF0b3JzID0gewogICAgICAgICIrIiwgIi0iLCAiKiIsICIvIiwgIiUiLCAiKysiLCAiLS0iLCAiPSIsICIrPSIsICItPSIsICIqPSIsICIvPSIsICIlPSIsCiAgICAgICAgIj09IiwgIiE9IiwgIjwiLCAiPiIsICI8PSIsICI+PSIsICImJiIsICJ8fCIsICIhIiwgIiYiLCAifCIsICJeIiwgIn4iLAogICAgICAgICI8PCIsICI+PiIsICI+Pj0iLCAiPDw9IiwgIi0+IiwgIiY9IiwgInw9IiwgIl49Igp9OwoKdmVjdG9yIDwgc3RyaW5nID4gdG9rZW5zOwoKYm9vbCBpc1N5bWJvbChjaGFyIGNoKSB7cmV0dXJuICFpc2FscGhhKGNoKSBhbmQgIWlzZGlnaXQoY2gpIGFuZCAoY2ggIT0gJyAnKSBhbmQgKHN0YXRpY19jYXN0PGludD4oY2gpICE9IDkpO30KYm9vbCBpc1N5bWJvbChzdHJpbmcgY2gpIHtyZXR1cm4gKGNoLnNpemUoKSA+IDEpID8gZmFsc2U6IGlzU3ltYm9sKGNoWzBdKTt9CmJvb2wgaXNOdW1iZXIoY2hhciBjaCkge3JldHVybiBjaCA+PSAnMCcgYW5kIGNoIDw9ICc5Jzt9CmJvb2wgaXNOdW1iZXIoc3RyaW5nIHMpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5zaXplKCk7IGkrKykgewogICAgICAgIGlmIChzW2ldIDwgJzAnIG9yIHNbaV0gPiAnOScpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwp9Cgpib29sIGlzRmxvYXQoc3RyaW5nIHMpIHsKICAgIGJvb2wgcG9pbnQgPSBmYWxzZTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5zaXplKCk7IGkrKykgewogICAgICAgIGlmIChzW2ldID09ICcuJykgcG9pbnQgPSB0cnVlOwogICAgICAgIGVsc2UgaWYgKHNbaV0gPCAnMCcgYW5kIHNbaV0gPiAnOScpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiBwb2ludCBhbmQgKHMgIT0gIi4iKTsKfQoKYm9vbCBoYW5kbGVfb3BlcmF0b3Ioc3RyaW5nIHMsIGludCAmaSwgc3RyaW5nICZ0bXApIHsKICAgIGlmICgoaSA8IHMuc2l6ZSgpIC0gMSkpIHsKICAgICAgICBzdHJpbmcgbmV3UzsKICAgICAgICBuZXdTICs9IHNbaV07CiAgICAgICAgbmV3UyArPSBzW2kgKyAxXTsKICAgICAgICBpZiAoY3BwT3BlcmF0b3JzLmZpbmQobmV3UykgIT0gY3BwT3BlcmF0b3JzLmVuZCgpKSB7CgogICAgICAgICAgICBpZiAoaSA8IHMuc2l6ZSgpIC0gMikgewogICAgICAgICAgICAgICAgbmV3UyArPSBzW2kgKyAyXTsKICAgICAgICAgICAgICAgIGlmIChjcHBPcGVyYXRvcnMuZmluZChuZXdTKSAhPSBjcHBPcGVyYXRvcnMuZW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICB0b2tlbnMucHVzaF9iYWNrKG5ld1MpOwogICAgICAgICAgICAgICAgICAgIHRtcCA9ICIiOwogICAgICAgICAgICAgICAgICAgIGkgKz0gMjsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ld1MucG9wX2JhY2soKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdG9rZW5zLnB1c2hfYmFjayhuZXdTKTsKICAgICAgICAgICAgdG1wID0gIiI7CiAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9Cgp2b2lkIGdldFRva2VuKHN0cmluZyBzKSB7CiAgICBzdHJpbmcgdG1wOwogICAgaW50IGNudCA9IDA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHMuc2l6ZSgpOyBpKyspIHsKICAgICAgICBpZiAoaXNOdW1iZXIoc1tpXSkgb3Igc1tpXSA9PSAnLicpIHsKICAgICAgICAgICAgc3RyaW5nIG51bTsKICAgICAgICAgICAgd2hpbGUgKGkgPCBzLnNpemUoKSBhbmQgKGlzTnVtYmVyKHNbaV0pIG9yIChzW2ldID09ICcuJykpKSB7CiAgICAgICAgICAgICAgICBudW0gKz0gc1tpXTsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobnVtICE9ICIuIikgewogICAgICAgICAgICAgICAgdG9rZW5zLnB1c2hfYmFjayhudW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaS0tOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzU3ltYm9sKHNbaV0pKSB7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgIGkgLSAxICE9IC0xIGFuZAogICAgICAgICAgICAgICAgaSArIDEgIT0gcy5zaXplKCkgYW5kCiAgICAgICAgICAgICAgICBzW2kgLSAxXSAhPSAnICcgYW5kCiAgICAgICAgICAgICAgICBzW2kgKyAxXSAhPSAnICcKICAgICAgICAgICAgKSB7CiAgICAgICAgICAgICAgICBpZiAodG1wLnNpemUoKSkgdG9rZW5zLnB1c2hfYmFjayh0bXApOwogICAgICAgICAgICAgICAgc3RyaW5nIHN0cjsKICAgICAgICAgICAgICAgIHN0ciArPSBzW2ldOwoKICAgICAgICAgICAgICAgIGlmIChoYW5kbGVfb3BlcmF0b3IocywgaSwgdG1wKSkgY29udGludWU7CgogICAgICAgICAgICAgICAgdG9rZW5zLnB1c2hfYmFjayhzdHIpOwoKICAgICAgICAgICAgICAgIHRtcCA9ICIiOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc3RyaW5nIHN0cjsKICAgICAgICAgICAgICAgIHN0ciArPSBzW2ldOwoKICAgICAgICAgICAgICAgIGlmICh0bXAuc2l6ZSgpKSB0b2tlbnMucHVzaF9iYWNrKHRtcCk7CgogICAgICAgICAgICAgICAgaWYgKGhhbmRsZV9vcGVyYXRvcihzLCBpLCB0bXApKSBjb250aW51ZTsKCiAgICAgICAgICAgICAgICB0b2tlbnMucHVzaF9iYWNrKHN0cik7CgogICAgICAgICAgICAgICAgdG1wID0gIiI7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0gCiAgICAgICAgZWxzZSBpZiAoc1tpXSA9PSAnICcgYW5kICFpc1N5bWJvbChzW2kgLSAxXSkpIHsKCiAgICAgICAgICAgIGlmICh0bXAuc2l6ZSgpKSB0b2tlbnMucHVzaF9iYWNrKHRtcCk7CiAgICAgICAgICAgIHRtcCA9ICIiOwogICAgICAgIH0KCiAgICAgICAgaWYgKChzW2ldICE9ICcgJykgYW5kIChzdGF0aWNfY2FzdDxpbnQ+KHNbaV0gIT0gOSkpKSB7CgogICAgICAgICAgICB0bXAgKz0gc1tpXTsKICAgICAgICB9CgogICAgfQp9Cgp2ZWN0b3IgPCBzdHJpbmcgPiBnZXRLZXl3b3JkcygpIHsKCiAgICB2ZWN0b3IgPCBzdHJpbmcgPiBrZXl3b3JkczsKICAgIGZvciAoYXV0byBlbDogdG9rZW5zKSB7CgogICAgICAgIGlmIChjcHBLZXl3b3Jkcy5maW5kKGVsKSAhPSBjcHBLZXl3b3Jkcy5lbmQoKSkgCiAgICAgICAgICAgIGtleXdvcmRzLnB1c2hfYmFjayhlbCk7CgogICAgfQoKICAgIHJldHVybiBrZXl3b3JkczsKCn0KCnZlY3RvciA8IHN0cmluZyA+IGdldElkZW50aWZpZXIoKSB7CgogICAgdmVjdG9yIDwgc3RyaW5nID4gaWRlbnRpZmllcjsKCiAgICBmb3IgKGF1dG8gZWw6IHRva2VucykgewogICAgICAgIGlmIChjcHBLZXl3b3Jkcy5maW5kKGVsKSA9PSBjcHBLZXl3b3Jkcy5lbmQoKSBhbmQgIWlzU3ltYm9sKGVsKSBhbmQgIWlzTnVtYmVyKGVsKSBhbmQgIWlzRmxvYXQoZWwpIGFuZCBjcHBPcGVyYXRvcnMuZmluZChlbCkgPT0gY3BwT3BlcmF0b3JzLmVuZCgpKQogICAgICAgICAgICBpZGVudGlmaWVyLnB1c2hfYmFjayhlbCk7CiAgICB9CgogICAgcmV0dXJuIGlkZW50aWZpZXI7Cn0KCnZlY3RvciA8IHN0cmluZyA+IGdldE9wZXJhdG9yKCkgewogICAgdmVjdG9yIDwgc3RyaW5nID4gb3BlcmF0b3JzOwoKICAgIGZvciAoYXV0byBlbDogdG9rZW5zKSB7CiAgICAgICAgaWYgKGNwcE9wZXJhdG9ycy5maW5kKGVsKSAhPSBjcHBPcGVyYXRvcnMuZW5kKCkpIHsKICAgICAgICAgICAgb3BlcmF0b3JzLnB1c2hfYmFjayhlbCk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBvcGVyYXRvcnM7Cn0KCnZlY3RvciA8IHN0cmluZyA+IGdldFN5bWJvbHMoKSB7CiAgICB2ZWN0b3IgPCBzdHJpbmcgPiBzeW1ib2xzOwogICAgZm9yIChhdXRvIGVsOiB0b2tlbnMpIHsKICAgICAgICBpZiAoaXNTeW1ib2woZWwpIGFuZCAoY3BwT3BlcmF0b3JzLmZpbmQoZWwpID09IGNwcE9wZXJhdG9ycy5lbmQoKSkpCiAgICAgICAgICAgIHN5bWJvbHMucHVzaF9iYWNrKGVsKTsKICAgIH0KCiAgICByZXR1cm4gc3ltYm9sczsKfQoKdmVjdG9yIDwgc3RyaW5nID4gZ2V0TnVtYmVycygpIHsKICAgIHZlY3RvciA8IHN0cmluZyA+IG51bWJlcnM7CiAgICBmb3IgKGF1dG8gZWw6IHRva2VucykgewogICAgICAgIGlmIChpc051bWJlcihlbCkpCiAgICAgICAgICAgIG51bWJlcnMucHVzaF9iYWNrKGVsKTsKICAgIH0KICAgIHJldHVybiBudW1iZXJzOwp9Cgp2ZWN0b3IgPCBzdHJpbmcgPiBnZXRGbG9hdHMoKSB7CiAgICB2ZWN0b3IgPCBzdHJpbmcgPiBmbG9hdHM7CiAgICBmb3IgKGF1dG8gZWw6IHRva2VucykgewogICAgICAgIGlmIChpc0Zsb2F0KGVsKSkKICAgICAgICAgICAgZmxvYXRzLnB1c2hfYmFjayhlbCk7CiAgICB9CiAgICByZXR1cm4gZmxvYXRzOwp9CgppbnQgbWFpbigpIHsKCiAgICBzdHJpbmcgczsgCiAgICBpbnQgdG9rZW4gPSAwOwoKICAgIHdoaWxlIChnZXRsaW5lKGNpbiwgcykpIHsKCiAgICAgICAgZ2V0VG9rZW4ocyk7CgogICAgfQoKICAgIHZlY3RvciA8IHN0cmluZyA+IGtleXdvcmRzID0gZ2V0S2V5d29yZHMoKTsKICAgIHZlY3RvciA8IHN0cmluZyA+IGlkZW50aWZpZXJzID0gZ2V0SWRlbnRpZmllcigpOwogICAgdmVjdG9yIDwgc3RyaW5nID4gb3BlcmF0b3JzID0gZ2V0T3BlcmF0b3IoKTsKICAgIHZlY3RvciA8IHN0cmluZyA+IHN5bWJvbHMgPSBnZXRTeW1ib2xzKCk7CiAgICB2ZWN0b3IgPCBzdHJpbmcgPiBudW1iZXJzID0gZ2V0TnVtYmVycygpOwogICAgdmVjdG9yIDwgc3RyaW5nID4gZmxvYXRzID0gZ2V0RmxvYXRzKCk7CgogICAgY291dCA8PCAiVG90YWwgTnVtYmVycyBvZiBUb2tlbnNcdFx0OiIgPDwgdG9rZW5zLnNpemUoKSA8PCBlbmRsOwogICAgY291dCA8PCAiS2V5d29yZHNcdFx0XHRcdFx0OiIgPDwga2V5d29yZHMuc2l6ZSgpIDw8ICIgIjsKICAgIGZvciAoYXV0byBlbDoga2V5d29yZHMpIGNvdXQgPDwgZWwgPDwgIiAiOwogICAgY291dCA8PCBlbmRsOwogICAgY291dCA8PCAiSWRlbnRpZmllcnNcdFx0XHRcdFx0OiIgPDwgaWRlbnRpZmllcnMuc2l6ZSgpIDw8ICIgIjsKICAgIGZvciAoYXV0byBlbDogaWRlbnRpZmllcnMpIGNvdXQgPDwgZWwgPDwgIiAiOwogICAgY291dCA8PCBlbmRsOwogICAgY291dCA8PCAiT3BlcmF0b3JzXHRcdFx0XHRcdDoiIDw8IG9wZXJhdG9ycy5zaXplKCkgPDwgIiAiOwogICAgZm9yIChhdXRvIGVsOiBvcGVyYXRvcnMpIGNvdXQgPDwgZWwgPDwgIiAiOwogICAgY291dCA8PCBlbmRsOwogICAgY291dCA8PCAiU3ltYm9sc1x0XHRcdFx0XHRcdDoiIDw8IHN5bWJvbHMuc2l6ZSgpIDw8ICIgIjsKICAgIGZvciAoYXV0byBlbDogc3ltYm9scykgY291dCA8PCBlbCA8PCAiICI7CiAgICBjb3V0IDw8IGVuZGw7CiAgICBjb3V0IDw8ICJJbnRlZ2VyIENvbnN0YW50c1x0XHRcdDoiIDw8IG51bWJlcnMuc2l6ZSgpIDw8ICIgIjsKICAgIGZvciAoYXV0byBlbDogbnVtYmVycykgY291dCA8PCBlbCA8PCAiICI7CiAgICBjb3V0IDw8IGVuZGw7CiAgICBjb3V0IDw8ICJGbG9hdGluZyBQb2ludCBDb25zdGFudHNcdDoiIDw8IGZsb2F0cy5zaXplKCkgPDwgIiAiOwogICAgZm9yIChhdXRvIGVsOiBmbG9hdHMpIGNvdXQgPDwgZWwgPDwgIiAiOwogICAgY291dCA8PCBlbmRsOwoKICAgIHJldHVybiAwOwp9