#include <bits/stdc++.h>
using namespace std;
static string toLower(const string &s) { string res = s; for (char &c : res) c = tolower(c); return res; }
int main() { ios::sync_with_stdio(false); cin.tie(NULL);
int N;
if (!(cin >> N)) return 0;
struct Person { string name, parent; bool alive; };
vector<Person> members;
members.reserve(N);
unordered_map<string, string> nameMap; // lower-case -> original
for (int i = 0; i < N; i++) {
string name, parent, isAlive;
cin >> name >> parent >> isAlive;
bool alive = (isAlive == "true" || isAlive == "True");
members.push_back({name, parent, alive});
nameMap[toLower(name)] = name;
}
// Build children map and identify root
unordered_map<string, vector<string>> children;
string root;
for (auto &p : members) {
if (toLower(p.parent) == "null") {
root = p.name;
} else {
string key = toLower(p.parent);
auto it = nameMap.find(key);
if (it != nameMap.end()) {
children[it->second].push_back(p.name);
}
else {
// Parent not found; ignore or could handle error
}
}
}
vector<string> succession;
succession.reserve(3);
// Iterative preorder DFS
stack<string> st;
if (!root.empty()) st.push(root);
while (!st.empty() && succession.size() < 3) {
string u = st.top(); st.pop();
// Find alive status from members list or map
// We can build aliveMap
// Build alive map first
static unordered_map<string, bool> aliveMap;
if (aliveMap.empty()) {
for (auto &p : members) aliveMap[p.name] = p.alive;
}
if (aliveMap[u]) {
succession.push_back(u);
if (succession.size() == 3) break;
}
auto it = children.find(u);
if (it != children.end()) {
// push in reverse birth order: children were inserted in input order
for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) {
st.push(*rit);
}
}
}
for (auto &name : succession) cout << name << ' ';
return 0;
}