#include #include #include #include #include #include #include #include #include using namespace std; typedef int length; typedef map edgeset; typedef map graph; #define NOT_CONN 65536 class ToIntR { map mp; int id; vector rmp; public: ToIntR() : id(0) {} int operator[] (const string& t) { if(mp.count(t)) return mp[t]; rmp.push_back(t); return mp[t] = id++; } const string& id2value(int i) { return rmp[i]; } int size() const { return id; } }; template bool reachable(map >& m, const T& a, const T& b) { return m.count(a) && m[a].count(b); } int count_vert(graph& g, ToIntR& vtmap) { for(graph::const_iterator iter = g.begin(); iter != g.end(); ++iter){ vtmap[iter->first]; const edgeset& es = iter->second; for(edgeset::const_iterator it2 = es.begin(); it2 != es.end(); ++it2){ vtmap[it2->first]; } } return vtmap.size(); } map > WarshallFloyd(graph& g, ToIntR& vtmap) { int n = count_vert(g, vtmap); vector< vector > D(n, vector(n, NOT_CONN)); for(graph::const_iterator iter = g.begin(); iter != g.end(); ++iter){ const int v = vtmap[iter->first]; D[v][v] = 0; edgeset es = iter->second; for(edgeset::iterator i = es.begin(); i != es.end(); ++i) if(vtmap[i->first] != v) // avoid self loop D[v][vtmap[i->first]] = i->second; } for(int k = 0; k < n; ++k) for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) D[i][j] = min(D[i][j], D[i][k] + D[k][j]); map< string, map > result; for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) if(D[i][j] < NOT_CONN) result[vtmap.id2value(i)][vtmap.id2value(j)] = D[i][j]; return result; } pair parse(const string& s) { unsigned idx = s.find('-'); return make_pair(s.substr(0, idx), s.substr(idx + 1)); } bool solve(const pair& road, map >& dist) { if(reachable(dist, road.second, road.first)){ int len = dist[road.second][road.first]; //cout << "reachable len=" << len << endl; return len & 1; }else{ //cout << "not reachable" << endl; return false; } } int main() { int N, M; while(cin >> N, N){ string str; map dmap; int dmax = 0; graph g, gr; getline(cin, str); for(int i = 0; i < N; ++i){ getline(cin, str); pair road = parse(str); g[road.second][road.first] = 1; gr[road.first][road.second] = 1; } ToIntR vtmap; map > dist = WarshallFloyd(g, vtmap); // same order graph rg = g; for(graph::iterator it = g.begin(); it != g.end(); ++it){ edgeset& es = it->second; for(edgeset::iterator i1 = es.begin(); i1 != es.end(); ++i1){ edgeset::iterator i2 = i1; for(++i2; i2 != es.end(); ++i2){ //assert(it->first != i1->first && it->first != i2->first); if(!reachable(g, i1->first, i2->first) && !reachable(g, i2->first, i1->first)){ if(!reachable(dist, i1->first, i2->first) && !reachable(dist, i2->first, i1->first)){ rg[i1->first][i2->first] = 2; rg[i2->first][i1->first] = 2; } } } } } // same order 2 for(graph::iterator it = gr.begin(); it != gr.end(); ++it){ edgeset& es = it->second; for(edgeset::iterator i1 = es.begin(); i1 != es.end(); ++i1){ edgeset::iterator i2 = i1; for(++i2; i2 != es.end(); ++i2){ //assert(it->first != i1->first && it->first != i2->first); if(!reachable(gr, i1->first, i2->first) && !reachable(gr, i2->first, i1->first)){ if(!reachable(dist, i1->first, i2->first) && !reachable(dist, i2->first, i1->first)){ rg[i1->first][i2->first] = 2; rg[i2->first][i1->first] = 2; } } } } } dist = WarshallFloyd(rg, vtmap); cin >> M; getline(cin, str); cout << vtmap.size() << endl; for(int i = 0; i < M; ++i){ getline(cin, str); cout << (solve(parse(str), dist) ? "YES" : "NO") << endl; } } }