Problem: Problem

There are $ N $ Amidakuji with 3 vertical lines.
No matter which line you start from, the Amidakuji that ends at the starting line is considered a good Amidakuji.
You can select one or more Amidakuji and connect them vertically in any order.
Output "yes" if you can make a good Amidakuji, otherwise output "no".

There are $ w_i $ horizontal lines in the $ i $ th Amidakuji.
$ a_ {i, j} $ indicates whether the $ j $ th horizontal bar from the top of Amidakuji $ i $ extends from the central vertical line to the left or right.
If $ a_ {i, j} $ is 0, it means that it extends to the left, and if it is 1, it means that it extends to the right.

Constraints

The input satisfies the following conditions.

* $ 1 \ le N \ le 50 $
* $ 0 \ le w_i \ le 100 $
* $ a_ {i, j} $ is 0 or 1

Input

The input is given in the following format.


$ N $
$ w_1 $ $ a_ {1,1} $ $ a_ {1,2} $ ... $ a_ {1, w_1} $
$ w_2 $ $ a_ {2,1} $ $ a_ {2,2} $ ... $ a_ {2, w_2} $
...
$ w_N $ $ a_ {N, 1} $ $ a_ {N, 2} $ ... $ a_ {N, w_N} $


All inputs are given as integers.
$ N $ is given on the first line.
$ W_i $ and $ w_i $ $ a_ {i, j} $ are given on the following $ N $ line, separated by blanks.

Output

If you can make a good Amidakuji, it outputs "yes", otherwise it outputs "no".

Examples

Input

3
2 0 0
1 1
5 1 0 0 1 0


Output

yes


Input

2
1 1
1 0


Output

no

Solution (in CPP):

Solution:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cassert>
#include <exception>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> P;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<P> vp;
#define rep(i,a,n) for(ll i = (a);i < (n);i++)
#define per(i,a,n) for(ll i = (a);i > (n);i--)
#define lep(i,a,n) for(ll i = (a);i <= (n);i++)
#define pel(i,a,n) for(ll i = (a);i >= (n);i--)
#define clr(a,b) memset((a),(b),sizeof(a))
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(),(c).end()
#define sz size()
#define print(X) cout << (X) << endl
const ll INF = 1e+9+7;
ll n,m,l;
string s,t;
ll d[200010],dp[550][550];

string change(string boo){
  string str = "123";
  rep(i,0,boo.sz){
    if(boo[i] == '1')swap(str[1],str[2]);
    else swap(str[1],str[0]);
  }
  return str;
}

string exchange(string str,string key){
  if(key == "132")swap(str[1],str[2]);
  if(key == "321")swap(str[0],str[2]);
  if(key == "213")swap(str[0],str[1]);
  if(key == "231"){
    swap(str[0],str[1]);
    swap(str[1],str[2]);
  }
  if(key == "312"){
    swap(str[0],str[1]);
    swap(str[0],str[2]);
  }
  return str;
}

int main(){
  t = "no";
  int num[6] = {0,1,1,1,2,2};
  cin >> n;
  vector<string> vec{"123","132","321","213","231","312"};
  map<string,int> test;
  rep(i,0,n){
    string boolean;
    cin >> m;
    rep(j,0,m){
      char c;
      cin >> c;
      boolean += c;
    }
    test[change(boolean)]++;
  }
  rep(i,0,vec.sz)if(test[vec[i]] > num[i])t = "yes";
  if(t != "yes"){
    vector<string> vec2;
    rep(i,1,6){
      rep(j,0,test[vec[i]])vec2.pb(vec[i]);
    }
    sort(all(vec));
    do{
      string res = vec2[0];
      // cout << "first_res:" << res << endl;
      rep(i,1,vec2.sz){
        res = exchange(res,vec2[i]);
        // cout << "res:" << res << endl;
        if(res == "123")t = "yes";
      }
    }while(next_permutation(vec2.begin(),vec2.end()));
  }
  print(t);
  return 0;
}