//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
#define rep(i, n) for(int i=0; i<n; ++i)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
using namespace std;
using ll = int64_t;
using ld = long double;
using P = pair<int, int>;
using vs = vector<string>;
using vi = vector<int>;
using vvi = vector<vi>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQG = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0xccccccc;
const ll LINF = 0xcccccccccccccccLL;
template<typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) {return a < b && (a = b, true);}
template<typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) {return a > b && (a = b, true);}
template<typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) { return is >> p.first >> p.second;}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) { return os << p.first << ' ' << p.second;}

struct UnionFind {
	vector<int> par; // 親を指すvector,-par[親]は木のサイズ
	UnionFind(int n):par(n, -1) {} // uniteで親を埋め込んでいく必要あり
	int root(int x) { // 親をたどる&データの整理
		if(par[x] < 0) return x;
		return par[x] = root(par[x]);
	}
	bool unite(int x, int y) { // データの結合
		x = root(x);
		y = root(y);
		if(x == y) return false;
		if(par[x] > par[y]) swap(x, y);
		par[x] += par[y];
		par[y] = x;
		return true;
	}
	bool same(int x, int y) {return root(x) == root(y);} // 所属判定
	int size(int x) {return -par[root(x)];} // 木のサイズ
};

//head

#define N 400010

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin >> n;
	vi cnt(N);
	UnionFind uft(N);
	rep(i, n) {
		int a, b;
		cin >> a >> b;
		uft.unite(a, b);
		cnt[a]++;
	}
	rep(i, N) if(uft.root(i) != i) cnt[uft.root(i)] += cnt[i];
	int ans = 0;
	rep(i, N) if(uft.root(i) == i) {
		ans += min(uft.size(i), cnt[i]);
	}
	cout << ans << endl;
}
#define NOMINMAX
#define TEST_MODE true

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include "bits/stdc++.h"
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rep2(i,a,b) for(int i=(a);i<(int)(b);++i)
#define rrep(i,n) for(int i=(n)-1;i>=0;--i)
#define rrep2(i,a,b) for(int i=(a)-1;i>=(int)b;--i)
#define range(i,a,b,c) for(int i=a;c>0?i<b:i>b;i+=c)

#define chmax(a,b) (a=(a)<(b)?(b):(a))
#define chmin(a,b) (a=(a)>(b)?(b):(a))

#define i1(a) cin>>a;
#define i2(a,b) cin>>a>>b;
#define i3(a,b,c) cin>>a;i2(b,c);
#define i4(a,b,c,d) cin>>a;i3(b,c,d);
#define i5(a,b,c,d) cin>>a;i4(b,c,d);

#define o1(a) cout<<a<<endl;
#define o2(a,b) cout<<a<<" ";p1(b);
#define o3(a,b,c) cout<<a<<" ";p2(b, c);

#define abp(o,a,b) o1(((o)?a:b))
#define YEP(x) abp(x,"YES","NO")
#define Yep(x) abp(x,"Yes","No")

#define all(a) begin(a),end(a)
#define ifnot(a) if(!(a))
#define int long long

#ifdef LOCAL_ENV

#if TEST_MODE==true
const bool test = true;
#define dump(x) cerr<<#x<<" : "<<(x)<< " "
#define dumpl(x) dump(x)<<endl
#else
const bool test = false;
#define dump(x) 
#define dumpl(x)
#endif

#else
const bool test = false;
#define dump(x) 
#define dumpl(x)
#endif

using ll = int;
using ull = unsigned int;
using ld = long double;

ll dx[] = { 1,0,-1,0 };
ll dy[] = { 0,1,0,-1 };
const ll inf = (ll)1 << 60;
const ll undefined = inf;
const ll INFL = (ll)1 << 60;
ll mod_n = (ll)1e9 + 7;
const double eps = 1e-10;
typedef long double Real;
// return -1, 0, 1
ll sgn(const Real& r) { return(r > eps) - (r < -eps); }
ll sgn(const Real& a, const Real& b) { return sgn(a - b); }

const ll MAX = (ll)2e5 + 5;
const ll MAX2 = (ll)2e3 + 5;

vector<string> split(const string& str, char sep) { vector<string> v; stringstream ss(str); string buffer; while (getline(ss, buffer, sep)) v.push_back(buffer); return v; }

string join(const vector<string>& v, const string delim = 0) { string s; if (!v.empty()) { s += v[0]; for (decltype(v.size()) i = 1, c = v.size(); i < c; ++i) { if (delim != "")s += delim; s += v[i]; } }return s; }

string operator*(const string& s, const ll& n) { string res = ""; rep(i, n)res += s; return res; }

#define sum(a) accumulate(all(a),0ll)

template<typename T>T gcd(T a, T b) { T c; while (a != 0) { c = a; a = b % a; b = c; }; return b; }
#define bit_cnt(n) [](int n){int c=0;while(N){if(N&1)c++;N>>=1;}return c;};

template<typename T>void prll_vec(ostream& o, vector<T> a) { rep(i, a.size() - 1)o << a[i] << " "; o << a.back() << endl; }

ll pow_n(ll x, ll n) { ll r = 1; while (n > 0) { if (n & 1)r = r * x; x = x * x; n >>= 1; }return r; }

ll H, W;

#define grid_ng(y,x) (y<0||y>=H||x<0||x>=W)

ll div_ceil(ll a, ll b) { ll r = a / b; if (a % b != 0)r++; return r; }


struct Point { ll x, y; bool operator<(const Point& r)const { if (x != r.x)return x < r.x; return y < r.y; } };

int n;

class Solver {
public:
	void solve() {
		int n; i1(n);
		vector<int> a(n), b(n);
		rep(i, n) i1(a[i]);
		rep(i, n) i1(b[i]);

		int sum = 0;
		rep(i, n) {
			sum += a[i] * b[i];
		}
		Yep(sum == 0);
	}
};

signed main() { srand((unsigned int)time(NULL)); cout << fixed << setprecision(20); auto ptr = new Solver(); ptr->solve(); delete ptr; return 0; }