/*
ID: C043
LANG: C++
TASK: man
*/

#include<stdio.h>

int p1[16384], p2[16384];

struct edge {
	int to, next;
	edge() { };
	edge(int _to, int _next) : to(_to), next(_next) { };
} v1[1048576], v2[1048576];
int l1, l2;

void init() {
	for(int i = 0; i < 16384; ++i) {
		p1[i] = p2[i] = -1;
	}
}

void solve() {
	int M, a, b, add_new, succ, total = 0;
	scanf("%d", &M);
	for(int i = 0; i < M; ++i) {
		scanf("%d%d", &a, &b);
		add_new = 1;
		//printf("Searching %d -> %d\n", a, b);
		for(int i = p2[a]; i != -1; i = v2[i].next) {
			if(v2[i].to == b) {
				add_new = 0;
				break;
			}
		}
		if(add_new) {
			++total;
			//printf("Adding %d -> %d\n", a, b);
			// Add a->b
			for(int i = p1[b]; i != -1; i = v1[i].next) {
				succ = v1[i].to;
				if(a == succ) continue;
				//printf("Indirect %d -> %d\n", a, succ);
				
				v2[l2] = edge(succ, p2[a]);
				p2[a] = l2;
				++l2;				
				
				v2[l2] = edge(a, p2[succ]);
				p2[succ] = l2;
				++l2;
			}
			v1[l1] = edge(b, p1[a]);
			p1[a] = l1;
			++l1;
			
			// Add b->a
			for(int i = p1[a]; i != -1; i = v1[i].next) {
				succ = v1[i].to;
				if(b == succ) continue;
				//printf("Indirect %d -> %d\n", b, succ);
				
				v2[l2] = edge(succ, p2[b]);
				p2[b] = l2;
				++l2;
				
				v2[l2] = edge(b, p2[succ]);
				p2[succ] = l2;
				++l2;
			}
			v1[l1] = edge(a, p1[b]);
			p1[b] = l1;
			++l1;
		} else {
			//printf("Exists %d -> %d\n", a, b);
		}
	}
	printf("%d\n", total);
}

int main() {
	init();
	solve();
	return 0;
}
