#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); i++)
//#define int long long
#define FOR(i, m, n) for (int i = (m); i < (n); i++)
#define all(x) x.begin(), x.end()
using pii = pair<int, int>;
using ll = long long;

int t = 0;

struct Futon {
    int X[2], Y[2];
    int id;
    Futon(int x, int y, char c, int id) : id(id) {
        X[0] = X[1] = x, Y[0] = Y[1] = y;
        if (c == 'x')
            X[1] = x + 1;
        else
            Y[1] = y + 1;
    }
    bool operator<(const Futon &rhs) {
        if (X[0] == rhs.X[0]) return Y[0] < rhs.Y[0];
        return X[0] < rhs.X[0];
    }
    void show() { cerr << X[0] << " " << Y[0] << " " << X[1] << " " << Y[1] << endl; }
    pii p1() { return {X[0], Y[0]}; }
    pii p2() { return {X[1], Y[1]}; }
};

constexpr int dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0};
bool connect(Futon &a, Futon &b) {
    REP(i, 2) REP(j, 2) REP(k, 4) {
        if (a.X[i] + dx[k] == b.X[j] && a.Y[i] + dy[k] == b.Y[j]) return true;
    }
    return false;
}

vector<int> G[100010];

bool solve() {
    t++;
    set<pii> stX, stY;
    int N;
    cin >> N;
    if (N == 0) return false;
    vector<Futon> fs;
    REP(i, N) {
        int x, y;
        char c;
        cin >> x >> y >> c;
        Futon f(x, y, c, i);
        fs.push_back(f);
        G[i].clear();
    }
    sort(all(fs));
    REP(i, N) {
        FOR(j, i + 1, N) {
            if (fs[j].X[0] > fs[i].X[0] + 2) break;
            if (connect(fs[i], fs[j])) {
                // fs[i].show();
                // fs[j].show();
                // cerr << endl;
                G[i].push_back(j);
                G[j].push_back(i);
            }
        }
    }
    map<pii, int> mp;
    vector<bool> done(N);
    bool possible = true;
    queue<int> que;
    REP(i, N) {
        if (!possible) break;
        if (done[i]) continue;

        que.push(i);
        while (!que.empty()) {
            if (!possible) break;
            int id = que.front();
            que.pop();
            if (done[id]) continue;
            done[id] = true;
            bool found1 = false, found2 = false;
            int x0 = fs[id].X[0], y0 = fs[id].Y[0];
            REP(k, 4) {
                if (!mp.count({x0 + dx[k], y0 + dy[k]})) continue;
                if (mp[{x0 + dx[k], y0 + dy[k]}] == 1) found1 = true;
                if (mp[{x0 + dx[k], y0 + dy[k]}] == 2) found2 = true;
            }
            if (found1 && found2) possible = false;
            int x1 = fs[id].X[1], y1 = fs[id].Y[1];
            bool found11 = false, found22 = false;
            REP(k, 4) {
                if (!mp.count({x1 + dx[k], y1 + dy[k]})) continue;
                if (mp[{x1 + dx[k], y1 + dy[k]}] == 1) found11 = true;
                if (mp[{x1 + dx[k], y1 + dy[k]}] == 2) found22 = true;
                if (mp[{x1 + dx[k], y1 + dy[k]}] == 1 && found1) possible = false;
                if (mp[{x1 + dx[k], y1 + dy[k]}] == 2 && found2) possible = false;
            }
            if (found1 && found11) possible = false;
            if (found2 && found22) possible = false;
            if (found11 && found22) possible = false;
            if (found2 || found11) {
                mp[{x0, y0}] = 2;
                mp[{x1, y1}] = 1;
            } else {
                mp[{x0, y0}] = 1;
                mp[{x1, y1}] = 2;
            }

            for (auto nxt : G[id]) {
                que.push(nxt);
            }
        }
    }
    REP(i, N) {
        int x = fs[i].X[0], y = fs[i].Y[0];
        int x1 = fs[i].X[1], y1 = fs[i].Y[1];
        if (!possible) break;
        if (mp[{x, y}] == 1) {
            REP(k, 4) {
                if (x + dx[k] == x1 && y + dy[k] == y1) continue;
                if (mp[{x + dx[k], y + dy[k]}] == 2) possible = false;
            }
        } else if (mp[{x, y}] == 2) {
            REP(k, 4) {
                if (x + dx[k] == x1 && y + dy[k] == y1) continue;
                if (mp[{x + dx[k], y + dy[k]}] == 1) possible = false;
            }
        } else {
            cerr << "not decided!!!!" << endl;
        }
    }
    if (possible)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return true;
}

signed main() {
    while (solve())
        ;
}


Measured memory_bytes: 12412