#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define	N 1000 			/* amounts of tree node */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  allInSameSet
 *  Description:  check all over the node in the same set 
 * =====================================================================================
 */
	bool
allInSameSet ( int set[N], int index )
{
	int i, setNum = 0;	
	for ( i = 1 ; i <= index ; i++ )        /* find the unique set */
		if ( 0 != set[i] ) {
			setNum = set[i];
			break;	
		}
	for ( int j = i; j <= index; j++ ) {
		if ( setNum != set[j] && 0 != set[j]) {
			return false;           /* there is one set not connected to tree */
		}
	}
	return true; 
}		/* -----  end of function allInSameSet  ----- */
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  combineSet
 *  Description:  combine two sets to a parent's set 
 * =====================================================================================
 */
	void
combineSet ( int set[N], int index, int par, int son)
{
	
	for ( int i = 1; i <= index; i++)
		if ( son == set[i]  && 0 != set[i] )
			set[i] = par;
}		/* -----  end of function combineSet  ----- */
/* * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:  set[node] == 0  means null. the number of set[node] means which set does
 *  		  the node in .
 *  		  divide nodes to sets, if node A point to node B then node A and B are
 *  		  in the same set, Once there is intersection between sets, combine them.
 * ===================================================================================== */ 
	int
main ( int argc, char *argv[] )
{
	int set[N];
	int a, b, sets = 1, max = -1, caseCount = 0;
	bool cycle = false;	
	while ( true ) {
		caseCount++;                    /* the number of cases */
		cycle = false;                  /* the flag of finding cycle in tree */
		memset(set, 0, sizeof(int)*N);  /* initial set */
		sets = 1;                       /* the first set */
		max = -1;                       /* upper bound of array */
		a = 0;
		b = 0;
		while ( 2 == scanf ( "%d %d", &a, &b )) {
			
			if ( 0 >= a && 0 >= b ) /* input is (0, 0) or (-1, -1) */
				break;
			
			if ( 0 >= a || 0 >= b )
			{
				cycle = true;   /* to use this flag to commit this graph is not tree */
			}
			
			max = (a>b)?a:b;        /* find upper bound of array */

			if ( (a == b) || (  (set[a] == set[b]) && ( 0 != set[a] && 0 != set[b]) ) ) {  
				cycle = true;   /* same input data or there is a edge between two nodes which location in same set */
			}
			else {
				
				if ( 0 == set[a] && 0 == set[b] ) { /* new set */
					set[a] = sets;
					set[b] = sets++; 
				}
				else {
					
					if ( 0 != set[a]   ) { /* because node a point to b, the element of set[b] are contained to set[a]*/
						combineSet(set, max, set[a], set[b]);
					}
					else {
						set[a] = set[b];
					}
				}
			}
		}                               /* end while */
		
		if ( 0 > a && 0 > b ) {         /* input is end */
			break;
		}
		 /* :BUG:2012年06月11日 14時28分19秒:: if I input (0, 0) there maybe reason of Runtime error */
		if ( !cycle && allInSameSet(set, max) )
			printf ( "Case %d is a tree.\n", caseCount );
		else {
			printf ( "Case %d is not a tree.\n", caseCount );	
		}
	}                                       /* end while */
	return EXIT_SUCCESS;
}				/* ----------  end of function main  ---------- */