/* ‰ï’ÑåŠw F */ #include #include #include #include using namespace std; #define NROAD_MAX 200 #define NCROSSING_MAX 1000 #define NIL (-1) #define HOR 0 #define VER 1 int nroad; // greaterG[i][j] => i > j bool greaterG[NROAD_MAX][NROAD_MAX]; // lessG[i][j] => i < j bool lessG[NROAD_MAX][NROAD_MAX]; bool greaterGIN[NROAD_MAX][NROAD_MAX]; bool lessGIN[NROAD_MAX][NROAD_MAX]; bool equalG[NROAD_MAX][NROAD_MAX]; bool ADJ[NROAD_MAX][NROAD_MAX]; int COLOR[NROAD_MAX]; int DIRECTION[NROAD_MAX]; bool greaterT[NROAD_MAX][NROAD_MAX]; bool lessT[NROAD_MAX][NROAD_MAX]; bool visited[NROAD_MAX]; void dfsGreater( int curr ) { visited[curr] = true; for ( int i = 0; i < nroad; i++ ) if ( !visited[i] && (equalG[curr][i] || lessG[curr][i]) ) dfsGreater(i); } bool compute( int left, int right ) { if ( DIRECTION[left] == DIRECTION[right] ) return false; if ( COLOR[left] != COLOR[right] ) return false; for ( int i = 0; i < nroad; i++ ) visited[i] = false; dfsGreater(right); return visited[left]; } void dfsDirection( int curr, int direction ) { DIRECTION[curr] = direction; for ( int i = 0; i < nroad; i++ ) if ( ADJ[curr][i] && DIRECTION[i] == NIL ) dfsDirection(i, (direction == HOR)? VER : HOR); else if ( ADJ[curr][i] && DIRECTION[i] == direction ) assert( false ); } void dfsColor( int curr, int color ) { COLOR[curr] = color; for ( int i = 0; i < nroad; i++ ) if ( ADJ[curr][i] && COLOR[i] == NIL ) dfsColor(i, color); } int getNodeID( map &M, const string &name ) { if ( M.find(name) != M.end() ) return M[name]; const int id = M.size(); M[name] = id; return id; } int main() { while ( true ) { int ncrossing; cin >> ncrossing; if ( ncrossing == 0 ) break; map name2node; for ( int i = 0; i < NROAD_MAX; i++ ) for ( int j = 0; j < NROAD_MAX; j++ ) ADJ[i][j] = lessG[i][j] = greaterG[i][j] = false; for ( int i = 0; i < NROAD_MAX; i++ ) for ( int j = 0; j < NROAD_MAX; j++ ) lessGIN[i][j] = greaterGIN[i][j] = false; for ( int i = 0; i < ncrossing; i++ ) { string name; cin >> name; const int p = name.find('-'); const string left = name.substr(0, p); const string right = name.substr(p+1); const int leftID = getNodeID(name2node, left); const int rightID = getNodeID(name2node, right); ADJ[leftID][rightID] = true; ADJ[rightID][leftID] = true; greaterGIN[leftID][rightID] = true; lessG[rightID][leftID] = true; greaterG[leftID][rightID] = true; } nroad = name2node.size(); for ( int i = 0; i < nroad; i++ ) COLOR[i] = NIL; int color = 0; for ( int i = 0; i < nroad; i++ ) if ( COLOR[i] == NIL ) dfsColor(i, color++); for ( int i = 0; i < nroad; i++ ) DIRECTION[i] = NIL; for ( int i = 0; i < nroad; i++ ) if ( DIRECTION[i] == NIL ) dfsDirection(i, HOR); for ( int i = 0; i < nroad; i++ ) for ( int j = 0; j < nroad; j++ ) { equalG[i][j] = false; for ( int k = 0; k < nroad; k++ ) if ( i != k && j != k && i != j && ADJ[i][k] && ADJ[k][j] ) equalG[i][j] = true; if ( !equalG[i][j] ) continue; for ( int k = 0; k < nroad && equalG[i][j]; k++ ) { if ( i == k || j == k || i == j ) continue; if ( lessG[i][k] && lessG[k][j] ) equalG[i][j] = false; if ( greaterG[i][k] && greaterG[k][j] ) equalG[i][j] = false; } } assert( nroad <= NROAD_MAX ); cout << nroad << endl; int nquery; cin >> nquery; for ( int i = 0; i < nquery; i++ ) { string name; cin >> name; const int p = name.find('-'); string left = name.substr(0, p); string right = name.substr(p+1); if ( name2node.find(left) == name2node.end() || name2node.find(right) == name2node.end() ) { cout << "NO" << endl; continue; } if ( compute(getNodeID(name2node, left), getNodeID(name2node, right)) ) cout << "YES" << endl; else cout << "NO" << endl; } } return 0; }