#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <iomanip>
#define _USE_MATH_DEFINES
#include <math.h>
#include <numeric>
#include <regex>
#include <locale>
#include <fstream>
#include <stdlib.h>
#include <cctype>

//#include <map>

using namespace std;

class cDice		// cDise -> cDice
{
	vector<int> X;
	vector<int> Y;
	vector<int> vLabel;
	vector<int> vRep;

	void rotateDice(char d)
	{
		int t;

		switch (d)
		{
			case 'N':
				t = X[0];
				X[0] = Y[0] = Y[1];
				Y[1] = 7 - t;
				break;
			case 'S':
				t = Y[1];
				Y[1] = Y[0];
				X[0] = Y[0] = 7 - t;
				break;
			case 'W':
				t = X[0];
				X[0] = Y[0] = X[1];
				X[1] = 7 - t;
				break;
			case 'E':
				t = X[1];
				X[1] = X[0];
				X[0] = Y[0] = 7 - t;
				break;
			default:break;
		}
	}

	vector<int> getCurrentSurface()
	{
		vector<int> t(vLabel.size());

		t[0] = vLabel.at(X[0] - 1);
		t[1] = vLabel.at(Y[1] - 1);
		t[2] = vLabel.at(X[1] - 1);
		t[3] = vLabel.at(7 - X[0] - 1);
		t[4] = vLabel.at(7 - Y[1] - 1);
		t[5] = vLabel.at(7 - X[1] - 1);

		return t;
	}

public:

	cDice(string l)
	{
		X = { 1, 3 };
		Y = { 1, 2 };

		istringstream iss(l);
		while (!iss.eof())
		{
			int t;
			iss >> t;
			vLabel.push_back(t);
			iss.ignore();
		}

		for (int i = 0; i < vLabel.size(); i++)
		{
			vRep.push_back(0);
			for (int j = 0; j < vLabel.size(); j++)
			{
				if (vLabel.at(i) == vLabel.at(j) && i != j)
				{
					vRep.at(i)++;
				}
			}
		}
	}

	void rotateByStr(string dir)
	{
		istringstream iss(dir);
		vector<char> vc;
		int char_size = 1;

		for (string::iterator it = dir.begin(); it != dir.end(); it += char_size)
		{
			int t;
			rotateDice(*it);
		}
	}

	void rotateAndFindTop(string dir,int t)
	{
		istringstream iss(dir);
		vector<char> vc;
		int char_size = 1;

		for (string::iterator it = dir.begin(); it != dir.end(); it += char_size)
		{
			rotateDice(*it);
			if (getCurrentTop() == t)break;
		}
	}

	vector<int> getRep()
	{
		return vRep;
	}

	vector<int> getLabel()
	{
		return vLabel;
	}

	int getCurrentTop()
	{
		if (X[0] == Y[0])
		{
			return vLabel.at(X[0] - 1);
		}
		return -1;
	}
	
	int getCurrentFront()
	{
		if (X[0] == Y[0])
		{
			return vLabel.at(Y[1] - 1);
		}
		return -1;
	}
	
	int getCurrentRight()
	{
		if (X[0] == Y[0])
		{
			return vLabel.at(X[1] - 1);
		}
		return -1;
	}

	bool operator==(cDice &d)
	{
		bool isSame;

		for (int i = 0; i < vRep.size(); i++)
		{
			if (vRep.at(i) == 0 || i == vRep.size() - 1)
			{
				rotateAndFindTop("NNNNENNN", vLabel.at(vRep.at(i)));
				d.rotateAndFindTop("NNNNENNN", getCurrentTop());
				int first = d.getCurrentFront();
				while (d.getCurrentFront() != getCurrentFront())
				{
					d.rotateByStr("NES");
					if (first == d.getCurrentFront())
					{
						isSame = false;
						break;
					}
				}
				if (getCurrentSurface() == d.getCurrentSurface())
				{
					isSame = true;
				}
				else
				{
					isSame = false;
				}
			}
		}
		return isSame;
	}
};

int main()
{
	int n;
	cin >> n;
	cin.ignore();

	vector<cDice> vcd;

	for (int i = 0; i < n; i++)
	{
		string lb;
		getline(cin, lb);
		cDice d(lb);
		vcd.push_back(d);
	}

	bool isSame = false;

	for (int i = 0; i < vcd.size(); i++)
	{
		isSame = false;
		for (int j = i + 1; j < vcd.size(); j++)
		{
			if (vcd.at(i) == vcd.at(j))
			{
				isSame = true;
				break;
			}
			else
			{
				isSame = false;
			}
		}
		if (isSame == true)break;
	}
	string ans(isSame ? "No" : "Yes");
	cout << ans << endl;

	return 0;
}

Measured memory_bytes: 3220