#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<P, P> PP;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main() {
	int n;
	while(cin >> n && n) {

		vector<PP> v(n);
		map<P, int> id;
		rep(i, n) {
			int x, y;
			char dir;
			cin >> x >> y >> dir;
		
			id[mp(x, y)] = i;
			v[i].first = mp(x, y);

			if(dir == 'x') {
				id[mp(x+1, y)] = i;
				v[i].second = mp(x+1, y);
			} else {
				id[mp(x, y+1)] = i;
				v[i].second = mp(x, y+1);
			}
		}

		map<P, bool> head, foot;
		int inQ[200005];
		memset(inQ, 0, sizeof(inQ));

		bool used[200005];
		memset(used, 0, sizeof(used));

		bool res = false;

		rep(i, n) {
			if(used[i]) continue;

			queue<PP> que;
			que.push(v[i]);
			inQ[i] = true;

			while(que.size()) {
				PP p = que.front(); que.pop();
				int pid = id[p.first];
				inQ[pid] = false;

				bool flag = false;
				rep(j, 4) {
					int ny = p.first.first + dy[j];
					int nx = p.first.second + dx[j];

					flag |= foot[mp(ny, nx)];
				}

				rep(j, 4) {
					int ny = p.second.first + dy[j];
					int nx = p.second.second + dx[j];

					flag |= head[mp(ny, nx)];
				}

				if(!flag) {
					used[pid] = true;
					head[p.first] = true;
					foot[p.second] = true;

					rep(j, 4) {
						int ny = p.first.first + dy[j];
						int nx = p.first.second + dx[j];
						P np = mp(ny, nx);
						int nj = id[mp(ny, nx)];

						rep(k, 4) {
							int nny = ny + dy[k];
							int nnx = nx + dx[k];
							P nnp = mp(nny, nnx);
							int nk = id[mp(nny, nnx)];

							if(nj == nk && !used[nj] && !inQ[nj]) {
								inQ[nj] = true;
								que.push(mp(np, nnp));
							}
						}
					}

					rep(j, 4) {
						int ny = p.second.first + dy[j];
						int nx = p.second.second + dx[j];
						P np = mp(ny, nx);
						int nj = id[mp(ny, nx)];

						rep(k, 4) {
							int nny = ny + dy[k];
							int nnx = nx + dx[k];
							P nnp = mp(nny, nnx);
							int nk = id[mp(nny, nnx)];

							if(nj == nk && !used[nj] && !inQ[nj]) {
								inQ[nj] = true;
								que.push(mp(np, nnp));
							}
						}
					}

					continue;
				}

				flag = false;
				rep(j, 4) {
					int ny = p.second.first + dy[j];
					int nx = p.second.second + dx[j];

					flag |= foot[mp(ny, nx)];
				}

				rep(j, 4) {
					int ny = p.first.first + dy[j];
					int nx = p.first.second + dx[j];

					flag |= head[mp(ny, nx)];
				}

				if(!flag) {
					used[pid] = true;
					head[p.second] = true;
					foot[p.first] = true;

					rep(j, 4) {
						int ny = p.first.first + dy[j];
						int nx = p.first.second + dx[j];
						P np = mp(ny, nx);
						int nj = id[mp(ny, nx)];

						rep(k, 4) {
							int nny = ny + dy[k];
							int nnx = nx + dx[k];
							P nnp = mp(nny, nnx);
							int nk = id[mp(nny, nnx)];

							if(nj == nk && !used[nj] && !inQ[nj]) {
								inQ[nj] = true;
								que.push(mp(np, nnp));
							}
						}
					}

					rep(j, 4) {
						int ny = p.second.first + dy[j];
						int nx = p.second.second + dx[j];
						P np = mp(ny, nx);
						int nj = id[mp(ny, nx)];

						rep(k, 4) {
							int nny = ny + dy[k];
							int nnx = nx + dx[k];
							P nnp = mp(nny, nnx);
							int nk = id[mp(nny, nnx)];

							if(nj == nk && !used[nj] && !inQ[nj]) {
								inQ[nj] = true;
								que.push(mp(np, nnp));
							}
						}
					}
					continue;
				}

				res = true;
				break;
			}
		}

		if(res) cout << "No" << endl;
		else cout << "Yes" << endl;

	}

	return 0;
}

Measured memory_bytes: 35312