#include<iostream>
#include<cstring>
using namespace std;
const int N = 10010;
int p[N];
int id[N];//保存结点入度
int node_num, e_num;//记录结点数量以及边的数量
bool visit[N];//表明结点是否被访问过
bool not_true = false;
int find(int x) {
	//返回祖宗结点顺便加上路径压缩
	if (p[x] != x)p[x] = find(p[x]);
	return p[x];
}
void init() {
	for (int i = 0; i < 10010; i++) {
		p[i] = i;
	}
}
void Union(int x, int y) {
	//合并操作
	if (find(x) != find(y))p[find(x)] = find(y);//修改根结点的指向就是合并操作
}
int main() {
	//本题要积累起的知识点
	// 1.如何判断图是否是一颗树,每个结点的入度最大为1
	// 2.其次不能有环--得用并查集来判断是否有环
	//       判断是否有环的思路:若一个图已经联通的情况下,再不增加结点的情况下增加一条边就会形成环
	// 3.在以上两条条件都满足的情况下,得确保整个图是联通的,也就是要顶点数等于边的数量加1
	int x, y;
	int t = 0;//表明当前是第几个案例
	//并查集别忘了要先初始化
	init();

	//读入多组数据的题就是要注意在下一组数据开始前恢复原来的状态
	while (cin >> x >> y) {
		if (x == 0 && y == 0) {
			//先判断该情况是否是一个树
			t++;
			//注意空树也是个树,这种情况要特判
			if (node_num == 0 && e_num == 0) {
				printf("Case %d is a tree.\n", t);
				continue;
			}
			//刚刚没有.纠错了,这点要注意
			if (node_num == e_num + 1 && not_true == false)printf("Case %d is a tree.\n", t);
			else printf("Case %d is not a tree.\n", t);

			//插入结束清空恢复数据
			memset(visit, 0, sizeof visit);
			memset(id, 0, sizeof id);
			init();
			not_true = false;
			node_num = 0, e_num = 0;
			//此时0,0就不要再执行接下来从操作了
			continue;
		}
		if (x == -1 & y == -1)break;
		//这个要在插入边前判断
		if (find(x) == find(y)) {
			//如果这两个结点所在部分有相同的根结点,说明已经联通了
			//这时候再加入一条边肯定就会成环,不会形成树
			not_true = true;
		}
		Union(x, y);
		//别忘了还要计算入度
		if (id[y] == 0)id[y]++;
		else not_true = true;
		
		e_num++;
		if (!visit[x])visit[x]=true,node_num++;
		if (!visit[y])visit[y]=true,node_num++;
		
	}
	return 0;
}