#include #define REP(A,B) for(int (A)=0;(A)<(B);(A)++) using namespace std; #define ll long long #define pb push_back char str[5]; typedef vector VI; typedef vector VVI; bool FindMatch(int i, const VVI& w, VI&mr, VI&mc, VI& seen) { REP(j, w[i].size()) { if(w[i][j]&&!seen[j]) { seen[j]=true; if(mc[j]<0 || FindMatch(mc[j], w, mr, mc, seen)) { mr[i]=j; mc[j]=i; return true; } } } return false; } int BipartiteMatching(const VVI &w, VI& mr, VI&mc) { mr = VI(w.size(), -1); mc = VI(w[0].size(), -1); int ct = 0; REP(i, w.size()) { VI seen(w[0].size()); if(FindMatch(i, w, mr, mc, seen)) ct++; } return ct; } int main() { int n; while(scanf("%d", &n)==1) { vector cards; REP(i, n) { scanf("%s", str); cards.pb(string(str)); // printf("%s ", cards.back().c_str()); } vector> Graph; REP(i, 2*n) { Graph.pb(vector()); REP(j, 2*n) Graph[i].pb(0); } REP(i, n) REP(j, n) { if(i != j) { bool yes = false; if(cards[i][0]==cards[j][0]) { Graph[2*i+1][2*j] = Graph[2*j][2*i+1] = 1; yes = true; } else if(cards[i][1]==cards[j][1]) { Graph[2*i+1][2*j] = Graph[2*j][2*i+1] = 1; yes = true; } // if(yes) printf("edge from %d to %d (%d %d)\n", i, j, 2*i+1, j); } } VI RM, CM; int M = BipartiteMatching(Graph, RM, CM); // printf("%d\n", M); printf("%s\n", M >= 2*(n-1) ? "YES" : "NO"); } return 0; }