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<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　  |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/










int N, A[6];
//---------------------------------------------------------------------------------------------------
vector<vector<int>> B = { {0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0} };
int get(vector<int> v) {
    rep(i, 0, 6) {
        int ok = 1;
        rep(j, 0, 3) if (v[j] != B[i][j]) ok = 0;
        if (ok) return i;
    }
    assert(0);
}
//---------------------------------------------------------------------------------------------------
#define yes "yes"
#define no "no"
string solve() {
    vector<int> v;
    v.push_back(0);
    rep(i, 0, 6) v.push_back(i);

    do {
        int s = 0, t = -1;
        rep(i, 1, 7) if (v[i] == 0) t = i;
        assert(1 <= t);

        vector<int> cnt(6);
        rep(i, s, t) {
            int a = v[i];
            int b = v[i + 1];

            vector<int> w;
            rep(u, 0, 3) rep(v, 0, 3) if (B[a][u] == B[b][v]) w.push_back(v);
            cnt[get(w)]++;
        }

        int ok = 1;
        rep(i, 0, 6) if (cnt[i] > A[i]) ok = 0;
        if (ok) {
            return yes;
        }
    } while (next_permutation(all(v)));

    return no;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N;
    rep(i, 0, N) {
        int w; cin >> w;
        vector<int> v = { 0, 1, 2 };
        rep(j, 0, w) {
            int a; cin >> a;
            if (a == 0) swap(v[0], v[1]);
            else swap(v[1], v[2]);
        }

        A[get(v)]++;
    }

    cout << solve() << endl;
}