#include <iostream.h>

long A[2001][2];
long N;
long E[2001];
long root;

void Read();
long IsTree();
void Solve();

long main()
{
	Read();
	if(IsTree())
		Solve();
	else
		cout<<"0 0"<<endl;

	return 0;
}

void Read()
{
	cin>>N;

	long i;
	for(i=0;i<N;i++)
		cin>>A[i][0]>>A[i][1];
}

long IsTree()
{
	void FillExist();

	long i;
	long v[2001];
	long rootfound=0;
	for(i=0;i<2000;i++) v[i]=0;

	FillExist();
	//ako ima duga kum pove4e ot 1 vuzel, to ne e durvo
	for(i=0;i<N;i++)
	{
		v[A[i][1]]++;
		if(v[A[i][1]]==2)
			return 0;
	}

	//ako ima pove4e ot 1 koren, to ne e durvo
	//koren -> vuzel,koito se sre6ta v 'E', no ne i v 'v'
	for(i=0;i<2001;i++)
	{
		if((E[i]) && (!v[i]))
		{
			if(rootfound)
				return 0;
			root=i;
			rootfound=1;
		}
	}

	//ako dvete gorni sa izpulneni,nqma nujda da proverqvame za edinstven put(vinagi e samo 1)

	return 1;
}

void FillExist()
{
	long i;
	for(i=0;i<N;i++)
		E[A[i][0]]=E[A[i][1]]=1;
}

void Solve()
{
	long i;
	long leafcount=0;

	for(i=0;i<2001;i++)
		if(E[i]) leafcount++;

	cout<<leafcount<<' '<<root<<endl;
}