#include #include #include using namespace std; // 自定义pair哈希 struct PairHash { size_t operator()(const pair& p) const { return hash()( ((long long)p.first << 32) | p.second ); } }; // 自定义tuple哈希 struct TupleHash { size_t operator()(const tuple& t) const { auto hash1 = hash{}(get<0>(t)); auto hash2 = hash{}(get<1>(t)); auto hash3 = hash{}(get<2>(t)); return (hash1 ^ (hash2 << 1)) ^ (hash3 << 2); } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int Q; cin >> Q; unordered_set vertices; unordered_set, PairHash> edges; unordered_set, TupleHash> faces; int v_count = 0, e_count = 0, f_count = 0; while (Q--) { int a, b, c; cin >> a >> b >> c; // 顶点处理(同之前) int new_v = 0; if (!vertices.count(a)) { vertices.insert(a); new_v++; } if (!vertices.count(b)) { vertices.insert(b); new_v++; } if (!vertices.count(c)) { vertices.insert(c); new_v++; } v_count += new_v; // 边处理(必须标准化) auto e1 = make_pair(min(a, b), max(a, b)); auto e2 = make_pair(min(b, c), max(b, c)); auto e3 = make_pair(min(c, a), max(c, a)); int new_e = 0; if (!edges.count(e1)) { edges.insert(e1); new_e++; } if (!edges.count(e2)) { edges.insert(e2); new_e++; } if (!edges.count(e3)) { edges.insert(e3); new_e++; } e_count += new_e; // 面处理(全排序) int x = min({a, b, c}); int z = max({a, b, c}); int y = a + b + c - x - z; auto f = make_tuple(x, y, z); if (!faces.count(f)) { faces.insert(f); f_count++; } } cout << v_count - e_count + f_count << endl; return 0; }