Problem: Shikamaru and Asuma like to play different games, and sometimes they play the following: given an increasing list of numbers, they take turns to move. Each move consists of picking a number from the list.

Assume the picked numbers are v_{i_1}, v_{i_2}, …, v_{i_k}. The following conditions must hold:

  * i_{j} < i_{j+1} for all 1 ≤ j ≤ k-1; 
  * v_{i_{j+1}} - v_{i_j} < v_{i_{j+2}} - v_{i_{j+1}} for all 1 ≤ j ≤ k-2. 



However, it's easy to play only one instance of game, so today Shikamaru and Asuma decided to play n simultaneous games. They agreed on taking turns as for just one game, Shikamaru goes first. At each turn, the player performs a valid move in any single game. The player who cannot move loses. Find out who wins, provided that both play optimally.

Input

The first line contains the only integer n (1 ≤ n ≤ 1000) standing for the number of games Shikamaru and Asuma play at once. Next lines describe the games.

Each description starts from a line with the only number m (m≥ 1) denoting the length of the number list. The second line contains the increasing space-separated sequence v_1, v_2, ..., v_m from the game (1 ≤ v_{1} < v_{2} < ... < v_{m} ≤ 10^{5}).

The total length of all sequences doesn't exceed 10^5.

Output

Print "YES" if Shikamaru can secure the victory, and "NO" otherwise.

Examples

Input


1
10
1 2 3 4 5 6 7 8 9 10


Output


YES


Input


2
10
1 2 3 4 5 6 7 8 9 10
10
1 2 3 4 5 6 7 8 9 10


Output


NO


Input


4
7
14404 32906 41661 47694 51605 75933 80826
5
25374 42550 60164 62649 86273
2
7002 36731
8
23305 45601 46404 47346 47675 58125 74092 87225


Output


NO

Note

In the first example Shikamaru can pick the last number, and Asuma cannot do anything because of the first constraint.

In the second sample test Asuma can follow the symmetric strategy, repeating Shikamaru's moves in the other instance each time, and therefore win.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using db = double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<db, db>;
using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<ll>;
using vd = vector<db>;
using vs = vector<str>;
using vpi = vector<pi>;
using vpl = vector<pl>;
using vpd = vector<pd>;
template <class T>
using V = vector<T>;
template <class T, size_t SZ>
using AR = array<T, SZ>;
template <class T>
using PR = pair<T, T>;
const int MOD = 1e9 + 7;
const int MX = 2e5 + 5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
constexpr int pct(int x) { return __builtin_popcount(x); }
constexpr int bits(int x) { return 31 - __builtin_clz(x); }
ll cdiv(ll a, ll b) { return a / b + ((a ^ b) > 0 && a % b); }
ll fdiv(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); }
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
template <class T, class U>
T fstTrue(T lo, T hi, U first) {
  hi++;
  assert(lo <= hi);
  while (lo < hi) {
    T mid = lo + (hi - lo) / 2;
    first(mid) ? hi = mid : lo = mid + 1;
  }
  return lo;
}
template <class T, class U>
T lstTrue(T lo, T hi, U first) {
  lo--;
  assert(lo <= hi);
  while (lo < hi) {
    T mid = lo + (hi - lo + 1) / 2;
    first(mid) ? lo = mid : hi = mid - 1;
  }
  return lo;
}
template <class T>
void remDup(vector<T>& v) {
  sort(begin(v), end(v));
  v.erase(unique(begin(v), end(v)), end(v));
}
template <class T, class U>
void erase(T& t, const U& u) {
  auto it = t.find(u);
  assert(it != end(t));
  t.erase(u);
}
template <class T>
void re(complex<T>& c);
template <class T, class U>
void re(pair<T, U>& p);
template <class T>
void re(vector<T>& v);
template <class T, size_t SZ>
void re(AR<T, SZ>& a);
template <class T>
void re(T& x) {
  cin >> x;
}
void re(db& d) {
  str t;
  re(t);
  d = stod(t);
}
void re(ld& d) {
  str t;
  re(t);
  d = stold(t);
}
template <class T, class... U>
void re(T& t, U&... u) {
  re(t);
  re(u...);
}
template <class T>
void re(complex<T>& c) {
  T a, b;
  re(a, b);
  c = {a, b};
}
template <class T, class U>
void re(pair<T, U>& p) {
  re(p.first, p.second);
}
template <class T>
void re(vector<T>& x) {
  for (auto& a : x) re(a);
}
template <class T, size_t SZ>
void re(AR<T, SZ>& x) {
  for (auto& a : x) re(a);
}
template <class T>
void rv(int& n, vector<T>& x) {
  re(n);
  x.resize(n);
  for (auto& a : x) re(a);
}
str to_string(char c) { return str(1, c); }
str to_string(const char* second) { return (str)second; }
str to_string(str second) { return second; }
str to_string(bool b) { return to_string((int)b); }
template <class T>
str to_string(complex<T> c) {
  stringstream ss;
  ss << c;
  return ss.str();
}
str to_string(vector<bool> v) {
  str res = "{";
  for (int i = (0); i < ((int)(v).size()); ++i) res += char('0' + v[i]);
  res += "}";
  return res;
}
template <size_t SZ>
str to_string(bitset<SZ> b) {
  str res = "";
  for (int i = (0); i < (SZ); ++i) res += char('0' + b[i]);
  return res;
}
template <class T, class U>
str to_string(pair<T, U> p);
template <class T>
str to_string(T v) {
  bool fst = 1;
  str res = "";
  for (const auto& x : v) {
    if (!fst) res += " ";
    fst = 0;
    res += to_string(x);
  }
  return res;
}
template <class T, class U>
str to_string(pair<T, U> p) {
  return to_string(p.first) + " " + to_string(p.second);
}
template <class T>
void pr(T x) {
  cout << to_string(x);
}
template <class T, class... U>
void pr(const T& t, const U&... u) {
  pr(t);
  pr(u...);
}
void ps() { pr("\n"); }
template <class T, class... U>
void ps(const T& t, const U&... u) {
  pr(t);
  if (sizeof...(u)) pr(" ");
  ps(u...);
}
void DBG() { cerr << "]" << endl; }
template <class T, class... U>
void DBG(const T& t, const U&... u) {
  cerr << to_string(t);
  if (sizeof...(u)) cerr << ", ";
  DBG(u...);
}
void setIn(str second) { freopen(second.c_str(), "r", stdin); }
void setOut(str second) { freopen(second.c_str(), "w", stdout); }
void unsyncIO() { cin.tie(0)->sync_with_stdio(0); }
void setIO(str second = "") {
  unsyncIO();
  if ((int)(second).size()) {
    setIn(second + ".in"), setOut(second + ".out");
  }
}
int N, M;
vi game;
int mex(set<int> second) {
  int cur = 0;
  while (second.count(cur)) cur++;
  return cur;
}
int go(vi a, vi b) {
  while ((int)(a).size() > 2) a.erase(begin(a));
  set<int> vals;
  for (int i = (0); i < ((int)(b).size()); ++i) {
    if ((int)(a).size() == 2) {
      if (!(a[1] - a[0] < b[i] - a[1])) {
        continue;
      }
    }
    vi A = a;
    A.push_back(b[i]);
    vals.insert(go(A, vi(begin(b) + i + 1, end(b))));
  }
  return mex(vals);
}
int val() { return go({}, game); }
int find_max(vi a, vi b) {
  for (int i = (0); i < ((int)(a).size()); ++i)
    for (int j = (i + 1); j < ((int)(a).size()); ++j)
      for (int k = (j + 1); k < ((int)(a).size()); ++k)
        if (a[j] - a[i] >= a[k] - a[j]) return 0;
  int res = (int)(a).size();
  for (int i = (0); i < ((int)(b).size()); ++i) {
    vi A = a;
    A.push_back(b[i]);
    ckmax(res, find_max(A, vi(begin(b) + i + 1, end(b))));
  }
  return res;
}
int brute() { return find_max({}, game); }
int get_brute(vi v) {
  N = (int)(v).size();
  game = v;
  return brute();
}
int get_val(vi v) {
  N = (int)(v).size();
  game = v;
  return val();
}
void verify(vi v) {
  int ans = get_brute(v);
  if (ans < (int)(v).size()) {
    for (int i = (0); i < ((int)(v).size()); ++i) {
      vi V = v;
      V.erase(begin(V) + i);
      0;
      if (ans == get_brute(V)) return;
    }
  }
}
struct DSU {
  vi e;
  void init(int N) { e = vi(N, -1); }
  int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }
  bool sameSet(int a, int b) { return get(a) == get(b); }
  int size(int x) { return -e[get(x)]; }
  void unite(int x, int y) {
    x = get(x), y = get(y);
    assert(x < y);
    e[x] = y;
  }
};
DSU D;
int at_least[MX], rkey[MX];
int new_mx[MX];
int actual() {
  for (int i = (1); i < (100005); ++i) at_least[i] = 100004;
  for (auto& t : game) at_least[t] = t;
  for (int i = (0); i < ((int)(game).size()); ++i) rkey[game[i]] = i;
  for (int i = (100004) - 1; i >= (1); --i) ckmin(at_least[i], at_least[i + 1]);
  vi mx((int)(game).size(), MOD);
  set<int> all_vals;
  for (int val = 0;; ++val) {
    bool not_done = 0;
    for (auto& t : mx)
      if (t > -MOD) not_done = 1;
    if (!not_done) break;
    for (int i = (0); i < ((int)(game).size()); ++i) new_mx[i] = -MOD;
    for (auto& t : game) D.e[t] = -1;
    for (int i = ((int)(game).size()) - 1; i >= (0); --i) {
      ckmin(new_mx[i], mx[i]);
      if (mx[i] > -MOD && new_mx[i] <= -MOD) all_vals.insert(val);
      int lo = game[i] - mx[i], hi = game[i] - new_mx[i];
      mx[i] = new_mx[i];
      ckmax(lo, 1);
      ckmin(hi, game[i]);
      if (lo >= hi) continue;
      int huh = at_least[lo];
      while (1) {
        huh = D.get(huh);
        if (huh >= hi) break;
        new_mx[rkey[huh]] = game[i] - huh - 1;
        D.unite(huh, at_least[huh + 1]);
      }
    }
  }
  return mex(all_vals);
}
int dumb() {
  V<vi> ans((int)(game).size(), vi((int)(game).size()));
  set<int> al;
  for (int j = ((int)(game).size()) - 1; j >= (0); --j) {
    for (int i = (j)-1; i >= (0); --i) {
      set<int> bad;
      for (int k = (j + 1); k < ((int)(game).size()); ++k)
        if (game[k] - game[j] > game[j] - game[i]) bad.insert(ans[j][k]);
      ans[i][j] = mex(bad);
    }
    set<int> wut;
    for (int k = (j + 1); k < ((int)(game).size()); ++k) wut.insert(ans[j][k]);
    al.insert(mex(wut));
  }
  return mex(al);
}
int main() {
  setIO();
  D.init(100005);
  re(N);
  int ans = 0;
  for (int i = (0); i < (N); ++i) {
    rv(M, game);
    ans ^= actual();
  }
  if (ans)
    ps("YES");
  else
    ps("NO");
}