#include <algorithm>
#include <cstdio>
#include <vector>
constexpr int N = 200005;
int n;
std::vector<int> G[N];
int tp[N], dep[N];
struct node
{
int tp, dep, id;
};
void dfs1(int u, int fa)
{
for (int v : G[u])
{
if (v == fa) continue;
dep[v] = dep[u] + 1;
dfs1(v, u);
}
}
using pii = std::pair<int, int>;
std::vector<pii> ans;
node dfs2(int u, int fa)
{
node res{0, 0, 0};
std::vector<pii> sub[4];
sub[tp[u]].emplace_back(dep[u], u);
for (int v : G[u])
{
if (v == fa) continue;
node t = dfs2(v, u);
if (t.tp == -1) return node{-1, -1, -1};
if (t.tp > 0) sub[t.tp].emplace_back(t.dep, t.id);
}
for (int i = 1; i <= 3; ++i) std::sort(sub[i].begin(), sub[i].end(), std::greater<pii>());
if (!sub[3].empty())
{
int cnt = 1;
for (int i = 1; i < sub[3].size(); ++i)
{
if (sub[3][i].first != sub[3][i - 1].first)
{
if (cnt & 1)
{
if (res.tp) return node{-1, -1, -1};
res = node{3, sub[3][i - 1].first, sub[3][i - 1].second};
}
for (int j = i - cnt; j < i - 1; j = 2)
ans.emplace_back(sub[3][j].second, sub[3][j + 1].second);
cnt = 1;
}
else
cnt++;
}
for (int j = sub[3].size() - cnt; j < sub[3].size() - 1; j += 2)
ans.emplace_back(sub[3][j].second, sub[3][j + 1].second);
if (cnt & 1)
{
if (res.tp != 0) return (node){-1, -1, -1};
res = (node){3, sub[3][sub[3].size() - 1].first, sub[3][sub[3].size() - 1].second};
}
}
if (sub[1].size() == sub[2].size())
{
for (int i = 0; i < sub[1].size(); i++)
{
if (sub[1][i].first <= sub[2][i].first) return (node){-1, -1, -1};
ans.emplace_back(sub[1][i].second, sub[2][i].second);
}
}
else if (sub[1].size() > sub[2].size())
{
int poi = sub[1].size() - 1;
for (int i = sub[2].size() - 1; i >= 0; i--)
{
while (poi >= 0 && sub[1][poi].first <= sub[2][i].first)
{
if (res.tp != 0) return node{-1, -1, -1};
res = node{1, sub[1][poi].first, sub[1][poi].second}, poi--;
}
if (poi >= 0 && sub[1][poi].first > sub[2][i].first)
{
ans.emplace_back(sub[1][poi].second, sub[2][i].second);
poi--;
}
else
return node{-1, -1, -1};
}
while (poi >= 0)
{
if (res.tp != 0) return node{-1, -1, -1};
res = node{1, sub[1][poi].first, sub[1][poi].second}, poi--;
}
}
else
{
int poi = 0;
for (int i = 0; i < sub[1].size(); i++)
{
while (poi < sub[2].size() && sub[1][i].first <= sub[2][poi].first)
{
if (res.tp != 0) return node{-1, -1, -1};
res = node{2, sub[2][poi].first, sub[2][poi].second}, poi++;
}
if (poi < sub[2].size() && sub[1][i].first > sub[2][poi].first)
{
ans.emplace_back(sub[1][i].second, sub[2][poi].second);
poi++;
}
else
return (node){-1, -1, -1};
}
while (poi < sub[2].size())
{
if (res.tp != 0) return (node){-1, -1, -1};
res = (node){2, sub[2][poi].first, sub[2][poi].second}, poi++;
}
}
if (u == 1 && res.tp) return (node){-1, -1, -1};
return res;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i < n; i++)
{
int u, v;
char str[20];
scanf("%d%d%s", &u, &v, str);
G[u].push_back(v);
G[v].push_back(u);
if (str[0] == 'C')
tp[u] = 1;
else if (str[0] == 'D')
tp[u] = 2;
else if (str[0] == 'T')
tp[u] = 3;
}
dfs1(1, 0);
node res = dfs2(1, 0);
if (res.tp == -1)
puts("NO");
else
{
puts("YES");
for (int i = 0; i < ans.size(); i++) printf("%d %d\n", ans[i].first, ans[i].second);
}
}