#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define cm (1 << 17)
char cn[cm], *ci = cn + cm, ct;

inline char getcha() {
	if (ci - cn == cm) {
		fread(cn, 1, cm, stdin);
		ci = cn;
	}
	return *ci++;
}

inline int getint() {
	int A = 0;
	while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	return A;
}

vector<int> p;

int get(int x) {
	return p[x] == x ? x : p[x] = get(p[x]);
}

int main() {
	int n = getint();
	constexpr int mx = 400010;
	p.resize(mx);
	iota(begin(p), end(p), 0);
	vector<int> cnt(mx);
	while (n--) {
		int a = getint(), b = getint();
		a = get(a), b = get(b);
		if (a != b) {
			p[b] = a;
			cnt[a] += cnt[b];
		}
		cnt[a]++;
	}
	vector<int> siz(mx);
	for (int i = 0; i < mx; i++) {
		siz[get(i)]++;
	}
	int ans = 0;
	for (int i = 0; i < mx; i++) {
		if (get(i) == i) {
			ans += min(cnt[i], siz[i]);
		}
	}
	printf("%d", ans);
}

#include <bits/stdc++.h>
using namespace std;

#define mnto(x, y) x = min(x, (__typeof__(x)) y)
#define mxto(x, y) y = max(x, (__typeof__(x)) y)
#define REP(i, s, e) for (int i = s; i < e; i++)
#define RREP(i, s, e) for (int i = s - 1; i >= e; i--)
typedef long long ll;
#define ALL(_a) _a.begin(), _a.end()
#define pb emplace_back
typedef vector<int> vi;
#define MP make_pair
#define FI first
#define SE second
typedef pair<int, int> ii;
#define MT make_tuple
typedef tuple<int, int, int> iii;

#define INF 1000000005
#define LINF 100000000000000005
#define MOD 1000000007
#define MAXN 200005
#define MAXA 400005

int n;
int in[MAXA];
vector<int> adjList[MAXA];
set<ii> st;
bool erased[MAXA];

int main() {
	scanf("%d", &n);
	REP (i, 0, n) {
		int a, b; scanf("%d%d", &a, &b);
		in[a]++;
		adjList[a].pb(b);
		if (a != b) {
			in[b]++;
			adjList[b].pb(a);
		}
	}
	REP (i, 1, MAXA) {
		if (in[i] == 0) continue;
		st.emplace(in[i], i);
	}
	int ans = 0;
	while (!st.empty()) {
		ii cur = *st.begin(); st.erase(st.begin());
		if (erased[cur.SE]) continue;
		for (int v : adjList[cur.SE]) {
			if (erased[v]) continue;
			st.erase(MP(in[v], v));
			in[v]--;
			if (in[v] > 0) st.emplace(MP(in[v], v));
			break;
		}
		erased[cur.SE] = true;
		ans++;
	}
	printf("%d\n", ans);
	return 0;
}
