#include using namespace std; typedef long long ll; typedef long double ld; #define REP(i, n) for (int i = 0; i < (n); ++i) #define REPR(i, n) for (int i = n - 1; i >= 0; --i) #define FOR(i, m, n) for (int i = m; i < n; ++i) #define FORR(i, m, n) for (int i = m; i >= n; --i) #define ALL(v) (v).begin(),(v).end() templatebool chmax(T &a, const T &b) { if (abool chmin(T &a, const T &b) { if (b> groups() { std::vector leader_buf(_n), group_size(_n); for (int i = 0; i < _n; i++) { leader_buf[i] = leader(i); group_size[leader_buf[i]]++; } std::vector> result(_n); for (int i = 0; i < _n; i++) { result[i].reserve(group_size[i]); } for (int i = 0; i < _n; i++) { result[leader_buf[i]].push_back(i); } result.erase( std::remove_if(result.begin(), result.end(), [&](const std::vector& v) { return v.empty(); }), result.end()); return result; } private: int _n; // root node: -1 * component size // otherwise: parent std::vector parent_or_size; }; int main(){ cin.tie(0); ios::sync_with_stdio(false); int n,m;cin >> n >> m; vector> a(n); REP(i,n){ int b,c;cin >> b >> c; b--,c--; a[c].push_back(b); } dsu uf(m); REP(i,n){ if(a[i].size()<2) continue; REP(j,a[i].size()-1){ uf.merge(a[i][j],a[i][j+1]); } } int ans=0; REP(i,m){ if(uf.leader(i)==i) ans+=uf.size(i)-1; } cout << ans << endl; }