#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std;

struct Edge {
    int u, v;
    Edge(int a, int b) : u(min(a,b)), v(max(a,b)) {}
    bool operator==(const Edge& other) const {
        return u == other.u && v == other.v;
    }
};

namespace std {
    template<> struct hash<Edge> {
        size_t operator()(const Edge& e) const {
            return hash<long long>()( ((long long)e.u << 32) | e.v );
        }
    };
}

bool isBipartite(const vector<vector<int>>& graph, int start, vector<int>& color) {
    queue<int> q;
    q.push(start);
    color[start] = 0;
    
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        
        for (int v : graph[u]) {
            if (color[v] == -1) {
                color[v] = color[u] ^ 1;
                q.push(v);
            } else if (color[v] == color[u]) {
                return false;
            }
        }
    }
    return true;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int M;
    cin >> M;
    
    // 记录每条边对应的三角形索引
    unordered_map<Edge, vector<int>> edgeMap;
    vector<tuple<int, int, int>> triangles(M);
    
    for (int i = 0; i < M; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        triangles[i] = {a, b, c};
        
        edgeMap[Edge(a, b)].push_back(i);
        edgeMap[Edge(b, c)].push_back(i);
        edgeMap[Edge(a, c)].push_back(i);
    }
    
    // 检查是否有边被超过2个三角形共享
    for (const auto& [e, tris] : edgeMap) {
        if (tris.size() > 2) {
            cout << "NO\n";
            return 0;
        }
    }
    
    // 构建约束图
    vector<vector<int>> graph(M);
    for (const auto& [e, tris] : edgeMap) {
        if (tris.size() == 2) {
            int u = tris[0], v = tris[1];
            graph[u].push_back(v);
            graph[v].push_back(u);
        }
    }
    
    // 二分图判定
    vector<int> color(M, -1);
    for (int i = 0; i < M; ++i) {
        if (color[i] == -1) {
            if (!isBipartite(graph, i, color)) {
                cout << "NO\n";
                return 0;
            }
        }
    }
    
    cout << "YES\n";
    return 0;
}