//	-*- mode: C++ -*-
//	Dice IV
//
//		Write a program which reads n dices constructed in the same way as Dice I, and determines whether they are all different. For the determination, use the same way as Dice III.
//
//	Input
//		In the first line, the number of dices n is given. In the following n lines, six integers assigned to the dice faces are given respectively in the same way as Dice III.
//
//	Output
//		Print "Yes" if given dices are all different, otherwise "No" in a line.
//
//	Constraints
//		2≤n≤100
//		0≤ the integer assigned to a face ≤100
//	Sample Input 1
//		3
//		1 2 3 4 5 6
//		6 2 4 3 5 1
//		6 5 4 3 2 1
//	Sample Output 1
//		No
//
//	Sample Input 2
//		3
//		1 2 3 4 5 6
//		6 5 4 3 2 1
//		5 4 3 2 1 6
//	Sample Output 2
//		Yes

#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <climits>

const unsigned int	faces	{6};

void	E(std::vector<unsigned int>& dice);
void	S(std::vector<unsigned int>& dice);
void	rotate(std::vector<unsigned int>&	dice);

bool	isSameDice(std::vector<unsigned int>&				diceA,
				   std::vector<unsigned int>&				diceB);

int main(int	argc,
		 char*	argv[])
{
	unsigned int	diceCount;
	std::cin >> diceCount;

	std::vector<std::vector<unsigned int>>	dices	{};

	for(unsigned int i = 0; i < diceCount; i++){
		std::vector<unsigned int>	dice	{};
		dice.resize(faces, 0);
		for(unsigned int j = 0; j < faces; j++){
			std::cin >> dice[j];
		}

		dices.push_back(dice);
	}

	bool	isSame	= false;

	for(unsigned int i = 0; (i < diceCount - 1) && (isSame == false); i++){
		std::vector<unsigned int>	diceA	= dices[i];

		for(unsigned int j = i + 1; (j < diceCount) && (isSame == false); j++){
			std::vector<unsigned int>	diceB	= dices[j];

			isSame	= isSameDice(diceA, diceB);
		}
	}
	
	std::cout << (isSame ? "No" : "Yes") << '\n';

    return 0;
}

void	E(std::vector<unsigned int>& dice)
{
	unsigned int	x	= dice[0];
	dice[0]	= dice[3];
	dice[3]	= dice[5];
	dice[5]	= dice[2];
	dice[2]	= x;
}

void	S(std::vector<unsigned int>& dice)
{
	unsigned int	x	= dice[0];
	dice[0]	= dice[4];
	dice[4]	= dice[5];
	dice[5]	= dice[1];
	dice[1]	= x;
}

void	rotate(std::vector<unsigned int>&	dice)
{
	unsigned int	x	= dice[1];
	dice[1]	= dice[2];
	dice[2]	= dice[4];
	dice[4]	= dice[3];
	dice[3]	= x;
}

bool	isSameDice(std::vector<unsigned int>&	diceA,
				   std::vector<unsigned int>&	diceB)
{
	bool	isMatch	{false};

	// 前方向に一回転させる
	for(unsigned int i = 0; i < 4; i++){
		S(diceB);

		// 一回転がす毎に一致判定
		isMatch	= std::equal(diceA.begin(), diceA.end(), diceB.begin());

		if(isMatch){	// 一致したら終了
			return	isMatch;
		}

		// 一致しなかったら、横方向に一回転させながら一致判定
		for(unsigned int j = 0; j < 4; j++){
			rotate(diceB);

			isMatch	= std::equal(diceA.begin(), diceA.end(), diceB.begin());

			if(isMatch){	// 一致したら終了
				return	isMatch;
			}
		}
	}

	// 前方向に一回転させても一致しない場合は右方向に一回転
	for(unsigned int i = 0; i < 4; i++){
		E(diceB);

		// 一回転がす毎に一致判定
		isMatch	= std::equal(diceA.begin(), diceA.end(), diceB.begin());

		if(isMatch){	// 一致したら終了
			return	isMatch;
		}

		// 一致しなかったら、横方向に一回転させながら一致判定
		for(unsigned int j = 0; j < 4; j++){
			rotate(diceB);

			isMatch	= std::equal(diceA.begin(), diceA.end(), diceB.begin());

			if(isMatch){	// 一致したら終了
				return	isMatch;
			}
		}
	}

	return	isMatch;
}



Measured memory_bytes: 3168