#include <iostream>
#include <iomanip>
#define _USE_MATH_DEFINES
#include <math.h>
#include <string>
#include <stdio.h>
#include <sstream>

using namespace std;

class Dice
{
public:
	Dice() {};
	Dice(int s1, int s2, int s3, int s4, int s5, int s6)
	{
		Upper = s1;
		South = s2;
		East = s3;
		West = s4;
		North = s5;
		Down = s6;
	};
	Dice(int *input)
	{
		for (int i = 0; i < 6; ++i)
			v[i] = input[i];
	};
	~Dice() {};
public:
	union
	{
		struct
		{
			int Upper, South, East, West, North, Down;
		};
		int v[6];
	};
	
	enum DIRECTION
	{
		UPPER = 0,
		SOUTH,
		EAST,
		WEST,
		NORTH,
		DOWN
	};


public:
	void RolltoNorth();
	void RolltoSouth();
	void RolltoEast();
	void RolltoWest();
	void RollalongCW();
	void RollalongUCW();
	void RolltoUpper(int input);

public:
	int isMatched(int upper, int front);
	int getUpper() { return this->Upper; }
	int getSouth() { return this->South; }
	int getEast() { return this->East; }
	int getWest() { return this->West; }
	int getNorth() { return this->North; }
	int getDown() { return this->Down; }

public:
	void Disp() 
	{
		cout <<"U: " << this->Upper << " "
			<< "S: " << this->South << " "
			<< "E: " << this->East << " "
			<< "W: " << this->West << " "
			<< "N: " << this->North << " "
			<< "D: " << this->Down << endl;
	};
	void DispUpper()
	{
		cout << this->Upper << endl;
	};
	void CloneDice(Dice &input)
	{
		for (int i = 0; i < 6; ++i)
			this->v[i] = input.v[i];
	}
};

void Dice::RolltoNorth()
{
	Dice a;
	a.Down = this->North;
	a.North = this->Upper;
	a.Upper = this->South;
	a.South = this->Down;
	a.East = this->East;
	a.West = this->West;
	*this = a;
}
void Dice::RolltoSouth()
{
	Dice a;
	a.Down = this->South;
	a.South = this->Upper;
	a.Upper = this->North;
	a.North = this->Down;
	a.East = this->East;
	a.West = this->West;
	*this = a;
}

void Dice::RolltoEast()
{
	Dice a;
	a.Down = this->East;
	a.East = this->Upper;
	a.Upper = this->West;
	a.West = this->Down;
	a.South = this->South;
	a.North = this->North;
	*this = a;
}

void Dice::RolltoWest()
{
	Dice a;
	a.Down = this->West;
	a.West = this->Upper;
	a.Upper = this->East;
	a.East = this->Down;
	a.South = this->South;
	a.North = this->North;
	*this = a;
}

void Dice::RollalongCW()
{
	Dice a;
	a.East = this->North;
	a.North = this->West;
	a.West = this->South;
	a.South = this->East;
	a.Upper = this->Upper;
	a.Down = this->Down;
	*this = a;
}

void Dice::RollalongUCW()
{
	Dice a;
	a.West = this->North;
	a.North = this->East;
	a.East = this->South;
	a.South = this->West;
	a.Upper = this->Upper;
	a.Down = this->Down;
	*this = a;
}

void Dice::RolltoUpper(int input)
{
	switch (input)
	{
	case UPPER:
		return;
	case SOUTH:
		this->RolltoNorth();
		return;
	case EAST:
		this->RolltoWest();
		return;
	case WEST:
		this->RolltoEast();
		return;
	case NORTH:
		this->RolltoSouth();
		return;
	case DOWN:
		this->RolltoEast();
		this->RolltoEast();
		return;
	}

}

int Dice::isMatched(int upper, int front)
{
	int temp = -1;
	for (int i = 0; i < 6; ++i)
	{
		if (this->v[i] == upper)
			temp = i;
	}
	if (temp == -1)
		return -1;

	switch (temp)
	{
	case 2:
	case 3:
		while (true)
		{
			if (upper != this->getUpper())
				this->RolltoEast();
			else
				break;
		}
		break;
	case 0:
	case 1:
	case 4:
	case 5:
		while (true)
		{
			if (upper != this->getUpper())
				this->RolltoNorth();
			else
				break;
		}
		break;
	default:
		return -1;
	}

	temp = -1;
	for (int i = 0; i < 6; ++i)
	{
		if (this->v[i] == front)
			temp = i;
	}
	if (temp == -1)
		return -1;

	while (true)
	{
		if (front != this->getSouth())
			this->RollalongCW();
		else
			break;
	}

	return this->getEast();
}

bool bCheckEWNS(Dice &A, Dice &B)
{
	if (A.getEast() == B.getEast()
		&& A.getWest() == B.getWest()
		&& A.getNorth() == B.getNorth()
		&& A.getSouth() == B.getSouth())
		return true;
	else
		return false;
}

bool bIsMatched(Dice &A, Dice &B)
{
	// 全探索でAとBはあわせる
	// Aを基準にし，upperが合うものがあったら，回転する．
	// frontを合わせに行きあったら
	// もう一面を合ってるか確認．

	Dice cloneA, cloneB;
	cloneA.CloneDice(A);
	cloneB.CloneDice(B);

	bool flag = false;

	for (int i = 0; i < 6; ++i)
	{
		for (int j = 0; j < 6; ++j)
		{
			if (A.v[i]== B.v[j])
			{
				cloneA.CloneDice(A);
				cloneB.CloneDice(B);

				cloneA.RolltoUpper(i);
				cloneB.RolltoUpper(j);

				if (cloneA.getDown() != cloneB.getDown())
					break;
				
				for (int k = 0; k < 4; ++k)
				{
					flag = bCheckEWNS(cloneA, cloneB);
					if (flag)
						break;
					cloneB.RollalongCW();
				}

			}
			if (flag)
				break;
		}
		if (flag)
			break;
	}

	return flag;
}



int main()
{
	int numOfDice;
	cin >> numOfDice;

	Dice allDice[100];
	for (int i = 0; i < numOfDice; ++i)
	{
		for (int j = 0; j < 6; ++j)
			cin >> allDice[i].v[j];
	}

	Dice A, B;
	bool flag = true;
	for (int i = 0; i < numOfDice; ++i)
	{
		for (int j = i + 1; j < numOfDice; ++j)
		{
			A.CloneDice(allDice[i]);
			B.CloneDice(allDice[j]);

			if (bIsMatched(A, B))
				flag = false;
		}
	}

	if (flag)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;

	return 0;
}





Measured memory_bytes: 3144