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:
// Does this make the program faster?
#if not LOCAL
#define NDEBUG 1
#endif
#include<bits/stdc++.h>

struct Tree{
	std::vector<int> data;
	std::vector<int> changedList;

	Tree(int size): data(size*2, INT_MIN), changedList() {}

	int offset()const{
		return int(data.size()/2);
	}

	void fastReset(){
		for(auto node: changedList) data[node]=INT_MIN;
		changedList.clear();
	}

	void setMaximum(int left, int right, int value){
		auto const process=[&](int node){
			if(data[node]==INT_MIN)
				changedList.push_back(node);

			data[node]=std::max(data[node], value);
		};

		for( left+=offset(), right+=offset();
				left!=right;
				left>>=1, right>>=1){
			if(left&1) process(left++);
			if(right&1) process(--right);
		}
	}

	int operator[](int index) const{
		int result=INT_MIN;
		for(int node=index+offset(); node; node>>=1)
			result=std::max(result, data[node]);
		return result;
	}
};


int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int number; std::cin>>number;

	int resultAll{};


	std::vector<Tree> data; // reuse the data structure to avoid memset time
	int const globalMaxValue=100000;

	for(int _=0; _<number; ++_){
		int len; std::cin>>len;
		assert(len>=1);
		std::vector<int> value(len); for(auto& it: value) std::cin>>it;
		assert(std::is_sorted(begin(value), end(value)));
		assert(value.back()<=globalMaxValue);


		if(number==1){
			assert(len!=0);
			std::cout<<"YES\n";
			return 0;
		}


		for(auto& it: data) it.fastReset();
		// if _3, the amortized complexity of this function is just existing+20*(number<=1000)

		//int const maxValue=value.back();


		// data[g][a] = maximum b such that f(a, b)==g (and b in value), or INT_MIN
		// conjecture: there are only log(maxValue) distinct data values (_3)

		// update: _3 was wrong. (really?)
		// so result==447 with 1e5 values.
		// Let's special-case it.

		// grundy value of states reachable from the initial state.
		// Used to compute mex -> grundy value of the initial state.
		std::vector<char> initialMark(value.size()); // total complexity: 1e5

		// f(a, b) | b in value = grundy value, last=a
		for(auto index=value.size(); index--;){ // total number of iterations: 1e5
			int const b=value[index];

			/*
			compute all f(*, b) values
			
			formula:
			f(a, b)=Mex f(b, c) |c>2b-a
			
			properties:
			f(a, b)<=f(a+1, b)
			a<=b
			
			to compute:
			* for all a, f(a, b)>=0
			* find a0 = minimum a such that {f(b, c)} >= {0} <=> f(a, b)>=1
			so a0=2*b-(maximum c0 such that {f(b, c) | c>c0} >= {0})
			c0 = (maximum c0 such that {f(b, c) | c>c0} >= {0})
			= (maximum c0 such that 0 in {f(b, c) | c>c0})
			= (maximum c0 such that any(f(b, c)==0 | c>=c0+1))
			= (maximum c0' such that any(f(b, c)==0 | c>=c0'))-1
			= (maximum c0' such that f(b, c0')==0)-1
			= data[0][b]-1
			a0=2*b+1-data[0][b]
			
			find a1>=a0 = maximum a such that {f(b, c)} >= {0, 1} <=> f(a, b)>=2
			a1=max(a0, 2*b+1-data[1][b])
			
			similarly, a_i = max(a_(i-1), 2*b+1-data[i][b])
			where a_(-1) = 0  (given that all data values (values in `value`) are >0)
			
			if data[][]==INT_MIN, then a_i==INT_MAX i.e. there's no f(a, b)==i+1
			
			assert(a_i==INT_MAX or a_i<=b for all i);


			update the data structure
			f[0..a_0][b] = 0    -> data[0][0..a_0]   max= b
			f[a_0..a_1][b] = 1  -> data[1][a_0..a_1] max= b
			...
			
			similarly, data[j][a_(j-1)..a_i] max= b  for all 0<=j<=i.
			special case: set a_i=min(a_i, b) (_2)
			*/


			for(int i=0, lasta=0;; ++i){ // if _3 then i<=20
				// => each loop iteration does 20*log(globalMaxValue) ~= 400 steps at most
				// excluding _4
				// => total: 1e5*400=4e7.

				int ai, tmp;
				if(i>=(int)data.size() or (tmp=data[i][b])==INT_MIN){
					assert(lasta<=b+1);
					ai=b+1; // _2
				}else{
					// at the moment, data[i][b]>=b if it's not INT_MIN (it's only set at _1)
					// so b*2+1-data[i][b] <= b+1
					ai=std::max(lasta,
						b*2+1-tmp
						);
					assert(ai<=b+1);
				}

				assert((int)data.size()>=i);
				if(i==(int)data.size()) // _4
					data.emplace_back(globalMaxValue+1); // total complexity: data.size()*globalMaxValue
				// <= 20*1e5 == 2e6 if _3
				// -> 4e6 int in main, 4e6 for fastReset -> 8e6 int -> 32 MB
#if 0
				for(int j=lasta; j<ai; ++j)
					data[i][j]=std::max(data[i][j], b);
#else
				assert(lasta<=ai);
				data[i].setMaximum(lasta, ai,  b); // _1
#endif

				if(ai==b+1){
					assert(lasta<ai);
					// a state with g==f[b][b] == i is reachable from the initial state
					if(i<(int)initialMark.size())
						initialMark[i]=true; // this line is run at most value.size()==initialMark.size() times
					break;
				}
				lasta=ai;
			}
		}

		int result=int(std::find(begin(initialMark), end(initialMark), false)-initialMark.begin());
		// grundy value of the initial state

		resultAll^=result;
	}
	std::cout<<(resultAll!=0 ? "YES\n": "NO\n");
}