#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <vector>

using namespace std;

// input & output filenames
#define FILE_IN "metro.in"
#define FILE_OUT "metro.out"

//restrictions
const int MAXK = 1000;
const int MINK = 1;
const int MAXN = (MAXK-1)*3;
const int MINN = 0;

// global variables
vector<int> circ[MAXK];	// circle stations
vector<int> com[2*MAXK];	// non-circle(common) stations

int test[MAXK];
int mark[MAXK];				// lines colors, same color if have common non-circle station
int tmp[MAXK];
int tmp2[MAXK];				
char tmp3[MAXK];
int adj[MAXK][MAXK];		// adjacency matrix (cnum*cnum)
int total[MAXK];			// number of stations had lines of i-th color
int cnum;

int k,n
		,cn  // number of circle stations
		,cm; // number of non-circle stations

int ans;

int isBipartite(int i,int col) {
	assert(tmp[i]==0);
	tmp[i] = col;

	int j;	
	for (j=0;j<cnum;j++) 
		if (adj[i][j]==0) {
			if (tmp[j]==0) {
				if (!isBipartite(j,3-col))
					return 0;
			} else { 
				if (tmp[j]+tmp[i]!=3) 
					return 0;				
			}
		}
	return 1;	
}

void Init(){
	cn = cm = 0;
	memset(mark,0,sizeof(mark));
	memset(adj,0,sizeof(adj));
	memset(total,0,sizeof(total));
}

void OutData(){
	if (ans)
		printf("YES\n");
	else
		printf("NO\n");	
}

int ReadData(){
	if (scanf("%d %d",&k,&n)!=2) return 0;

	//check restrictions
	assert(k>=MINK);
	assert(k<=MAXK);
	assert(n>=MINN);
	assert(n<=MAXN);

	int i,j,t,x,y;

	for (i=0;i<n;i++) {
		assert(scanf("%d",&t)==1);
		assert(t>1);
		assert(scanf("%d",&x)==1);
		if (x!=0) break;		
		
		circ[cn].clear();
		for (j=1;j<t;j++){
			y = x;
			assert(scanf("%d",&x)==1);
			assert(y<x);	// check increasing
			assert(x<k);
			circ[cn].push_back(x);			
		}
		cn++;
		x=-1;
	}

	if (x>0) {		
		assert(x<k);
		com[cm].clear();
		com[cm].push_back(x);
		for (j=1;j<t;j++){					
			y = x;
			assert(scanf("%d",&x)==1);
			assert(y<x);	// check increasing
			assert(x<k);
			com[cm].push_back(x);
		}
		cm++;
		i++;
	}
	
	for (;i<n;i++) {
		assert(scanf("%d",&t)==1);
		assert(t>1);
		
		com[cm].clear();
		x = 0;	//all stations must be non-circle (>0)
		for (j=0;j<t;j++){					
			y = x;
			assert(scanf("%d",&x)==1);
			assert(y<x);	// check increasing
			assert(x<k);
			com[cm].push_back(x);
		}
		cm++;
	}

    //check test topology

    memset(test, 0, sizeof(test));    
    vector<int>::iterator p;	

    for (i=0;i<cn;i++) {
		p = circ[i].begin();
		while(p!=circ[i].end()) {
			test[*p]++;
			assert(test[*p]<=2);	// <= 2 staions of line lie on circle line
			p++;
		}
    }

    memset(test, 0, sizeof(test));        
    for (i=0;i<cm;i++) {
    	p = com[i].begin();
    	while (p!=com[i].end()) {
    		test[*p]++;
    		assert(test[*p]<=1);	// <= 1 non-circle stations on current line
			p++;
    	}	
    }

	return 1;
}

void Solve(){
	int i;
	vector<int>::iterator p;	
	
	// color lines
	for (i=0;i<cm;i++) {
		p = com[i].begin();
		while (p!=com[i].end()) {
			assert(mark[*p]==0);
			mark[*p] = i+1;
			p++;
		}
	}
		
	cnum = cm;
	int j;
	
	// calculate total numer of stations had lines of i-th color
	for (j=0;j<cn;j++) {
		p = circ[j].begin();
		while (p!=circ[j].end()) {
			if (mark[*p]==0)	
				mark[*p] = ++cnum;				
			
			total[mark[*p]-1]++;
			p++;
		}		
	}

	int dx = MAXK+1;
	int cur;
	
	// find relationships between colors
	for (i=0;i<cnum;i++) {		
		memset(tmp,0,sizeof(tmp[0])*cnum);	
		memset(tmp2,0,sizeof(tmp2[0])*cnum);	
		memset(tmp3,0,sizeof(tmp3[0])*cnum);	
		for (j=0;j<cn;j++) {
			cur = 0;
			p = circ[j].begin();
			while (p!=circ[j].end()) {
				if (mark[*p]==i+1) {
					cur = 1;
					break;					
				}			
				p++;
			}

			p = circ[j].begin();
			while (p!=circ[j].end()) {
				if (mark[*p]!=i+1) {
					
					if (total[mark[*p]-1]==1) {
						adj[mark[*p]-1][i] = 1;					
						adj[i][mark[*p]-1] = 1;										
					}

					if (tmp3[mark[*p]-1]!=0 && tmp3[mark[*p]-1]!=j+1){
						tmp[mark[*p]-1] += tmp2[mark[*p]-1];
						tmp2[mark[*p]-1] = 0;
					}

					if (cur) tmp2[mark[*p]-1]++;
					
					tmp3[mark[*p]-1] = j+1;

					tmp[mark[*p]-1] += dx;					

					if (tmp[mark[*p]-1] == dx*total[mark[*p]-1]) {
						adj[mark[*p]-1][i] = 1;					
						adj[i][mark[*p]-1] = 1;					
					}
				}
				p++;
			}
			if (cur) dx++;
		}
		adj[i][i] = 1;
	}

	// cheching for contradioctions, if successfully than YES, else NO
	memset(tmp,0,sizeof(tmp[0])*cnum);

	ans = 1;
	for (i=0;i<cnum;i++) 
		if (tmp[i]==0){
			if (!isBipartite(i,1)) {
				ans = 0;
				break;
			}
		}
}

int main() {
	
	freopen(FILE_IN,"r",stdin);
	freopen(FILE_OUT,"w",stdout);

	Init();
	while (ReadData()) {
		Solve();
		OutData();
		Init();
	}

	fclose(stdout);	
	return 0;
}