Problem:
Problem F:
Name the Crossing
The city of Kyoto is well-known for its Chinese plan: streets are
either North-South or East-West. Some streets are numbered, but most
of them have real names.
Crossings are named after the two streets crossing there,
e.g. Kawaramachi-Sanjo is the crossing of Kawaramachi street and Sanjo
street. But there is a problem: which name should come first?
At first the order seems quite arbitrary: one says Kawaramachi-Sanjo
(North-South first) but Shijo-Kawaramachi (East-West first). With some
experience, one realizes that actually there
seems to be an "order" on the streets, for instance in the above
Shijo is "stronger" than Kawaramachi, which in turn is "stronger" than
Sanjo.
One can use this order to deduce the names of other crossings.
You are given as input a list of known crossing names X-Y.
Streets are either North-South or East-West, and only orthogonal streets
may cross.
As your list is very incomplete, you start by completing it using
the following rule:
two streets A and B have
equal strength
if (1) to (3) are
  all true:
they both cross the same third street C in the input
there is no street D such that D-A and B-D appear in the input
there is no street E such that A-E and E-B appear in the input
We use this definition to extend our strength relation:
A is
stronger
than B, when there is a
  sequence A = A
1
, A
2
, ..., A
n
= B,
  with
n
at least 2,
where, for any
i
in 1 ..
n
-1, either
  A
i
-A
i
+1
is an input crossing or
  A
i
and A
i
+1
have equal strength.
Then you are asked whether some other possible crossing names X-Y are
valid. You should answer affirmatively if you can infer the validity of a
name, negatively if you cannot. Concretely:
YES    if you can infer that the two streets are orthogonal, and X
         is stronger than Y
NO     otherwise
Input
The input is a sequence of data sets, each of the form
N
Crossing
1
...
Crossing
N
M
Question
1
...
Question
M
Both
Crossing
s and
Question
s are of the form
X-Y
where
X
and
Y
are strings of alphanumerical characters,
of lengths no more than 16. There is no white space, and case matters
for alphabetical characters.
N
and
M
are between 1 and 1000 inclusive, and there are
no more than 200 streets in a data set.
The last data set is followed by a line containing a zero.
Output
The output for each data set should be composed of
M
+1 lines,
the first one containing the number of streets
in the
Crossing
part of the input, followed by the answers to
each question, either YES or NO without any spaces.
Sample Input
7
Shijo-Kawaramachi
Karasuma-Imadegawa
Kawaramachi-Imadegawa
Nishioji-Shijo
Karasuma-Gojo
Torimaru-Rokujo
Rokujo-Karasuma
6
Shijo-Karasuma
Imadegawa-Nishioji
Nishioji-Gojo
Shijo-Torimaru
Torimaru-Gojo
Shijo-Kawabata
4
1jo-Midosuji
Midosuji-2jo
2jo-Omotesando
Omotesando-1jo
4
Midosuji-1jo
1jo-Midosuji
Midosuji-Omotesando
1jo-1jo
0
Output for the Sample Input
8
YES
NO
YES
NO
YES
NO
4
YES
YES
NO
NO

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define sz(A) (ll)(A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
int main(){
    while(1){
        ll N;cin>>N;
        if(!N)return 0;
        map<string,ll>memo;
        vector<pi>es;
        ll cnt=0;
        while(N--){
            string S;cin>>S;
            ll t=find(ALL(S),'-')-S.begin();
            string X=S.substr(0,t),Y=S.substr(t+1,sz(S)-t-1);
            if(memo.find(X)==memo.end())memo[X]=cnt++;
            if(memo.find(Y)==memo.end())memo[Y]=cnt++;
            es.emplace_back(pi(memo[X],memo[Y]));
        }
        vector<vector<bool>>E(cnt,vector<bool>(cnt));
        for(auto[u,v]:es)E[u][v]=1;
        vector<vector<ll>>R(cnt,vector<ll>(cnt,1e18));
        for(auto[u,v]:es)R[u][v]=1;
        vector<vector<bool>>same(cnt,vector<bool>(cnt));
        REP(i,cnt)REP(j,cnt){
            bool ok=0;
            REP(k,cnt)if((E[i][k]&&E[j][k])||(E[k][i]&E[k][j]))ok=1;
            if(!ok)continue;
            REP(k,cnt)if(E[k][i]&&E[j][k])ok=0;
            REP(k,cnt)if(E[i][k]&&E[k][j])ok=0;
            if(ok)R[i][j]=0;
        }
        REP(i,cnt)REP(j,cnt)REP(k,cnt)R[j][k]=min(R[j][k],R[j][i]+R[i][k]);
        ll M;cin>>M;
        cout<<cnt<<endl;
        while(M--){
            string S;cin>>S;
            ll t=find(ALL(S),'-')-S.begin();
            string X=S.substr(0,t),Y=S.substr(t+1,sz(S)-t-1);
            if(memo.find(X)==memo.end()||memo.find(Y)==memo.end())cout<<"NO"<<endl;
            else{
                ll u=memo[X],v=memo[Y];
                if(R[u][v]>1e17)cout<<"NO"<<endl;
                else if(R[u][v]%2)cout<<"YES"<<endl;
                else cout<<"NO"<<endl;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3388
final_rank: 6

code_snippet: #include<iostream>
#include<map>
#include<cstring>
using namespace std;
const int maxn=256;
map<string,int>mp;
int mp_cnt;
int edge[maxn][maxn];
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        memset(edge,0x3e,sizeof edge);
        mp.clear();
        mp_cnt=0;
        for(int i=1;i<=n;++i)
        {
            string a,b;
            cin>>a;
            b=a.substr(a.find('-')+1,a.length()-a.find('-')-1);
            a=a.substr(0,a.find('-'));
            //cout<<a<<" "<<b<<endl;
            if(mp.find(a)==mp.end())
                mp[a]=++mp_cnt;
            if(mp.find(b)==mp.end())
                mp[b]=++mp_cnt;
            edge[mp[a]][mp[b]]=1;
        }

        for(int i=1;i<=mp_cnt;++i)
        {
            for(int j=i+1;j<=mp_cnt;++j)
            {
                int flag=false;
                for(int k=1;k<=mp_cnt;++k)
                {
                    if(k==i||k==j)continue;
                    if((edge[i][k]==1&&edge[k][j]==1)
                    ||(edge[j][k]==1&&edge[k][i]==1))
                    {
                        flag=false;
                        break;
                    }
                    if((edge[i][k]==1&&edge[j][k]==1)
                    ||(edge[k][i]==1&&edge[k][j]==1))
                        flag=true;
                }
                if(flag)
                {
                    edge[i][j]=2;
                    edge[j][i]=2;
                }
            }
        }

        for(int k=1;k<=mp_cnt;++k)
            for(int i=1;i<=mp_cnt;++i)
            {
                if(i==k)continue;
                for(int j=1;j<=mp_cnt;++j)
                    edge[i][j]=min(edge[i][j],edge[i][k]+edge[k][j]);
            }
        /*for(int i=1;i<=mp_cnt;++i)
        {
            for(int j=1;j<=mp_cnt;++j)
                printf("%3d",edge[i][j]==0x3e3e3e3e?88:edge[i][j]);
            printf("\n");
        }*/
        printf("%d\n",mp_cnt);
        int m;
        scanf("%d",&m);
        for(int i=1;i<=m;++i)
        {
            string a,b;
            cin>>a;
            b=a.substr(a.find('-')+1,a.length()-a.find('-')-1);
            a=a.substr(0,a.find('-'));
            if(edge[mp[a]][mp[b]]%2==1)
                printf("YES\n");
            else printf("NO\n");
            //cout<<mp.find(a)->first<<" "<<mp.find(a)->second<<endl;
            //cout<<mp.find(b)->first<<" "<<mp.find(b)->second<<endl;
        }
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3640
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define fir first
#define sec second
//#define int long long
#define inf 0x3f
using namespace std;
int n,m;
int p = 0;
int d[210][210];
signed main(){
#ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif
    while(cin>>n && n){
        memset(d,inf,sizeof(d));
        p = 0;
        int mx = d[0][0];
        map<string,int> mp;
        string s;
        for(int i = 0;i<n;i++){
            cin>>s;
            int tmp;
            int sn = s.size();
            for(int j = 0;j<sn;j++){
                if(s[j] == '-'){
                    tmp = j;
                    break;
                }
            }
            string s0 = s.substr(0,tmp);
            string s1 = s.substr(tmp+1);
            int t0,t1;
            if(mp.find(s0) == mp.end()){
                t0 = p;
                mp[s0] = p++;
            }else{
                t0 = mp[s0];
            }
            if(mp.find(s1) == mp.end()){
                t1 = p;
                mp[s1] = p++;
            }else{
                t1 = mp[s1];
            }
            d[t0][t1] = 1;
        }
        for(int i = 0;i<p;i++){
            d[i][i] = 0;
        }
        for(int i = 0;i<p;i++){
            for(int j = i+1;j<p;j++){
                 bool fg = false;
                 for(int k = 0;k<p;k++){
                     if(d[k][i] == 1 && d[j][k] == 1){
                         fg = false;
                         break;
                     }
                     if(d[i][k] == 1 && d[k][j] == 1){
                         fg = false;
                         break;
                     }
                     if(d[i][k]==1&&d[j][k]==1){
                         fg = true;
                     }
                     if(d[k][j] == 1&& d[k][i] == 1){
                         fg = true;
                     }
                 }
                 if(fg){
                     d[i][j] = 0;
                     d[j][i] = 0;
                 }
            }
        }
        for(int k = 0;k<p;k++){
            for(int i  = 0;i<p;i++){
                for(int j = 0;j<p;j++){
                    if(d[i][j]>d[i][k]+d[k][j]){
                        d[i][j]=d[i][k]+d[k][j];
                    }
                }
            }
        }
        cout<<p<<endl;
        cin>>m;
        for(int i = 0;i<m;i++){
            cin>>s;
            int sn = s.size();
            int tmp;
            for(int j = 0;j<sn;j++){
                if(s[j]=='-'){
                    tmp = j;
                    break;
                }
            }
            string s0 = s.substr(0,tmp);
            string s1 = s.substr(tmp+1);
            int t0,t1;
            if(mp.find(s0) == mp.end() || mp.find(s1) == mp.end()){
                cout<<"NO"<<endl;
                continue;
            }
            t0 = mp[s0];
            t1 = mp[s1];
            if(d[t0][t1] != mx && d[t0][t1]&1){
                cout<<"YES"<<endl;
            }else{
                cout<<"NO"<<endl;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3516
final_rank: 5

code_snippet: #include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <utility>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <deque>
#include <algorithm>
#include <stack>
#include <sstream>
#include <cstdlib>
#include <ctime>
/*-----------------------*/
//#define int long long
#define INF 10000
#define INF2 0x7f7f7f7f
using namespace std;
/*-----------------------*/

map<string,int> mp;

int getID(string s){
    if(mp.find(s) == mp.end()){
        int n = mp.size();
        mp[s]=n;
    }
    return mp[s];
}

int g[200][200];

signed main(){
#ifdef LOCAL
    freopen("input.txt", "r", stdin );
    freopen("output.txt", "w", stdout);
#endif
    int n;
    while(~scanf("%d", &n) && n){
        for(int i  = 0; i<200; i++) for(int j = 0; j<200; j++) g[i][j] = INF;
        mp.clear();
        for(int i=0; i < n; i++){
            string s;
            cin >> s;
            string s1 = s.substr(0, s.find('-'));
            string s2 = s.substr(s.find('-')+1);
            int i1= getID(s1);
            int i2= getID(s2);
            g[i1][i2]=1;
        }
        int m = mp.size();
        cout<<m<<endl;
        for(int i=0;i<m;i++){
            for(int j=0;j<m;j++){
                if(g[i][j] == 1 || g[j][i] == 1) continue;
                //rule1
                bool b=false;
                for(int k=0;k<m;k++){
                    if(k==i||k==j) continue;
                    if((g[i][k] == 1 || g[k][i] == 1) && (g[j][k] == 1 || g[k][j] == 1)){
                        b=true;
                        break;
                    }
                }
                //rule2, 3
                for(int k=0;k<m;k++){
                    if(k==i||k==j) continue;
                    if((g[k][i] == 1 && g[j][k] == 1) || (g[i][k] == 1 && g[k][j] == 1)){
                        b=false;
                        break;
                    }
                }
                if(b) g[i][j] = g[j][i] = 0;
            }
        }
        for(int i=0;i<m;i++) g[i][i]=0;
        for(int k=0;k<m;k++){
            for(int i=0;i<m;i++){
                for(int j=0;j<m;j++){
                    g[i][j]=min(g[i][j], g[i][k] + g[k][j]);
                }
            }
        }
        int q;
        cin >> q;
        for(int i=0; i < q; i++){
            string s;
            cin >> s;
            string s1 = s.substr(0, s.find('-'));
            string s2 = s.substr(s.find('-')+1);
            int i1= getID(s1);
            int i2= getID(s2);
            if(i1>=m || i2>=m || g[i1][i2] % 2 == 0){
                puts("NO");
            }else{
                puts("YES");
            }

        }
    }

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3596
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <map>

using namespace std;
using ll = long long;
using ps = pair<string, string>;
#define dbg(x) cout << #x << " = " << x << endl
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define fi first
#define se second

const int INF = 100100100;
const double ESP = 1e-9;

ps split(string s) {
	auto pos = s.find("-");

	return { s.substr(0, pos), s.substr(pos + 1) };
}

const int N = 201;

int main()
{
	int n, m;

	while (cin >> n) {
		if (!n) break;

		int cnt = 0;
		int d[N][N], C[N][N];
		bool arr[N][N];
		map<string, int> map;

		rep(i,N)rep(j,N) arr[i][j] = false;
		
		rep(i,N)rep(j,N) d[i][j] = INF;
		rep(i, N) d[i][i] = 0;

		rep(i, N)rep(j, N) C[i][j] = INF;
		rep(i, N) C[i][i] = 0;


		rep(i,n) {
			string s;
			cin >> s;
			ps c = split(s);

			if (!map.count(c.fi)) map[c.fi] = cnt++;
			if (!map.count(c.se)) map[c.se] = cnt++;

			int u = map[c.fi], v = map[c.se];

			C[u][v] = 1;
			d[u][v] = d[v][u] = 1;
			arr[u][v] = true;
		}

		cout << cnt << endl;

		rep(k, cnt)rep(i, cnt)rep(j, cnt) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);


		auto same_degree = [&](int a, int b) {
			bool same = false;
			rep(i, cnt) {
				if ((arr[a][i] || arr[i][a]) && (arr[b][i] || arr[i][b])) same = true;
			}
			if (!same) return false;

			rep(i, cnt) {
				if (arr[i][a] && arr[b][i]) return false;
				if (arr[a][i] && arr[i][b]) return false;
			}
			return true;
		};

		rep(i, cnt)rep(j, i) {
			if (same_degree(i, j)) {
				//cout << "DEG :: " << i << " " << j << endl;
				C[i][j] = C[j][i] = 1;
			}
		}


		rep(k, cnt)rep(i, cnt)rep(j, cnt) C[i][j] = min(C[i][j], C[i][k] + C[k][j]);

		cin >> m;
		while (m--) {
			string q;
			cin >> q;

			ps qc = split(q);

			bool ok = false;
			if (map.count(qc.fi) && map.count(qc.se)) {
				int u = map[qc.fi], v = map[qc.se];
				//dbg(C[u][v]);

				if (d[u][v] % 2 == 1 && C[u][v] < INF) ok = true;
			}
			cout << (ok ? "YES" : "NO") << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3532
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <map>

using namespace std;
using ll = long long;
using ps = pair<string, string>;
#define dbg(x) cout << #x << " = " << x << endl
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define fi first
#define se second

const int INF = 100100100;
const double ESP = 1e-9;

ps split(string s) {
	auto pos = s.find("-");

	return { s.substr(0, pos), s.substr(pos + 1) };
}

const int N = 201;

int main()
{
	int n, m;

	while (cin >> n) {
		if (!n) break;

		int cnt = 0;
		int d[N][N], C[N][N];
		bool arr[N][N];
		vector<int> G[N];
		map<string, int> map;

		rep(i,N)rep(j,N) arr[i][j] = false;
		
		rep(i,N)rep(j,N) d[i][j] = INF;
		rep(i, N) d[i][i] = 0;

		rep(i, N)rep(j, N) C[i][j] = INF;
		rep(i, N) C[i][i] = 0;


		rep(i,n) {
			string s;
			cin >> s;
			ps c = split(s);

			if (!map.count(c.fi)) map[c.fi] = cnt++;
			if (!map.count(c.se)) map[c.se] = cnt++;

			int u = map[c.fi], v = map[c.se];

			G[u].push_back(v);
			C[u][v] = 1;
			d[u][v] = d[v][u] = 1;
			arr[u][v] = true;
		}

		cout << cnt << endl;

		rep(k, cnt)rep(i, cnt)rep(j, cnt) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);


		auto same_degree = [&](int a, int b) {
			bool same = false;
			rep(i, cnt) {
				if ((arr[a][i] || arr[i][a]) && (arr[b][i] || arr[i][b])) same = true;
			}
			if (!same) return false;

			rep(i, cnt) {
				if (arr[i][a] && arr[b][i]) return false;
				if (arr[a][i] && arr[i][b]) return false;
			}
			return true;
		};

		rep(i, cnt)rep(j, i) {
			if (same_degree(i, j)) {
				//cout << "DEG :: " << i << " " << j << endl;
				C[i][j] = C[j][i] = 1;
			}
		}


		rep(k, cnt)rep(i, cnt)rep(j, cnt) C[i][j] = min(C[i][j], C[i][k] + C[k][j]);

		cin >> m;
		while (m--) {
			string q;
			cin >> q;

			ps qc = split(q);

			bool ok = false;
			if (map.count(qc.fi) && map.count(qc.se)) {
				int u = map[qc.fi], v = map[qc.se];
				//dbg(C[u][v]);

				if (d[u][v] % 2 == 1 && C[u][v] < INF) ok = true;
			}
			cout << (ok ? "YES" : "NO") << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3556
final_rank: 11

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<map>
#include<vector>
#include<bitset>
#include<queue>
using namespace std;
#line 2 "/home/kotatsugame/library/datastructure/UF.cpp"
struct UF{
	int n;
	vector<int>parent,rank;
	UF(int n_=0):n(n_),parent(n_),rank(n_,1)
	{
		for(int i=0;i<n_;i++)parent[i]=i;
	}
	int find(int a){return parent[a]!=a?parent[a]=find(parent[a]):a;}
	bool same(int a,int b){return find(a)==find(b);}
	bool unite(int a,int b)
	{
		a=find(a),b=find(b);
		if(a==b)return false;
		if(rank[a]<rank[b])
		{
			parent[a]=b;
			rank[b]+=rank[a];
		}
		else
		{
			parent[b]=a;
			rank[a]+=rank[b];
		}
		return true;
	}
	int size(int a){return rank[find(a)];}
};
#line 8 "a.cpp"
int N,M;
map<string,int>id;
int X[1000],Y[1000];
pair<string,string>rd()
{
	string s;cin>>s;
	pair<string,string>ret;
	ret.first="";
	int i=0;
	while(s[i]!='-')ret.first+=s[i++];
	i++;
	ret.second=s.substr(i);
	return ret;
}
bitset<200>R[200],L[200];
main()
{
	while(cin>>N,N)
	{
		id.clear();
		for(int i=0;i<N;i++)
		{
			pair<string,string>p=rd();
			if(id.find(p.first)==id.end())
			{
				int sz=id.size();
				id[p.first]=sz;
			}
			if(id.find(p.second)==id.end())
			{
				int sz=id.size();
				id[p.second]=sz;
			}
			X[i]=id[p.first];
			Y[i]=id[p.second];
		}
		int n=id.size();
		for(int i=0;i<n;i++)R[i]=L[i]=0;
		for(int i=0;i<N;i++)
		{
			R[X[i]][Y[i]]=1;
			L[Y[i]][X[i]]=1;
		}
		UF uf(n);
		for(int i=0;i<n;i++)for(int j=i+1;j<n;j++)
		{
			if((R[i]&L[j]).any()||(L[i]&R[j]).any())continue;
			if((R[i]&R[j]).any()||(L[i]&L[j]).any())uf.unite(i,j);
		}
		vector<int>ps;
		for(int i=0;i<n;i++)if(i==uf.find(i))ps.push_back(i);
		vector<vector<int> >dist(n,vector<int>(n,1e9));
		for(int i=0;i<n;i++)dist[i][i]=0;
		for(int i=0;i<N;i++)
		{
			int u=uf.find(X[i]);
			int v=uf.find(Y[i]);
			dist[u][v]=1;
		}
		for(int k:ps)for(int i:ps)for(int j:ps)dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
		cout<<n<<endl;
		int M;cin>>M;
		for(;M--;)
		{
			pair<string,string>p=rd();
			if(id.find(p.first)==id.end()||id.find(p.second)==id.end())
			{
				cout<<"NO"<<endl;
				continue;
			}
			int u=uf.find(id[p.first]),v=uf.find(id[p.second]);
			int d=dist[u][v];
			if(d%2==1)cout<<"YES"<<endl;
			else cout<<"NO"<<endl;
		}
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3228
final_rank: 1

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-8, PI = acos(-1);
//ここから編集    

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(6);
    
    /* 存在しない地名ならばNO */
    

    int n;
    while(cin >> n, n){
        vector<pair<string, string>> cross;
        map<string, int> mp;
        int cnt = 0;
        vector<vector<int>> graph(210, vector<int>(210, 0));
        REP(i,n){
            string s; cin >> s;
            string t1 = "", t2="";
            int idx = 0;
            while(idx < s.size() && s[idx] != '-'){
                t1 += s[idx]; idx++;
            }
            idx++;
            while(idx < s.size()){
                t2 += s[idx]; idx++;
            }
            cross.push_back({t1, t2});

            if(mp.count(t1) == 0) mp[t1] = cnt++;
            if(mp.count(t2) == 0) mp[t2] = cnt++;

            int v = mp[t1], u = mp[t2];
            graph[v][u] = 1;
        }
        cout << cnt << endl;
        vector<vector<int>> g(cnt);
        REP(i,n){
            int v = mp[cross[i].first], u = mp[cross[i].second];
            g[v].push_back(u);
            g[u].push_back(v);
        }

        vector<vector<int>> dist(cnt, vector<int>(cnt,INT_MAX)); 
        {
            for(int i=0; i<cnt; i++){
                dist[i][i] = 0;
                queue<int> q;
                q.push(i);
                while(q.size()){
                    int v = q.front();
                    q.pop();
                    for(auto u: g[v]){
                        if(dist[i][u] == INT_MAX){
                            dist[i][u] = dist[i][v] + 1;
                            q.push(u);
                        }
                    }
                }
            }
        }

        vector<vector<int>> memo(cnt, vector<int>(cnt,0));
        REP(i,cnt){
            REP(j,cnt){
                bool f1 = true, f2 = false;
                REP(k,cnt){
                    
                    if((graph[i][k] && graph[k][j]) || graph[j][k] && graph[k][i]){
                        f1 = false;
                    }
                    if((graph[i][k] || graph[k][j]) && (graph[j][k] || graph[k][i])){
                        f2 = true;
                    }
                }
                if(f1&&f2){
                    memo[i][j] = 1;
                }
            }
        }
        REP(i,cnt) REP(j,cnt) graph[i][j] |= memo[i][j];
        REP(k,cnt) REP(i,cnt) REP(j,cnt) graph[i][j] |= (graph[i][k] & graph[k][j]);

        int M; cin >> M;
        REP(i,M){
            string s; cin >> s;
            string t1 = "", t2="";
            int idx = 0;
            while(idx < s.size() && s[idx] != '-'){
                t1 += s[idx]; idx++;
            }

            idx++;
            while(idx < s.size()){
                t2 += s[idx]; idx++;
            }

            if(mp.find(t1) == mp.end() || mp.find(t2) == mp.end()){
                cout << "NO" << endl;
            }else{
                if(dist[mp[t1]][mp[t2]] % 2 == 0){
                    cout << "NO" << endl;
                }else{
                    if(graph[mp[t1]][mp[t2]]) cout << "YES" << endl;
                    else cout << "NO" << endl;
                }
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3704
final_rank: 14

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

class UnionFind {
	vector<int>parent;
	vector<int>rank;
public:
	UnionFind(int num) {
		num++;
		parent.resize(num);
		rank.resize(num);
		for (int i = 0; i < num; i++) {
			parent[i] = i;
			rank[i] = 0;
		}
	}
	int Find(int node) {
		if (parent[node] == node)return node;
		else return parent[node] = Find(parent[node]);
	}
	void Unite(int u, int v) {
		u = Find(u);
		v = Find(v);
		if (u == v)return;
		if (rank[u] < rank[v])parent[u] = v;
		else {
			parent[v] = u;
			if (rank[u] == rank[v])rank[u]++;
		}
	}
	bool Check_Same(int u, int v) {
		return Find(u) == Find(v);
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	while (cin >> N, N) {
		map<string, int>mp;
		vector<string>s(N);
		vector<pair<string, string>>vs;
		for (auto &i : s) {
			cin >> i;
			int box = i.find('-');
			string t = i.substr(0, box);
			string u = i.substr(box + 1, i.size() - 1 - box);
			vs.push_back({ t,u });
			mp[t] = mp[u] = 0;
		}
		M = mp.size();
		vector<string>conv;
		for (auto &i : mp) {
			i.second = conv.size();
			conv.push_back(i.first);
		}
		vector<vector<int>>dp(M, vector<int>(M, MOD));
		for (int i = 0; i < M; i++)dp[i][i] = 0;
		for (int i = 0; i < N; i++) {
			dp[mp[vs[i].first]][mp[vs[i].second]] = 1;
		}
		UnionFind uf(M);
		for (int i = 0; i < M; i++) {
			for (int j = 0; j < M; j++) {
				bool flag = true;
				bool ok = false;
				for (int k = 0; k < M; k++) {
					if (dp[i][k] != MOD && dp[k][j] != MOD)flag = false;
					if (dp[j][k] != MOD && dp[k][i] != MOD)flag = false;
					if (dp[i][k] == dp[j][k] && dp[i][k] == 1)ok = true;
					if (dp[k][i] == dp[k][j] && dp[k][i] == 1)ok = true;
				}
				if (ok&&flag) {
					uf.Unite(i, j);
				}
			}
		}
		for (int i = 0; i < M; i++) {
			for (int j = 0; j < M; j++) {
				dp[i][j] = MOD;
			}
			dp[i][i] = 0;
		}
		for (int i = 0; i < vs.size(); i++) {
			int a = uf.Find(mp[vs[i].first]);
			int b = uf.Find(mp[vs[i].second]);
//			cout << a << " edge " << b << endl;
			dp[a][b] = 1;
		}
		for (int k = 0; k < M; k++) {
			for (int i = 0; i < M; i++) {
				for (int j = 0; j < M; j++) {
					dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
				}
			}
		}
		vector<int>parent(M, -1);
		vector<int>dis(M, MOD);
		for (int i = 0; i < M; i++) {
			if (parent[i] != -1)continue;
			parent[i] = i;
			dis[i] = 0;
			queue<int>Q;
			Q.push(i);
			while (!Q.empty()) {
				int cn = Q.front();
				Q.pop();
				for (int j = 0; j < N; j++) {
					if (vs[j].first == conv[cn]) {
						if (dis[mp[vs[j].second]] > dis[cn] + 1) {
							parent[mp[vs[j].second]] = i;
							dis[mp[vs[j].second]] = dis[cn] + 1;
							Q.push(mp[vs[j].second]);
						}
					}
					else if (vs[j].second==conv[cn]) {
						if (dis[mp[vs[j].first]] > dis[cn] + 1) {
							parent[mp[vs[j].first]] = i;
							dis[mp[vs[j].first]] = dis[cn] + 1;
							Q.push(mp[vs[j].first]);
						}
					}
				}
			}
		}
		cout << M << endl;
	//	for (auto i : mp) {
	//		cout << i.first << " " << uf.Find(i.second) << endl;
	//	}
	//	for (int i = 0; i < N; i++) {
	//		for (int j = 0; j < N; j++) {
	//			cout << i << " " << j << " " << dp[i][j] << endl;
	//		}
	//	}
		cin >> K;
		while (K--) {
			string t;
			cin >> t;
			int p = t.find('-');
			string u = t.substr(0, p);
			string v = t.substr(p + 1, t.size() - 1 - p);
			if (mp.find(u) == mp.end() || mp.find(v) == mp.end()) {
				cout << "NO\n";
				continue;
			}
			int a = uf.Find(mp[u]), b = uf.Find(mp[v]);
//			cout << a << " " << b << endl;
//			cout << dp[a][b] << " " << dp[b][a] << endl;
			if (dis[a] % 2 == dis[b] % 2) {
				cout << "NO\n";
				continue;
			}
			if (dp[a][b] == MOD) {
				cout << "NO\n";
				continue;
			}
			cout << "YES\n";
		}
	}
}
accuracy: 1
time_ms: 140
memory_kb: 3524
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
pair<string, string> split(string S){
  int N = S.size();
  for (int i = 0; i < N; i++){
    if (S[i] == '-'){
      return make_pair(S.substr(0, i), S.substr(i + 1));
    }
  }
}
int main(){
  while (1){
    int N;
    cin >> N;
    if (N == 0){
      break;
    }
    vector<string> A(N), B(N);
    for (int i = 0; i < N; i++){
      string S;
      cin >> S;
      tie(A[i], B[i]) = split(S);
    }
    map<string, int> mp;
    for (int i = 0; i < N; i++){
      if (!mp.count(A[i])){
        int id = mp.size();
        mp[A[i]] = id;
      }
      if (!mp.count(B[i])){
        int id = mp.size();
        mp[B[i]] = id;
      }
    }
    int V = mp.size();
    cout << V << endl;
    vector<int> a(N), b(N);
    for (int i = 0; i < N; i++){
      a[i] = mp[A[i]];
      b[i] = mp[B[i]];
    }
    vector<vector<int>> E1(V);
    for (int i = 0; i < N; i++){
      E1[a[i]].push_back(b[i]);
      E1[b[i]].push_back(a[i]);
    }
    vector<int> c(V, -1);
    int cnt = 0;
    for (int i = 0; i < V; i++){
      if (c[i] == -1){
        c[i] = cnt;
        queue<int> Q;
        Q.push(i);
        while (!Q.empty()){
          int v = Q.front();
          Q.pop();
          for (int w : E1[v]){
            if (c[w] == -1){
              c[w] = c[v] ^ 1;
              Q.push(w);
            }
          }
        }
        cnt += 2;
      }
    }
    vector<vector<bool>> E2(V, vector<bool>(V, false));
    for (int i = 0; i < N; i++){
      E2[a[i]][b[i]] = true;
    }
    vector<vector<bool>> same(V, vector<bool>(V, false));
    for (int i = 0; i < V; i++){
      for (int j = 0; j < V; j++){
        bool ok1 = false, ok2 = true;
        for (int k = 0; k < V; k++){
          if (E2[i][k] && E2[j][k] || E2[k][i] && E2[k][j]){
            ok1 = true;
          }
          if (E2[i][k] && E2[k][j] || E2[k][i] && E2[j][k]){
            ok2 = false;
          }
        }
        if (ok1 && ok2){
          same[i][j] = true;
        }
      }
    }
    for (int i = 0; i < V; i++){
      for (int j = 0; j < V; j++){
        if (same[i][j]){
          E2[i][j] = true;
        }
      }
    }
    for (int i = 0; i < V; i++){
      for (int j = 0; j < V; j++){
        for (int k = 0; k < V; k++){
          if (E2[j][i] && E2[i][k]){
            E2[j][k] = true;
          }
        }
      }
    }
    int M;
    cin >> M;
    for (int i = 0; i < M; i++){
      string S;
      cin >> S;
      pair<string, string> P = split(S);
      if (!mp.count(P.first)){
        cout << "NO" << endl;
      } else if (!mp.count(P.second)){
        cout << "NO" << endl;
      } else {
        int x = mp[P.first];
        int y = mp[P.second];
        if ((c[x] ^ c[y]) == 1 && E2[x][y]){
          cout << "YES" << endl;
        } else {
          cout << "NO" << endl;
        }
      }
    }
  }
}
accuracy: 1
time_ms: 90
memory_kb: 3196
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=205,INF=1<<30;

vector<pair<int,int>> G[MAX];
int dis[MAX][MAX];

void DFS(int u,int root){
    for(auto to:G[u]){
        if(dis[to.fi][root]==-1){
            dis[to.fi][root]=dis[u][root]+to.se;
            DFS(to.fi,root);
        }else assert((dis[u][root]+to.se&1)==(dis[to.fi][root]&1));
    }
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        int N;cin>>N;
        if(N==0) break;
        map<string,int> MA;
        int id=0;
        vector<vector<int>> edge(205,vector<int>(205)),equal(205,vector<int>(205));
        for(int i=0;i<N;i++){
            string S;cin>>S;
            for(int j=0;j<si(S);j++){
                if(S[j]=='-'){
                    string X=S.substr(0,j),Y=S.substr(j+1);
                    if(MA.count(X)==0){
                        MA[X]=id;
                        id++;
                    }
                    if(MA.count(Y)==0){
                        MA[Y]=id;
                        id++;
                    }
                    edge[MA[X]][MA[Y]]=1;
                    break;
                }
            }
        }
        cout<<id<<endl;
        
        for(int i=0;i<id;i++){
            for(int j=i+1;j<id;j++){
                bool ok1=false,ok2=true;
                for(int k=0;k<id;k++){
                    if(i==k||j==k) continue;
                    
                    if(edge[i][k]&&edge[j][k]) ok1=true;
                    if(edge[k][i]&&edge[k][j]) ok1=true;
                    
                    if(edge[i][k]&&edge[k][j]) ok2=false;
                    if(edge[k][i]&&edge[j][k]) ok2=false;
                }
                
                if(edge[i][j]||edge[j][i]) ok1=false;
                
                if(ok1&&ok2) equal[i][j]=equal[j][i]=1;
            }
        }
        
        for(int i=0;i<MAX;i++) G[i].clear();
        
        for(int i=0;i<id;i++){
            for(int j=0;j<id;j++){
                if(i==j) continue;
                
                if(edge[i][j]) G[i].push_back(mp(j,1));
                else if(equal[i][j]) G[i].push_back(mp(j,0));
                
                //assert(!(edge[i][j]&&equal[i][j]));
            }
        }
        
        for(int i=0;i<id;i++){
            for(int j=0;j<id;j++) dis[j][i]=-1;
            dis[i][i]=0;
            DFS(i,i);
        }
        
        int M;cin>>M;
        
        for(int i=0;i<M;i++){
            string S;cin>>S;
            for(int j=0;j<si(S);j++){
                if(S[j]=='-'){
                    string X=S.substr(0,j),Y=S.substr(j+1);
                    
                    if(MA.count(X)==0||MA.count(Y)==0||X==Y){
                        cout<<"NO\n";
                        continue;
                    }
                    
                    int d=dis[MA[Y]][MA[X]];
                    if(d>=0&&(d&1)) cout<<"YES\n";
                    else cout<<"NO\n";
                    
                    break;
                }
            }
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3612
final_rank: 4

code_snippet: #include <iostream>
#include <string>
#include <map>
#include <vector>

using namespace std;

int v=0;
map<string,int> nameToVertex;

bool cGraph[202][202];
bool eGraph[202][202];
bool visited[202];

int N,M;

string buf;

void buildE(){
    for(int i=0;i<v;i++){
        for(int j=i+1;j<v;j++){
            bool comm=false,order=false;
            for(int k=0;k<v;k++){
                if (i==k||j==k) continue;
                comm |= (cGraph[i][k]||cGraph[k][i])&&(cGraph[j][k]||cGraph[k][j]);
                order |= (cGraph[i][k]&&cGraph[k][j])||(cGraph[j][k]&&cGraph[k][i]);
            }
            if (comm&&!order) eGraph[i][j]=eGraph[j][i]=true;
        }
    }
}

bool DFS1(int cur,int target,bool d){
    if (cur==target) return d;
    visited[cur]=true;
    for(int i=0;i<v;i++){
        if (visited[i]) continue;
        if ((cGraph[cur][i]||cGraph[i][cur])&&DFS1(i,target,!d)) return true;
    }
    return false;
}

bool DFS2(int cur,int target){
    if (cur==target) return true;
    visited[cur]=true;
    for(int i=0;i<v;i++){
        if (visited[i]) continue;
        if ((cGraph[cur][i]||eGraph[cur][i])&&DFS2(i,target)) return true;
    }
    return false;
}


int main(){

    while(true){
        cin>>N;
        if (!N) break;

        for(int i=0;i<v;i++) 
            for(int j=0;j<v;j++)
                cGraph[i][j]=false,eGraph[i][j]=false;
        
        nameToVertex.clear();
        v=0;

        for(int k=0;k<N;k++) {
            cin>>buf;
            int i=0;
            while(buf[i]!='-') i++;
            auto fst=buf.substr(0,i);
            auto snd=buf.substr(i+1);

            if(!nameToVertex.count(fst)) 
                nameToVertex[fst]=v++;
            

            if(!nameToVertex.count(snd)) 
                nameToVertex[snd]=v++;
            

            auto fstNum=nameToVertex[fst],sndNum=nameToVertex[snd];
            cGraph[fstNum][sndNum]=true;
        }

        buildE();

        cin>>M;
        cout<<v<<endl;

        for(int k=0;k<M;k++) {
            cin>>buf;
            int i=0;
            while(buf[i]!='-') i++;
            auto fst=buf.substr(0,i);
            auto snd=buf.substr(i+1);

            if (!nameToVertex.count(fst)||!nameToVertex.count(snd)){
                puts("NO");
                continue;
            }

            auto fstNum=nameToVertex[fst],sndNum=nameToVertex[snd];
            
            for(int i=0;i<v;i++) visited[i]=false;
            if (!DFS1(fstNum,sndNum,false)){
                puts("NO");
                continue;
            }

            for(int i=0;i<v;i++) visited[i]=false;

            if (DFS2(fstNum,sndNum)) puts("YES");
            else puts("NO");
            
        }

    }

    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3144
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template <typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
  if(a < b) {a = b; return true;}
  return false;
}
template <typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
  if(a > b) {a = b; return true;}
  return false;
}
template<typename T1, typename T2>
ostream& operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for(int i=0;i<((int)(v.size()));++i) {
    if(i) os << " ";
    os << v[i];
  }
  return os;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  while(1) {
    int n;
    cin >> n;
    if (n == 0) break;
    vector<pair<string, string>> v(n);
    for(int i=0;i<(n);++i) {
      string s;
      cin >> s;
      int pos = 0;
      for(int j=0;j<((int)(s.size()));++j) {
        if (s[j] == '-') {
          pos = j;
          break;
        }
      }
      v[i].first = s.substr(0, pos);
      v[i].second = s.substr(pos + 1, (int)(s.size()) - pos - 1);
    }
    map<string, int> mp;
    int id = 0;
    for(int i=0;i<(n);++i) {
      if (mp.find(v[i].first) == mp.end()) {
        mp[v[i].first] = id;
        id++;
      }
      if (mp.find(v[i].second) == mp.end()) {
        mp[v[i].second] = id;
        id++;
      }
    }
    vector<P> cross(n);
    for(int i=0;i<(n);++i) {
      cross[i].first = mp[v[i].first];
      cross[i].second = mp[v[i].second];
    }
    vvi g1(id);
    for(int i=0;i<(n);++i) {
      g1[cross[i].first].push_back(cross[i].second);
    }
    map<P, bool> sel1, sel2;
    for(int i=0;i<(n);++i) {
      for(int j=(i + 1);j<(n);++j) {
        if (cross[i].first == cross[j].first) {
          sel1[{cross[i].second, cross[j].second}] = true;
          sel1[{cross[j].second, cross[i].second}] = true;
        }
        if (cross[i].second == cross[j].second) {
          sel1[{cross[i].first, cross[j].first}] = true;
          sel1[{cross[j].first, cross[i].first}] = true;
        }
        if (cross[i].first == cross[j].second && cross[i].second != cross[j].first) {
          sel2[{cross[i].second, cross[j].first}] = true;
          sel2[{cross[j].first, cross[i].second}] = true;
        }
        if (cross[i].second == cross[j].first && cross[i].first != cross[j].second) {
          sel2[{cross[i].first, cross[j].second}] = true;
          sel2[{cross[j].second, cross[i].first}] = true;
        }
      }
    }
    for(int i=0;i<(n);++i) {
      sel2[{cross[i].first, cross[i].second}] = true;
      sel2[{cross[i].second, cross[i].first}] = true;
    }
    vvi g2(id);
    for(int i=0;i<(id);++i) {
      for(int j=0;j<(id);++j) {
        if (sel1[{i, j}] && !sel2[{i, j}]) {
          g2[i].push_back(j);
        }
      }
    }
    cout << id << endl;
    int m;
    cin >> m;
    for(int i=0;i<(m);++i) {
      string s;
      cin >> s;
      int pos = 0;
      for(int j=0;j<((int)(s.size()));++j) {
        if (s[j] == '-') {
          pos = j;
          break;
        }
      }
      string x = s.substr(0, pos);
      string y = s.substr(pos + 1, (int)(s.size()) - pos - 1);
      if (mp.find(x) == mp.end() || mp.find(y) == mp.end()) {
        cout << "NO" << endl;
        continue;
      }
      int idx = mp[x];
      int idy = mp[y];
      queue<P> que;
      vvi d(2, vi(id, INF));
      d[0][idx] = 0;
      que.push({0, idx});
      while (!que.empty()) {
        int col, now;
        tie(col, now) = que.front();
        que.pop();
        for (auto &nxt: g1[now]) {
          if (d[!col][nxt] > d[col][now] + 1) {
            d[!col][nxt] = d[col][now] + 1;
            que.push({!col, nxt});
          }
        }
        for (auto &nxt: g2[now]) {
          if (d[col][nxt] > d[col][now] + 1) {
            d[col][nxt] = d[col][now] + 1;
            que.push({col, nxt});
          }
        }
      }
      if (d[1][idy] != INF) {
        cout << "YES" << endl;
      } else {
        cout << "NO" << endl;
      }
    }
  }
}
accuracy: 1
time_ms: 50
memory_kb: 6328
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <utility>
using namespace std;
typedef pair<int, int> pii;

void input_crossing(string &a, string &b){
    string in;
    cin >> in;
    int n = in.length();
    for(int i=0; i<n; i++){
        if(in[i] == '-'){
            a = in.substr(0, i);
            b = in.substr(i+1, n-i-1);
            break;
        }
    }
}

int dfs(int curr, int g, vector<vector<pii>> &adj, vector<bool> &used){
    if(used[curr]) return -1;
    used[curr] = true;
    if(curr == g) return 0;
    
    for(auto next: adj[curr]){
        int ret = dfs(next.first, g, adj, used);
        if(ret != -1){
            return ret+next.second;
        }
    }
    return -1;
}

int main(){
    while(1){
        int n;
        cin >> n;
        if(n == 0) break;

        vector<string> a(n),b(n);
        int id=0;
        map<string, int> to_id;
        for(int i=0; i<n; i++){
            input_crossing(a[i], b[i]);
            if(to_id.count(a[i]) == 0){
                to_id[a[i]] = id++;
            }
            if(to_id.count(b[i]) == 0){
                to_id[b[i]] = id++;
            }
        }

        vector<int> aid(n),bid(n);
        int num_st = to_id.size();
        vector<vector<pii>> adj(num_st);
        for(int i=0; i<n; i++){
            aid[i] = to_id[a[i]];
            bid[i] = to_id[b[i]];
            adj[aid[i]].emplace_back(bid[i], 1);
        }
        vector<vector<int>> eq(num_st, vector<int>(num_st, 0));
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                if(aid[i]==aid[j] and eq[bid[i]][bid[j]]==0){
                    eq[bid[i]][bid[j]] = 1;
                }
                if(bid[i]==bid[j] and eq[aid[i]][aid[j]]==0){
                    eq[aid[i]][aid[j]] = 1;
                }
                if(aid[i]==bid[j]){
                    eq[bid[i]][aid[j]] = eq[aid[j]][bid[i]] = -1;
                }
            }
        }
        for(int i=0; i<num_st; i++){
            for(int j=i+1; j<num_st; j++){
                if(eq[i][j] == 1){
                    adj[i].emplace_back(j, 0);
                    adj[j].emplace_back(i, 0);
                }
            }
        }

        int m;
        cin >> m;
        cout << id << endl;
        for(int i=0; i<m; i++){
            string s,g;
            input_crossing(s, g);
            if(to_id.count(s)==0 or to_id.count(g)==0){
            	cout << "NO" << endl;
            	continue;
            }
            vector<bool> used(num_st, false);
            int ret = dfs(to_id[s], to_id[g], adj, used);
            if(ret!=-1 and ret%2==1){
                cout << "YES" << endl;
            }else{
                cout << "NO" << endl;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3324
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define inf (int)(1e7)
using namespace std;

struct intersection {
  string s, t;
};

int n, m;
map<string, int> mp;
vector<vector<int>> dist;
vector<vector<bool>> memo;
vector<intersection> v;

intersection parse(string &s);

int main() {
  while(1) {
    cin >> n;
    if(n == 0) break;
    v.resize(n);
    mp.clear();
    for(int i = 0; i < n; ++i) {
      string s;
      cin >> s;
      intersection in = parse(s);
      if(mp.find(in.s) == mp.end()) {
        int x = mp.size();
        mp[in.s] = x;
      }
      if(mp.find(in.t) == mp.end()) {
        int x = mp.size();
        mp[in.t] = x;
      }
      v[i] = in;
    }
    cout << mp.size() << endl;
    dist.assign(mp.size(), vector<int>(mp.size(), inf));
    memo.assign(mp.size(), vector<bool>(mp.size(), 0));
    for(int i = 0; i < n; ++i)
      dist[mp[v[i].s]][mp[v[i].t]] =
          memo[mp[v[i].s]][mp[v[i].t]] = 1;
    n = mp.size();
    for(int i = 0; i < n; ++i)
      for(int j = 0; j < n; ++j)
        if(!memo[i][j]) {
          bool ch = 0;
          for(int k = 0; k < n; ++k)
            if((memo[i][k] && memo[j][k]) ||
               (memo[k][i] && memo[k][j]))
              ch = 1;
          for(int k = 0; k < n; ++k)
            if((memo[i][k] && memo[k][j]) ||
               (memo[j][k] && memo[k][i]))
              ch = 0;
          if(ch) dist[i][j] = 2;
        }
    for(int k = 0; k < n; ++k)
      for(int i = 0; i < n; ++i)
        for(int j = 0; j < n; ++j)
          dist[i][j] =
              min(dist[i][j], dist[i][k] + dist[k][j]);
    cin >> m;
    for(int i = 0; i < m; ++i) {
      string s;
      cin >> s;
      intersection now = parse(s);
      if(mp.find(now.s) == mp.end() ||
         mp.find(now.t) == mp.end() ||
         dist[mp[now.s]][mp[now.t]] % 2 == 0)
        cout << "NO" << endl;
      else
        cout << "YES" << endl;
    }
  }
  return 0;
}

intersection parse(string &s) {
  bool ch = 0;
  intersection res = {"", ""};
  int len = s.size();
  for(int i = 0; i < len; ++i) {
    if(s[i] == '-') {
      ch = 1;
      continue;
    }
    if(!ch)
      res.s += s[i];
    else
      res.t += s[i];
  }
  return res;
}
accuracy: 1
time_ms: 120
memory_kb: 3516
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <math.h>
#include <string>
#include <climits>
#include <assert.h>
#include <iomanip>
#include <bitset>

#define FOR(i,a,b) for(int i= (a); i<((int)b); ++i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define IS_BIT_ON(bit, i) (bit & (1 << i))
#define BIT_ON(bit, i) (bit |= (1 << i))
#define BIT_OFF(bit, i) (bit &= ~(1 << i))
#define BIT_COUNT(bit) (__builtin_popcount(bit))

typedef long long LL;
template<typename T> std::vector<T> make_v(size_t a){return std::vector<T>(a);}
template<typename T,typename... Ts> auto make_v(size_t a, Ts... ts){ return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));}    // C++14
template<typename T,typename V> typename std::enable_if<std::is_class<T>::value==0>::type fill_v(T &t,const V &v){t=v;}
template<typename T,typename V> typename std::enable_if<std::is_class<T>::value!=0>::type fill_v(T &t,const V &v){for(auto &e:t) fill_v(e,v);}
template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
void print() { std::cout << std::endl; }
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) { std::cout << head; if (sizeof...(tail) != 0) {std::cout << " ";} print(std::forward<Tail>(tail)...); }
template <class T> void print(std::vector<T> &v) {for (auto& a : v) { std::cout << a; if (&a != &v.back()) {std::cout << " ";} }std::cout << std::endl;}
template <class T> void print(std::vector<std::vector<T>> &vv) { for (auto& v : vv) { print(v); }}
inline bool inside(long long y, long long x, long long H, long long W) {return 0 <= y and y < H and 0 <= x and x < W; }
template<class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }
template<class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) { return abs(x1 - x2) + abs(y1 - y2); }
template<typename T> T &chmin(T &a, const T &b) { return a = std::min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = std::max(a, b); }

template<class T> inline std::vector<T> unique(std::vector<T> v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    return v;
}
// 初項s, 交差dのn個の数列の和
long long sum_of_arithmetic_progression(long long s, long long d, long long n) {
    return n * (2 * s + (n - 1) * d) / 2;
}

// 2のべき乗数かどうか
bool is_power_of_two(long long x) {
    return !(x & (x - 1));
}

// aとbの最大公約数 O(log min(a, b))
long long gcd(long long a, long long b) {
    if (b == 0) { return a; }
    return gcd(b, a % b);
}

// 数列vの最大公約数 O(N log d)
long long gcd(std::vector<long long> &v) {
    long long ans = v[0];
    for (int i = 1; i < (int)v.size(); ++i) {
        ans = gcd(ans, v[i]);
    }
    return ans;
}

// aとbの最小公倍数 O(log min(a, b))
long long lcm(long long a, long long b) {
    long long g = gcd(a, b);
    return a / g * b;
}

const int INF = 1u << 30u;
const long long LINF = 1ull << 58u;
const double EPS = 1e-9;
const long double PI = acos(-1.0);
const std::vector<int> dy2 = {0, 1}, dx2 = {1, 0};  // 右，下
const std::vector<int> dy4 = {0, 1, 0, -1}, dx4 = {1, 0, -1, 0};    // 右，下，左，上
const std::vector<int> dy8 = { 0, -1, 0, 1, 1, -1, -1, 1 }, dx8 = { 1, 0, -1, 0, 1, 1, -1, -1 };

using namespace std;

// strをdelimiterで分割する
vector<string> split(const string &str, const string &delimiter) {
    vector<string> res;
    size_t current = 0, found, delimlen = delimiter.size();
    while ((found = str.find(delimiter, current)) != string::npos) {
        res.emplace_back(string(str, current, found - current));
        current = found + delimlen;
    }
    res.emplace_back(string(str, current, str.size() - current));
    return res;
}

class Edge {
public:
    const int no = 0;
    const int from = 0;
    const int to = 0;
    const long long weight = 0;

    Edge(int no, int from, int to, long long weight) : no(no), from(from), to(to), weight(weight) {
    }

};

class Graph {
public:
    const int N;    // ノード数
    int M = 0;      // エッジ数
    std::vector<std::vector<Edge>> graph;
    Graph(int N) : N(N) {
        this->graph.resize(N);
    }

    void add_undirected_edge(const int no, const int u, const int v, const long long w) {
        this->graph.at(u).emplace_back(Edge(no, u, v, w));
        this->graph.at(v).emplace_back(Edge(no, v, u, w));
        this->M++;
    }

    void add_directed_edge(const int no, const int from, const int to, const long long w) {
        this->graph.at(from).emplace_back(Edge(no, from, to, w));
        this->M++;
    }

    std::vector<Edge> &operator[](const int u) {
        return this->graph[u];
    }

    std::vector<std::vector<long long>> make_matrix_graph() {
        std::vector<std::vector<long long>> matrix(this->N, std::vector<long long>(this->N, INT_MAX));
        for (const auto &v : this->graph) {
            for (const auto &e : v) {
                matrix[e.from][e.to] = e.weight;
            }
        }
        return matrix;
    }

    // mode 0: undirected edge
    // mode 1: directed edge
    void show(int mode = 0) {
        std::cout << this->M << std::endl;
        for (const auto &v : this->graph) {
            for (const auto &e : v) {
                if (mode == 0) {
                    if (e.from < e.to) {
                        std::cout << e.from << " " << e.to << std::endl;
                    }
                }
                else {
                    std::cout << e.from << " " << e.to << std::endl;
                }
            }
        }
    }
};

void dfs(int u, int i, const int base, vector<int> &color, Graph &graph) {
    color[u] = base + (i % 2);
    FOE(e, graph[u]) {
        if (color[e.to] == -1) {
            dfs(e.to, i + 1, base, color, graph);
        }
    }
}

/**
 * 全ノード間の最短距離をもとめる
 * matrix[i][j]には辺e=(i,j)のコスト(辺が存在しない場合はINF)
 * 負の閉路がある場合は空を返す
 * O(|V|^3)
 */
std::vector<std::vector<int>> warshall_floyd(std::vector<std::vector<int>> matrix) {
    const unsigned long num_node = matrix.size();

    // 自分の距離は0
    for (int i = 0; i < num_node; ++i) {
        matrix.at(i).at(i) = 0;
    }

    for (int m = 0; m < num_node; ++m) {
        for (int s = 0; s < num_node; ++s) {
            for (int e = 0; e < num_node; ++e) {
                // sからeへmを経由して到達可能
                if (matrix.at(s).at(m) != INF and matrix.at(m).at(e) != INF) {
                    matrix.at(s).at(e) = std::min(matrix.at(s).at(e), matrix.at(s).at(m) + matrix.at(m).at(e));
                }
            }
        }
    }

    // 負閉路チェック
    for (int u = 0; u < num_node; ++u) {
        if (matrix.at(u).at(u) < 0) {
            return {};
        }
    }

    return matrix;
}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    while (true) {
        LL N;
        cin >> N;

        if (N == 0) {
            return 0;
        }

        int no = 0;
        unordered_map<string, int> name_no;
        vector<pair<int, int>> edges;
        FOR(i, 0, N) {
            string S;
            cin >> S;
            auto p = split(S, "-");
            string a = p[0];
            string b = p[1];

            if (name_no.find(a) == name_no.end()) {
                name_no[a] = no;
                no++;
            }

            if (name_no.find(b) == name_no.end()) {
                name_no[b] = no;
                no++;
            }
            edges.emplace_back(make_pair(name_no[a], name_no[b]));
        }

        Graph graph(no);
        auto g = make_v<int>(no, no);
        std::vector<std::vector<int>> matrix(no, vector<int>(no, INF));
        FOE(p, edges) {
            graph.add_undirected_edge(0, p.first, p.second, 1);

            g[p.first][p.second] = 1;
            g[p.second][p.first] = 2;
            matrix[p.first][p.second] = 1;
        }

        auto color = make_v<int>(no);
        fill_v(color, -1);
        int base = 0;
        FOR(i, 0, no) {
            if (color[i] == -1) {
                dfs(i, 0, base, color, graph);
                base += 4;
            }
        }

        FOR(a, 0, no) {
            FOR(b, a + 1, no) {

                bool found1 = false, found2 = false, found3 = false;
                FOR(c, 0, no) {
                    if (a == b or a == c or b == c) {
                        continue;
                    }

                    if (g[a][c] and g[b][c]) {
                        found1 = true;
                    }

                    if (g[c][a] == 1 and g[b][c] == 1) {
                        found2 = true;
                    }

                    if (g[a][c] == 1 and g[c][b] == 1) {
                        found3 = true;
                    }
                }

                if (found1 and not found2 and not found3) {
                    matrix[a][b] = 1;
                    matrix[b][a] = 1;
                }
            }
        }

        auto cost = warshall_floyd(matrix);

        print(no);
        LL M;
        cin >> M;
        FOR(i, 0, M) {
            string S;
            cin >> S;
            auto p = split(S, "-");
            string a = p[0];
            string b = p[1];

            if (name_no.find(a) == name_no.end()) {
                print("NO");
                continue;
            }

            if (name_no.find(b) == name_no.end()) {
                print("NO");
                continue;
            }

            int u = name_no[a];
            int v = name_no[b];

            if (abs(color[u] - color[v]) != 1) {
                print("NO");
                continue;
            }

            if (cost[u][v] != INF) {
                print("YES");
            }
            else {
                print("NO");
            }

        }

    }

    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3652
final_rank: 9

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<utility>
#include<map>
#include<complex>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
#define rep(i,n) for(int i=0;i<n;i++)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define stop char nyaa;cin>>nyaa;
#define per(i,n) for(int i=n-1;i>=0;i--)
typedef long double ld;

struct uf {
private:
	vector<int> par, ran;
public:
	uf(int n) {
		par.resize(n, 0);
		ran.resize(n, 0);
		rep(i, n) {
			par[i] = i;
		}
	}
	int find(int x) {
		if (par[x] == x)return x;
		else return par[x] = find(par[x]);
	}
	void unite(int x, int y) {
		x = find(x), y = find(y);
		if (x == y)return;
		if (ran[x] < ran[y]) {
			par[x] = y;
		}
		else {
			par[y] = x;
			if (ran[x] == ran[y])ran[x]++;
		}
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
};

int n, m;
void solve() {
	map<string, int> mp;
	map<string, bool> used;
	int tmp = 0;
	vector<P> v(n);
	rep(i, n) {
		string s; cin >> s;
		rep(j, s.length()) {
			if (s[j] == '-') {
				string le = s.substr(0, j);
				string ri = s.substr(j + 1, (int)s.length() - (j+1));
				int lid, rid;
				if (!used[le]) {
					used[le] = true;
					mp[le] = tmp; tmp++;
				}
				lid = mp[le];
				if (!used[ri]) {
					used[ri] = true;
					mp[ri] = tmp; tmp++;
				}
				rid = mp[ri];
				v[i] = { lid,rid };
				break;
			}
		}
	}
	vector<vector<int>> vl(tmp), vr(tmp);
	rep(i, n) {
		vl[v[i].first].push_back(i);
		vr[v[i].second].push_back(i);
	}
	vector<vector<bool>> b(tmp);
	rep(i, tmp)b[i].resize(tmp, false);
	rep(i, tmp) {
		rep(j, vl[i].size()) {
			Rep(k,j+1, vl[i].size()) {
				int lid = v[vl[i][j]].second;
				int rid = v[vl[i][k]].second;
				b[lid][rid] = b[rid][lid] = true;
			}
		}
		rep(j, vr[i].size()) {
			Rep(k, j + 1, vr[i].size()) {
				int lid = v[vr[i][j]].first;
				int rid = v[vr[i][k]].first;
				b[lid][rid] = b[rid][lid] = true;
			}
		}
	}
	rep(i, tmp) {
		rep(j, vl[i].size()) {
			rep(k, vr[i].size()) {
				int lid = v[vl[i][j]].second;
				int rid = v[vr[i][k]].first;
				b[lid][rid] = b[rid][lid] = false;
			}
		}
	}
	uf u(tmp); vector<vector<int>> bG(tmp);
	rep(i, n) {
		u.unite(v[i].first, v[i].second);
		bG[v[i].first].push_back(v[i].second);
		bG[v[i].second].push_back(v[i].first);
	}
	//uf u(tmp);
	//rep(i, tmp)rep(j, tmp)if (b[i][j])u.unite(i, j);
	vector<int> isns(tmp);
	vector<bool> chked(tmp, false);
	rep(i, tmp) {
		if (chked[i])continue;
		int cur = 0;
		queue<int> q; q.push(i);
		while (!q.empty()) {
			int len = q.size();
			rep(aa, len) {
				int id = q.front(); q.pop();
				isns[id] = cur;
				rep(j, bG[id].size()) {
					int to = bG[id][j];
					if (chked[to])continue;
					chked[to] = true;
					q.push(to);
				}
			}
			cur ^= 1;
		}
	}

	vector<vector<int>> G(tmp);
	rep(i, n) {
		int lid = v[i].first;
		int rid = v[i].second;
		G[lid].push_back(rid);
	}
	rep(i, tmp)rep(j, tmp)if (b[i][j])G[i].push_back(j);

	cout << tmp << endl;
	int m; cin >> m;
	rep(i, m) {
		string s; cin >> s;
		int len = s.length();
		int lid, rid;
		bool valid = true;
		rep(j, len) {
			if (s[j] == '-') {
				string le = s.substr(0, j);
				string ri = s.substr(j + 1, len - (j + 1));
				if (!used[le] || !used[ri])valid = false;
				lid = mp[le], rid = mp[ri];
				break;
			}
		}
		if (!valid) {
			cout << "NO" << endl; continue;
		}
		if (!u.same(lid, rid)) {
			cout << "NO" << endl; continue;
		}
		if (isns[lid] == isns[rid]) {
			cout << "NO" << endl; continue;
		}
		fill(chked.begin(), chked.begin() + tmp, false);
		queue<int> q; q.push(lid);
		bool f = false;
		while (!q.empty()) {
			int id = q.front(); q.pop();
			if (id == rid)f = true;
			rep(j, G[id].size()) {
				int to = G[id][j];
				if (!chked[to]) {
					chked[to] = true;
					q.push(to);
				}
			}
		}
		if (f) {
			cout << "YES" << endl;
		}
		else {
			cout << "NO" << endl;
		}
	}
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	while(cin>>n,n)solve();
	//stop
		return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3400
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
void chmin(int &a, int b) {
    a = min(a, b);
}

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
//const ll mod = 1000000007;
struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<ll> Size;
    UnionFind(int n = 1) {
        init(n);
    }

    void init(int n = 1) {
        par.resize(n + 1); rank.resize(n + 1); Size.resize(n + 1);
        for (int i = 0; i <= n; ++i) par[i] = i, rank[i] = 0, Size[i] = 1;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            return par[x] = r;
        }
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y);
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        Size[x] += Size[y];
        return true;
    }

    ll size(int x){
        return Size[root(x)];
    }
};

int N;
unordered_map<string, int> mp;
set<string> st;
string intersection[1005];
string before[1005], after[1005];
string name[205];
int dist[205][205];
bool beforei[205][205], afteri[205][205];
int main() {
    //cout.precision(10);
    cin.tie(0);
    ios::sync_with_stdio(false);
    UnionFind uni;
    int timer = 0;
    while(true) {
        timer++;
        //cerr << timer << endl;
        uni.init(500);
        st.clear();
        mp.clear();
        cin >> N;
        if(N == 0) break;
        for(int i = 1; i <= N; i++) {
            cin >> intersection[i];
            int moji = 0;
            while(intersection[i][moji] != '-') moji++;
            before[i] = intersection[i].substr(0, moji);
            after[i] = intersection[i].substr(moji + 1);
            st.insert(before[i]);
            st.insert(after[i]);
            //cerr << before[i] << " " << after[i] << endl;
        }
        int num = 0;
        for(auto itr = st.begin(); itr != st.end(); itr++) {
            num++;
            mp[*itr] = num;
            name[num] = *itr;
        }
        for(int i = 1; i <= num; i++) {
            for(int j = 1; j <= num; j++) beforei[i][j] = false, afteri[i][j] = false;
            for(int k = 1; k <= N; k++) {
                if(mp[before[k]] == i) afteri[i][mp[after[k]]] = true;
                if(mp[after[k]] == i) beforei[i][mp[before[k]]] = true;
            }
        }
        for(int i = 1; i <= num; i++) {
            for(int j = i + 1; j <= num; j++) {
                /*
                cerr << "----" << i << "----" << endl;
                for(int k = 1; k <= num; k++) {
                    cerr << k << " " << beforei[k] << " " << afteri[k] << endl;
                }
                */
                bool isok = false;
                for(int k = 1; k <= num; k++) {
                    if(beforei[i][k] && beforei[j][k]) isok = true;
                    if(afteri[i][k] && afteri[j][k]) isok = true;
                }
                if(!isok) continue;
                for(int k = 1; k <= num; k++) {
                    if(beforei[i][k] && afteri[j][k]) isok = false;
                    if(beforei[j][k] && afteri[i][k]) isok = false;
                }
                if(isok) uni.merge(i, j);
            }
        }
        /*
        for(int i = 1; i <= num; i++) {
            cerr << i << " " << name[i] << " " << uni.root(i) << endl;
        }
        */
        for(int i = 1; i <= num; i++) {
            for(int j = 1; j <= num; j++) {
                dist[i][j] = INF;
            }
            dist[i][i] = 0;
        }
        /*
        UnionFind uni2(1000);
        for(int i = 1; i <= N; i++) {
            uni2.merge(mp[before[i]], mp[after[i]] + 200);
            uni2.merge(mp[before[i]] + 200, mp[after[i]]);
            dist[mp[before[i]]][mp[after[i]]] = 1;
        }
        */
       for(int i = 1; i <= N; i++) {
           dist[uni.root(mp[before[i]])][uni.root(mp[after[i]])] = 1;
       }
        for(int i = 1; i <= num; i++) {
            for(int j = 1; j <= num; j++) {
                for(int k = 1; k <= num; k++) {
                    chmin(dist[j][k], dist[j][i] + dist[i][k]);
                }
            }
        }
        /*
        for(int i = 1; i <= num; i++) {
            for(int j = 1; j <= num; j++) cerr << dist[i][j] << " ";
            cerr << endl;
        }
        */
        int M;
        cin >> M;
        cout  << st.size() << endl;
        while(M--) {
            string in;
            cin >> in;
            string a, b;
            int moji = 0;
            while(in[moji] != '-') moji++;
            a = in.substr(0, moji);
            b = in.substr(moji + 1);
            if(st.find(a) == st.end() || st.find(b) == st.end()) {
                cout << "NO" << endl;
                continue;
            }
            a = name[uni.root(mp[a])];
            b = name[uni.root(mp[b])];
            //cerr << a << " " << mp[a] << " " << b << " " << mp[b] << endl;
            /*
            if(!uni2.issame(mp[a], mp[b] + 200)) {
                //cerr << "NOT CONNECTED" << endl;
                cout << "NO" << endl;
                continue;
            }
            */
            //cerr << dist[mp[a]][mp[b]] << endl;
            if(dist[mp[a]][mp[b]] == INF) cout << "NO" << endl;
            else if(dist[mp[a]][mp[b]] % 2 == 0) cout << "NO" << endl;
            else cout << "YES" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 3684
final_rank: 13

code_snippet: #include <bits/stdc++.h> 
using namespace std; 
#define rep(i,n) for(ll i = 0; i < ll(n); ++i) 
#define FOR(i,a,b) for(ll i = (a); i < ll(b); ++i) 
#define ROF(i,a,b) for(ll i = (a)-1; i >= ll(b); --i) 
#define all(a) (a).begin(),(a).end() 
#define fst first 
#define snd second 
typedef long long ll; 
typedef vector<ll> vi;
typedef vector<vi> vii;
const ll inf = 1ll<<10;

bool dfs(const vii &g, ll i, vi &color){
  ll sz = g.size();
  stack<ll> st;
  color[i] = 1;
  st.push(i);

  while(!st.empty()){
    int now = st.top();
    st.pop();

    rep(next,sz){
      if(now == next) continue;
      if(g[now][next] + g[next][now] == 0){ // now<->next
	if(color[next] and color[next] != color[now]){
	  //cout << now << endl << next << endl;
	  return false; 
	}else if(color[next] and color[next] == color[now]) continue;
	else{
	  color[next] = color[now];
	  st.push(next);
	}
      }else if(g[now][next] * g[next][now] == 0){ // now->next or next->now
	if(color[next] and color[next] == color[now]){
	  //cout << now << endl << next << endl;
	  return false;
	}else if(color[next] and color[next] != color[now]) continue;
	else{
	  color[next] = -color[now];
	  st.push(next);
	}
      }
    }
  }
  return true;
}

bool paintable(const vii &g, vi &color){
  ll sz = g.size();
  rep(i,sz) if(color[i] == 0) if(dfs(g,i,color) == false) return false;
  return true;
}

main(){
  ll m,n; 
  while(cin >> m, m){ 
    vector<string> input(m); 
    vector<vector<string>> cross(m,vector<string>(2)); 
    set<string> street; 
    rep(i,m){ 
      cin >> input[i]; 
      FOR(k,1,input[i].size()){ // A-BをAとBに分ける 
	if(input[i][k] == '-'){ 
	  cross[i][0] = input[i].substr(0,k); 
	  cross[i][1] = input[i].substr(k+1,input[i].size()-k-1); 
	  street.insert(cross[i][0]); 
	  street.insert(cross[i][1]); 
	  //cerr << cross[i][0] << endl << cross[i][1] << endl; 
	  break; 
	} 
      } 
    } 
    map<string,ll> ntoi; // 通りの名前からindex
    vector<string> iton; // indexから通りの名前
    ll tmpi = 0;
    for(auto name : street){ 
      ntoi[name] = tmpi;
      iton.push_back(name);
      tmpi++;
    }
    ll sz = street.size(); cout << sz << endl;
    vii g(sz,vi(sz,1)); 
    rep(i,m) g[ ntoi[cross[i][0]] ][ ntoi[cross[i][1]] ] = 0; // A->B
    
    vector<pair<ll,ll>> eqp; // 同水準のpair
    rep(i,sz) rep(j,sz){ // iとjが同水準か
      bool ieqj = false;
      rep(k,sz){
	if((g[i][k] + g[k][j]) * (g[j][k] + g[k][i]) == 0){ // i->k->jかj->k->iがある
	  ieqj = false;
	  break;
	}else if((g[i][k] + g[j][k]) * (g[k][i] + g[k][j]) == 0){ // i->k,j->kかk->i,k->jがある
	  ieqj = true;
	}
      }
      if(ieqj) eqp.push_back(make_pair(i,j));
    }
    rep(i,eqp.size()) g[eqp[i].fst][eqp[i].snd] = g[eqp[i].snd][eqp[i].fst] = 0; // A<->B
    //rep(i,sz){ rep(j,sz) cout << g[i][j] << " "; cout << endl; }

    vii d = g; // path i->j がある <=> d[i][j] == 0
    rep(k,sz) rep(i,sz) rep(j,sz) d[i][j] = min(d[i][j], d[i][k]+d[k][j]);

    vi color(sz);
    bool p = paintable(g,color);
    //cout << "p : " << p << endl;
    //rep(i,sz) cout << iton[i] << " : " << color[i] << endl;

    cin >> n;
    rep(k,n){
      string q; cin >> q;
      if(p == false){
	cout << "NO\n";
	continue;
      }
      string ql, qr;
      FOR(i,1,q.size()){ // A-BをAとBに分ける 
	if(q[i] == '-'){ 
	  ql = q.substr(0,i); 
	  qr = q.substr(i+1,q.size()-i-1);
	  break; 
	} 
      }
      if(ntoi.count(ql) * ntoi.count(qr) == 0){
	cout << "NO\n";
	continue;
      }
      if(d[ntoi[ql]][ntoi[qr]] != 0){
	cout << "NO\n";
	continue;
      }
      //cout << color[ntoi[ql]] << endl << color[ntoi[qr]] << endl;
      if(color[ntoi[ql]] != color[ntoi[qr]]) cout << "YES\n";
      else cout << "NO\n";
    }
  }
}
accuracy: 1
time_ms: 100
memory_kb: 3724
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define REP(i, a, n) for(ll i = ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;

pss split(string s) {
  ll k;
  REP(i, 0, s.size()) if(s[i] == '-') k = i;
  string fi = s.substr(0, k);
  string se = s.substr(k + 1, s.size() - k - 1);
  return pss(fi, se);
}

void dfs(ll v, vector<vector<ll>> &E, vector<bool> &used, vector<ll> &color, ll c) {
  if(used[v]) return;
  used[v] = true;

  color[v] = c;
  for(ll u : E[v]) dfs(u, E, used, color, -c);
}

bool dfs2(ll v, ll g, vector<vector<ll>> &E, vector<bool> &used) {
  if(v == g) return true;

  if(used[v]) return false;
  used[v] = true;

  bool ret = false;
  for(ll u : E[v]) ret = ret || dfs2(u, g, E, used);
  return ret;
}

int main(void) {
  ll N, M;
  while(cin >> N, N) {
    vector<string> uniq;
    vector<pss> C(N);
    REP(i, 0, N) {
      string s;
      cin >> s;
      C[i] = split(s);
      uniq.push_back(C[i].first);
      uniq.push_back(C[i].second);
    }
    cin >> M;
    vector<pss> Q(M);
    REP(i, 0, M) {
      string s;
      cin >> s;
      Q[i] = split(s);
      uniq.push_back(Q[i].first);
      uniq.push_back(Q[i].second);
    }
    sort(uniq.begin(), uniq.end());
    uniq.erase(unique(uniq.begin(), uniq.end()), uniq.end());

    vector<pll> cross(N), query(M);
    REP(i, 0, N) {
      cross[i].first = lower_bound(uniq.begin(), uniq.end(), C[i].first) - uniq.begin();
      cross[i].second = lower_bound(uniq.begin(), uniq.end(), C[i].second) - uniq.begin();
    }
    REP(i, 0, M) {
      query[i].first = lower_bound(uniq.begin(), uniq.end(), Q[i].first) - uniq.begin();
      query[i].second = lower_bound(uniq.begin(), uniq.end(), Q[i].second) - uniq.begin();
    }

    ll n = uniq.size();
    vector<vector<ll>> E(n), R(n), A(n), X(n);
    REP(i, 0, N) {
      E[cross[i].first].push_back(cross[i].second);
      R[cross[i].second].push_back(cross[i].first);
      A[cross[i].first].push_back(cross[i].second);
      A[cross[i].second].push_back(cross[i].first);
      X[cross[i].first].push_back(cross[i].second);
    }

    vector<bool> used(n, false);
    vector<ll> color(n);
    ll c = 1;
    REP(i, 0, n) if(!used[i]) dfs(i, A, used, color, c++);

    vector<vector<bool>> e(n, vector<bool>(n, false));
    REP(i, 0, N) e[cross[i].first][cross[i].second] = true;
    REP(i, 0, n) REP(j, 0, n) {
      bool c1 = false, c2 = true;
      REP(k, 0, n) {
        c1 = c1 || (e[i][k] && e[j][k]) || (e[k][i] && e[k][j]);
        c2 = c2 && !(e[i][k] && e[k][j]) && !(e[j][k] && e[k][i]);
      }
      if(c1 && c2) {
        X[i].push_back(j);
        X[j].push_back(i);
      }
    }

    set<ll> st;
    REP(i, 0, N) {
      st.insert(cross[i].first);
      st.insert(cross[i].second);
    }

    cout << st.size() << endl;
    REP(i, 0, M) {
      ll s = query[i].first, t = query[i].second;
      vector<bool> used2(n, false);
      bool ok = color[s] == -color[t] && dfs2(s, t, X, used2);
      cout << (ok ? "YES" : "NO") << endl;
    }
  }
}
accuracy: 1
time_ms: 120
memory_kb: 3612
final_rank: 17