#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void * wmem;
char memarr[ 96000000 ] ;
template < class T> inline void walloc1d( T ** arr, int x, void ** mem = & wmem) {
static int skip[ 16 ] = { 0 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
( * mem) = ( void * ) ( ( ( char * ) ( * mem) ) + skip[ ( ( unsigned long long ) ( * mem) ) & 15 ] ) ;
( * arr) = ( T* ) ( * mem) ;
( * mem) = ( ( * arr) + x) ;
}
template < class S> void arrInsert( const int k, int & sz, S a[ ] , const S aval) {
int i;
sz++ ;
for ( i= sz- 1 ; i> k; i-- ) {
a[ i] = a[ i- 1 ] ;
}
a[ k] = aval;
}
template < class S, class T> void arrInsert( const int k, int & sz, S a[ ] , const S aval, T b[ ] , const T bval) {
int i;
sz++ ;
for ( i= sz- 1 ; i> k; i-- ) {
a[ i] = a[ i- 1 ] ;
}
for ( i= sz- 1 ; i> k; i-- ) {
b[ i] = b[ i- 1 ] ;
}
a[ k] = aval;
b[ k] = bval;
}
template < class S, class T, class U> void arrInsert( const int k, int & sz, S a[ ] , const S aval, T b[ ] , const T bval, U c[ ] , const U cval) {
int i;
sz++ ;
for ( i= sz- 1 ; i> k; i-- ) {
a[ i] = a[ i- 1 ] ;
}
for ( i= sz- 1 ; i> k; i-- ) {
b[ i] = b[ i- 1 ] ;
}
for ( i= sz- 1 ; i> k; i-- ) {
c[ i] = c[ i- 1 ] ;
}
a[ k] = aval;
b[ k] = bval;
c[ k] = cval;
}
struct graph{
int N;
int * es;
int ** edge;
void setDirectEdge( int N__, int M, int A[ ] , int B[ ] , void ** mem = & wmem) {
int i;
N = N__;
walloc1d( & es, N, mem) ;
walloc1d( & edge, N, mem) ;
walloc1d( & edge[ 0 ] , M, mem) ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
es[ i] = 0 ;
}
for ( i= ( 0 ) ; i< ( M) ; i++ ) {
es[ A[ i] ] ++ ;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
walloc1d( & edge[ i] , es[ i] , mem) ;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
es[ i] = 0 ;
}
for ( i= ( 0 ) ; i< ( M) ; i++ ) {
edge[ A[ i] ] [ es[ A[ i] ] ++ ] = B[ i] ;
}
}
}
;
#define main dummy_main
int main( ) {
wmem = memarr;
return 0 ;
}
#undef main
map< string,int > mp;
string node[ 200000 ] ;
int N;
int M;
int A[ 200000 ] ;
int B[ 200000 ] ;
int vis[ 200000 ] ;
int getNode( string s) {
if ( mp.count ( s) ) {
return mp[ s] ;
}
node[ N] = s;
mp[ s] = N;
return N++ ;
}
class Solution{
public :
string findSmallestRegion( vector< vector< string>> & regions, string region1, string region2) {
int i;
int a;
int b;
int x;
int y;
graph g;
dummy_main( ) ;
N = M = 0 ;
mp.clear ( ) ;
for ( i= ( 0 ) ; i< ( regions.size ( ) ) ; i++ ) {
int j;
a = getNode( regions[ i] [ 0 ] ) ;
for ( j= ( 1 ) ; j< ( regions[ i] .size ( ) ) ; j++ ) {
b = getNode( regions[ i] [ j] ) ;
arrInsert( M,M,A,b,B,a) ;
}
}
x = getNode( region1) ;
y = getNode( region2) ;
g.setDirectEdge ( N,M,A,B) ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
vis[ i] = 0 ;
}
a = x;
for ( ;; ) {
vis[ a] = 1 ;
if ( g.es [ a] == 0 ) {
break ;
}
a = g.edge [ a] [ 0 ] ;
}
b = y;
for ( ;; ) {
if ( vis[ b] ) {
break ;
}
b = g.edge [ b] [ 0 ] ;
}
return node[ b] ;
}
}
;
// cLay varsion 20191123-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// map<string,int> mp;
// string node[2d5];
// int N, M, A[2d5], B[2d5];
// int vis[2d5];
//
// int getNode(string s){
// if(mp.count(s)) return mp[s];
// node[N] = s;
// mp[s] = N;
// return N++;
// }
//
// class Solution {
// public:
// string findSmallestRegion(vector<vector<string>>& regions, string region1, string region2) {
// int a, b, x, y;
// graph g;
// dummy_main();
//
// N = M = 0;
// mp.clear();
// rep(i,regions.size()){
// a = getNode(regions[i][0]);
// rep(j,1,regions[i].size()){
// b = getNode(regions[i][j]);
// arrInsert(M,M,A,b,B,a);
// }
// }
// x = getNode(region1);
// y = getNode(region2);
//
// g.setDirectEdge(N,M,A,B);
// rep(i,N) vis[i] = 0;
// a = x;
// for(;;){
// vis[a] = 1;
// if(g.es[a]==0) break;
// a = g.edge[a][0];
// }
// b = y;
// for(;;){
// if(vis[b]) break;
// b = g.edge[b][0];
// }
// return node[b];
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XSA9IHswLCAxNSwgMTQsIDEzLCAxMiwgMTEsIDEwLCA5LCA4LCA3LCA2LCA1LCA0LCAzLCAyLCAxfTsKICAoKm1lbSkgPSAodm9pZCopKCAoKGNoYXIqKSgqbWVtKSkgKyBza2lwWygodW5zaWduZWQgbG9uZyBsb25nKSgqbWVtKSkgJiAxNV0gKTsKICAoKmFycik9KFQqKSgqbWVtKTsKICAoKm1lbSk9KCgqYXJyKSt4KTsKfQp0ZW1wbGF0ZTxjbGFzcyBTPiB2b2lkIGFyckluc2VydChjb25zdCBpbnQgaywgaW50ICZzeiwgUyBhW10sIGNvbnN0IFMgYXZhbCl7CiAgaW50IGk7CiAgc3orKzsKICBmb3IoaT1zei0xO2k+aztpLS0pewogICAgYVtpXSA9IGFbaS0xXTsKICB9CiAgYVtrXSA9IGF2YWw7Cn0KdGVtcGxhdGU8Y2xhc3MgUywgY2xhc3MgVD4gdm9pZCBhcnJJbnNlcnQoY29uc3QgaW50IGssIGludCAmc3osIFMgYVtdLCBjb25zdCBTIGF2YWwsIFQgYltdLCBjb25zdCBUIGJ2YWwpewogIGludCBpOwogIHN6Kys7CiAgZm9yKGk9c3otMTtpPms7aS0tKXsKICAgIGFbaV0gPSBhW2ktMV07CiAgfQogIGZvcihpPXN6LTE7aT5rO2ktLSl7CiAgICBiW2ldID0gYltpLTFdOwogIH0KICBhW2tdID0gYXZhbDsKICBiW2tdID0gYnZhbDsKfQp0ZW1wbGF0ZTxjbGFzcyBTLCBjbGFzcyBULCBjbGFzcyBVPiB2b2lkIGFyckluc2VydChjb25zdCBpbnQgaywgaW50ICZzeiwgUyBhW10sIGNvbnN0IFMgYXZhbCwgVCBiW10sIGNvbnN0IFQgYnZhbCwgVSBjW10sIGNvbnN0IFUgY3ZhbCl7CiAgaW50IGk7CiAgc3orKzsKICBmb3IoaT1zei0xO2k+aztpLS0pewogICAgYVtpXSA9IGFbaS0xXTsKICB9CiAgZm9yKGk9c3otMTtpPms7aS0tKXsKICAgIGJbaV0gPSBiW2ktMV07CiAgfQogIGZvcihpPXN6LTE7aT5rO2ktLSl7CiAgICBjW2ldID0gY1tpLTFdOwogIH0KICBhW2tdID0gYXZhbDsKICBiW2tdID0gYnZhbDsKICBjW2tdID0gY3ZhbDsKfQpzdHJ1Y3QgZ3JhcGh7CiAgaW50IE47CiAgaW50ICplczsKICBpbnQgKiplZGdlOwogIHZvaWQgc2V0RGlyZWN0RWRnZShpbnQgTl9fLCBpbnQgTSwgaW50IEFbXSwgaW50IEJbXSwgdm9pZCAqKm1lbSA9ICZ3bWVtKXsKICAgIGludCBpOwogICAgTiA9IE5fXzsKICAgIHdhbGxvYzFkKCZlcywgTiwgbWVtKTsKICAgIHdhbGxvYzFkKCZlZGdlLCBOLCBtZW0pOwogICAgd2FsbG9jMWQoJmVkZ2VbMF0sIE0sIG1lbSk7CiAgICBmb3IoaT0oMCk7aTwoTik7aSsrKXsKICAgICAgZXNbaV0gPSAwOwogICAgfQogICAgZm9yKGk9KDApO2k8KE0pO2krKyl7CiAgICAgIGVzW0FbaV1dKys7CiAgICB9CiAgICBmb3IoaT0oMCk7aTwoTik7aSsrKXsKICAgICAgd2FsbG9jMWQoJmVkZ2VbaV0sIGVzW2ldLCBtZW0pOwogICAgfQogICAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICAgIGVzW2ldID0gMDsKICAgIH0KICAgIGZvcihpPSgwKTtpPChNKTtpKyspewogICAgICBlZGdlW0FbaV1dW2VzW0FbaV1dKytdID0gQltpXTsKICAgIH0KICB9Cn0KOwojZGVmaW5lIG1haW4gZHVtbXlfbWFpbgppbnQgbWFpbigpewogIHdtZW0gPSBtZW1hcnI7CiAgcmV0dXJuIDA7Cn0KI3VuZGVmIG1haW4KbWFwPHN0cmluZyxpbnQ+IG1wOwpzdHJpbmcgbm9kZVsyMDAwMDBdOwppbnQgTjsKaW50IE07CmludCBBWzIwMDAwMF07CmludCBCWzIwMDAwMF07CmludCB2aXNbMjAwMDAwXTsKaW50IGdldE5vZGUoc3RyaW5nIHMpewogIGlmKG1wLmNvdW50KHMpKXsKICAgIHJldHVybiBtcFtzXTsKICB9CiAgbm9kZVtOXSA9IHM7CiAgbXBbc10gPSBOOwogIHJldHVybiBOKys7Cn0KY2xhc3MgU29sdXRpb257CiAgcHVibGljOgogIHN0cmluZyBmaW5kU21hbGxlc3RSZWdpb24odmVjdG9yPHZlY3RvcjxzdHJpbmc+PiYgcmVnaW9ucywgc3RyaW5nIHJlZ2lvbjEsIHN0cmluZyByZWdpb24yKXsKICAgIGludCBpOwogICAgaW50IGE7CiAgICBpbnQgYjsKICAgIGludCB4OwogICAgaW50IHk7CiAgICBncmFwaCBnOwogICAgZHVtbXlfbWFpbigpOwogICAgTiA9IE0gPSAwOwogICAgbXAuY2xlYXIoKTsKICAgIGZvcihpPSgwKTtpPChyZWdpb25zLnNpemUoKSk7aSsrKXsKICAgICAgaW50IGo7CiAgICAgIGEgPSBnZXROb2RlKHJlZ2lvbnNbaV1bMF0pOwogICAgICBmb3Ioaj0oMSk7ajwocmVnaW9uc1tpXS5zaXplKCkpO2orKyl7CiAgICAgICAgYiA9IGdldE5vZGUocmVnaW9uc1tpXVtqXSk7CiAgICAgICAgYXJySW5zZXJ0KE0sTSxBLGIsQixhKTsKICAgICAgfQogICAgfQogICAgeCA9IGdldE5vZGUocmVnaW9uMSk7CiAgICB5ID0gZ2V0Tm9kZShyZWdpb24yKTsKICAgIGcuc2V0RGlyZWN0RWRnZShOLE0sQSxCKTsKICAgIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgICB2aXNbaV0gPSAwOwogICAgfQogICAgYSA9IHg7CiAgICBmb3IoOzspewogICAgICB2aXNbYV0gPSAxOwogICAgICBpZihnLmVzW2FdPT0wKXsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBhID0gZy5lZGdlW2FdWzBdOwogICAgfQogICAgYiA9IHk7CiAgICBmb3IoOzspewogICAgICBpZih2aXNbYl0pewogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGIgPSBnLmVkZ2VbYl1bMF07CiAgICB9CiAgICByZXR1cm4gbm9kZVtiXTsKICB9Cn0KOwovLyBjTGF5IHZhcnNpb24gMjAxOTExMjMtMQoKLy8gLS0tIG9yaWdpbmFsIGNvZGUgLS0tCi8vICNkZWZpbmUgbWFpbiBkdW1teV9tYWluCi8vIHt9Ci8vICN1bmRlZiBtYWluCi8vIAovLyBtYXA8c3RyaW5nLGludD4gbXA7Ci8vIHN0cmluZyBub2RlWzJkNV07Ci8vIGludCBOLCBNLCBBWzJkNV0sIEJbMmQ1XTsKLy8gaW50IHZpc1syZDVdOwovLyAKLy8gaW50IGdldE5vZGUoc3RyaW5nIHMpewovLyAgIGlmKG1wLmNvdW50KHMpKSByZXR1cm4gbXBbc107Ci8vICAgbm9kZVtOXSA9IHM7Ci8vICAgbXBbc10gPSBOOwovLyAgIHJldHVybiBOKys7Ci8vIH0KLy8gCi8vIGNsYXNzIFNvbHV0aW9uIHsKLy8gcHVibGljOgovLyAgIHN0cmluZyBmaW5kU21hbGxlc3RSZWdpb24odmVjdG9yPHZlY3RvcjxzdHJpbmc+PiYgcmVnaW9ucywgc3RyaW5nIHJlZ2lvbjEsIHN0cmluZyByZWdpb24yKSB7Ci8vICAgICBpbnQgYSwgYiwgeCwgeTsKLy8gICAgIGdyYXBoIGc7Ci8vICAgICBkdW1teV9tYWluKCk7Ci8vIAovLyAgICAgTiA9IE0gPSAwOwovLyAgICAgbXAuY2xlYXIoKTsKLy8gICAgIHJlcChpLHJlZ2lvbnMuc2l6ZSgpKXsKLy8gICAgICAgYSA9IGdldE5vZGUocmVnaW9uc1tpXVswXSk7Ci8vICAgICAgIHJlcChqLDEscmVnaW9uc1tpXS5zaXplKCkpewovLyAgICAgICAgIGIgPSBnZXROb2RlKHJlZ2lvbnNbaV1bal0pOwovLyAgICAgICAgIGFyckluc2VydChNLE0sQSxiLEIsYSk7Ci8vICAgICAgIH0KLy8gICAgIH0KLy8gICAgIHggPSBnZXROb2RlKHJlZ2lvbjEpOwovLyAgICAgeSA9IGdldE5vZGUocmVnaW9uMik7Ci8vIAovLyAgICAgZy5zZXREaXJlY3RFZGdlKE4sTSxBLEIpOwovLyAgICAgcmVwKGksTikgdmlzW2ldID0gMDsKLy8gICAgIGEgPSB4OwovLyAgICAgZm9yKDs7KXsKLy8gICAgICAgdmlzW2FdID0gMTsKLy8gICAgICAgaWYoZy5lc1thXT09MCkgYnJlYWs7Ci8vICAgICAgIGEgPSBnLmVkZ2VbYV1bMF07Ci8vICAgICB9Ci8vICAgICBiID0geTsKLy8gICAgIGZvcig7Oyl7Ci8vICAgICAgIGlmKHZpc1tiXSkgYnJlYWs7Ci8vICAgICAgIGIgPSBnLmVkZ2VbYl1bMF07Ci8vICAgICB9Ci8vICAgICByZXR1cm4gbm9kZVtiXTsKLy8gICB9Ci8vIH07Cg==