#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#define llint long long
#define inf 1e18

using namespace std;
typedef pair<llint, llint> P;

llint m, n;
llint lb[105][105], ub[105][105];
vector<llint> G[105];
vector<llint> topo;
bool used[105];

void tpsort(int v)
{
	used[v] = true;
	for(int i = 0; i < G[v].size(); i++){
		if(!used[G[v][i]]) tpsort(G[v][i]);
	}
	topo.push_back(v);
}

int main(void)
{
	cin >> m >> n;
	llint x, s, t; string c;
	for(int i = 1; i <= m; i++){
		for(int j = 1; j <= n; j++) ub[i][j] = inf, lb[i][j] = -inf;
		cin >> x;
		for(int j = 0; j < x; j++){
			cin >> s >> c >> t;
			if(c == "<=") ub[i][s] = min(ub[i][s], t);
			else lb[i][s] = max(lb[i][s], t);
		}
	}
	
	for(int i = 1; i <= m; i++){
		for(int j = 1; j <= n; j++){
			if(ub[i][j] < lb[i][j]){
				cout << "No" << endl;
				return 0;
			}
		}
	}
	for(int i = 1; i <= m; i++){
		for(int j = 1; j <= m; j++){
			for(int k = 1; k <= n; k++){
				if(ub[i][k] < lb[j][k]){
					G[i].push_back(j);
					break;
				}
			}
		}
	}
	
	
	for(int i = 1; i <= m; i++) if(!used[i]) tpsort(i);
	reverse(topo.begin(), topo.end());
	
	for(int i = 1; i <= m; i++) used[i] = false;
	for(int i = 0; i < topo.size(); i++){
		int v = topo[i];
		used[v] = true;
		for(int j = 0; j < G[v].size(); j++){
			if(used[G[v][j]]){
				cout << "No" << endl;
				return 0;
			}
		}
	}
	cout << "Yes" << endl;
	
	return 0;
}
