#include <iostream>
#include <string>
#include <cassert>

using namespace std;

const int DICE_SIZE = 6;
int const CmdCount = 6;
int const RotateLen = 4;

//ダイス
//東西南北に転がすことができる。
class dice {
  //一番上,南面,東面,西面,北面,底面の数字
  int values[DICE_SIZE];
public:
  dice (){};
  dice (const dice &d);
  virtual ~dice (){};
  int &operator[](int i){
    assert(0 <= i && i < DICE_SIZE);
    return values[i];
  };
  void docmd(string str);
  void docmd(char c);
  void setTopAndFront(int top,int front);
  void input(void);
  int right(void){return values[2];};
  int top(void){return values[0];};
  int front(void){return values[1];};
  bool Equal(const dice &d);
private:
  void output();
  bool IsArrayEqual(const dice &d);
  int indexs[CmdCount][RotateLen] = {
      {0, 2, 5, 3},
      {3, 5, 2, 0},
      {0, 1, 5, 4},
      {4, 5, 1, 0},
      {3, 1, 2, 4},
      {4, 2, 1, 3}};
  char cmdChar[CmdCount] = {'W', 'E', 'N', 'S','L','R'};
  string toTopCmd[6] = {"","N","W","E","S","NN"};
  string toFrontCmd[6] = {"S","","L","R","LL","N"};
  void move_forward(int *indexs);
  int find_value(int num);
};
dice::dice(const dice &d){
  for(int i = 0; i < DICE_SIZE; i++){
    this->values[i] = d.values[i];
  }
}
void dice::setTopAndFront(int top, int front){
  int idxTop = find_value(top);
  docmd(toTopCmd[idxTop]);
  int idxFront = find_value(front);
  docmd(toFrontCmd[idxFront]);
}
int dice::find_value(int num){
  for(int i = 0; i < DICE_SIZE; i++){
    if(values[i] == num){
      return i;
    }
  }
  assert(false);
}


void dice::docmd(string str){
  for(int i = 0; i < str.length(); i++){
    //cout << "docmd(str[i])" << str[i] << endl;
    docmd(str[i]);
  }
}

void dice::docmd(char c){
  for(int i = 0; i < CmdCount; i++){
    if (c == cmdChar[i]){
      //cout << cmdChar[i];
      move_forward(indexs[i]);
      return;
    }
  }
  assert(false);//命令表にない命令
}
void dice::move_forward(int *indexs){
  //for(int i = 0; i < 4; i++)cout << indexs[i];
  int temp = values[indexs[0]];
  values[indexs[0]] = values[indexs[1]];
  values[indexs[1]] = values[indexs[2]];
  values[indexs[2]] = values[indexs[3]];
  values[indexs[3]] = temp;
}
void dice::input(void){
  for(int i=0; i < DICE_SIZE; i++){
    int n;
    cin >> n;
    values[i] = n;
  }
}
bool dice::Equal(const dice &d){
  output();
  for(int i = 0; i < DICE_SIZE; i++){
    dice d2 = d;
    d2.docmd(toTopCmd[i]);
    for(int j = 0; j < RotateLen; j++){
      d2.docmd('L');
    //  cout << "d2 is ";
      d2.output();
      if (IsArrayEqual(d2)){
        return true;
      }
    }
  }
  return false;
}
void dice::output(){
/*  for(int i=0;i<DICE_SIZE;i++){
    cout << values[i] << " ";
  }
  cout << endl;*/
}
bool dice::IsArrayEqual(const dice &d){
  for (int i = 0; i < DICE_SIZE; i++) {
    if (d.values[i] != this->values[i]){
      return false;
    }
  }
  return true;
}
int main(int argc, char const *argv[]) {
  int count;
  cin >> count;
  dice *dice_array = new dice[count];
  for(int i = 0; i < count; i++){
    dice_array[i].input();
  }
  bool isALLNonEqual = true;
  for(int i = 1; i < count ;i++){
    if(dice_array[i].Equal(dice_array[0])){
      isALLNonEqual = false;
      break;
    }
  }
  if (isALLNonEqual){
    cout << "Yes" << endl;
  }else{
    cout << "No" << endl;
  }
  delete [] dice_array;
  return 0;
}
