#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
#define int long long int
const int INF = 1001001001001001LL;
const int MOD = 1000000007;

int di[4] = {0, 1, 0, -1};
int dj[4] = {1, 0, -1, 0};

bool dfs(int cur, vector<vector<pair<int, int>>> &g, vector<int> &color, int c){
    
    color[cur] = c;
    //cout << cur << " " << c << endl;
    for(int i = 0; i < g[cur].size(); i++){
        int nxt = g[cur][i].first;
        int val = g[cur][i].second;
        

        // 違う色にしなきゃ
        if(val == 1){
            int nxtc = 1;
            if(c == 1) nxtc = 2;
            if(color[nxt] == 0){
                if(!dfs(nxt, g, color, nxtc)) return false;
            }else if(color[nxt] != nxtc) return false;
        }else{
            int nxtc = 1;
            if(c == 2) nxtc = 2;
            if(color[nxt] == 0){
                if(!dfs(nxt, g, color, nxtc)) return false;
            }else if(color[nxt] != nxtc) return false;
        }
    }
    return true;  
}

signed main(){
    
    while(1){
        int n; cin >> n;
        if(!n) break;
        vector<int> x(n);
        vector<int> y(n);
        vector<char> dir(n);
        map<pair<int, int>, int> toNode;
        int V = 0;
        vector<vector<pair<int, int>>> g(2 * n);
        for(int i = 0; i < n; i++){
            cin >> x[i] >> y[i] >> dir[i];
            pair<int, int> u = {x[i], y[i]};
            pair<int, int> v = u;
            if(dir[i] == 'x') v.first++;
            else v.second++;
            int from = V;
            toNode[u] = V;
            V++;
            int to = V;
            toNode[v] = V;
            V++;
            g[from].push_back({to, 1});
            g[to].push_back({from, 1});
        }
        
        for(auto itr : toNode){
            pair<int, int> cur = itr.first;
            int curNode = itr.second;
            for(int h = 0; h < 4; h++){
                pair<int, int> nxt = cur;
                nxt.first += di[h];
                nxt.second += dj[h];
                if(toNode.find(nxt) != toNode.end()){
                    int nxtNode = toNode[nxt];
                    // 1 が既にあれば continue
                    bool flag = true;
                    for(int j = 0; j < g[curNode].size(); j++){
                        if(g[curNode][j].first == nxtNode && g[curNode][j].second == 1) flag = false;
                    }
                    if(flag) g[curNode].push_back({nxtNode, 2});
                }
            }
        }
        
        // グラフの判定
        assert(V = 2 * n);
        // 0 := 未決定
        // 1 := しろ
        // 2 := くろ

        /*
        cout << "gruph" << endl;
        for(int i = 0; i < V; i++){
            for(int j = 0; j < (int)g[i].size(); j++){
                cout << i << " " << g[i][j].first << " " << g[i][j].second << endl;
            }
        }
        */

        string ans = "Yes";
        vector<int> color(V, 0);
        for(int i = 0; i < V; i++){
            if(color[i] == 0){
                if(!dfs(i, g, color, 1)){
                    ans = "No";
                    break;
                }
            }
        }

        cout << ans << endl;
    }

    return 0;
}



Measured memory_bytes: 11548