/***************************************************************\
*Author:Hu Wenbiao
*Created Time: Tue 17 Aug 2010 09:36:56 AM CST
*File Name: main.cpp
*Description:树状dp.用map处理字符串得到编号,再tree_dp
\***************************************************************/
//*========================*Head File*========================*\\
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<map>
#include<string.h>
/*----------------------*Global Variable*----------------------*/
int first[210], n, tot, cnt, boss, employee;
int dp[210][2];
char a[110], b[110];
bool flag, visited[210], isroot[210];
struct Edge {
int next, to;
} edge[210];
#define insert(a,b) bcm.insert(pair<string,int>(a,b));
//*=======================*Main Program*=======================*//
using namespace std;
void insertedge(int a, int b)
{
edge[tot].to = b;
edge[tot].next = first[a];
first[a] = tot++;
isroot[b] = false;
}
void tree_dp(int from)
{
visited[from] = true;
int p = first[from], to;
dp[from][1] = 1;
while (p != -1) {
to = edge[p].to;
p = edge[p].next;
tree_dp(to);
dp[from][0] += max(dp[to][0], dp[to][1]);
dp[from][1] += dp[to][0];
}
}
bool check(int from, bool cho)
{ //cho表示from是否被选中
visited[from] = true;
int p = first[from], to;
if (cho) { //from被选
while (p != -1) {
to = edge[p].to;
p = edge[p].next;
if (!check(to, 0)) //子结点不能被选,检查各个子结点不被选的情况
return false;
}
} else { //from未被选
while (p != -1) {
to = edge[p].to;
p = edge[p].next;
if (dp[to][0] == dp[to][1]) //子结点可选可不选,一旦两者相等,结果不唯一
return false;
if (dp[to][0] > dp[to][1]) { //这时子结点不被选
if (!check(to, 0))
return false;
} else { //了结点被选
if (!check(to, 1))
return false;
}
}
}
return true;
}
int main()
{
map < string, int >bcm; //存放姓名和编号
map < string, int >::iterator iter;
while (scanf("%d", &n) != EOF && n) {
memset(first, -1, sizeof(first));
memset(dp, 0, sizeof(dp));
memset(isroot, true, sizeof(isroot));
memset(visited, false, sizeof(visited));
bcm.clear();
tot = 0;
cnt = 0;
flag = true;
scanf("%s", a); //bigboss
insert(a, ++cnt); //cnt是编号,从1开始
for (int i = 1; i < n; i++) {
scanf("%s %s", a, b);
iter = bcm.find(a);
if (iter == bcm.end()) { //a之前未出现
insert(a, ++cnt);
employee = cnt;
} else {
employee = iter->second;
}
iter = bcm.find(b);
if (iter == bcm.end()) {
insert(b, ++cnt);
boss = cnt;
} else {
boss = iter->second;
}
insertedge(boss, employee); //将边加入树中
}
tree_dp(1);
int ans = max(dp[1][0], dp[1][1]);
printf("%d ", ans);
memset(visited, 0, sizeof(visited));
if (dp[1][0] == dp[1][1])
flag = false;
else if (dp[1][0] > dp[1][1])
flag = check(1, 0);
else
flag = check(1, 1);
if (flag)
printf("Yes\n");
else
printf("No\n");
}
}