// 题目来源:POJ 3648
// 题目大意:有n对夫妻参加婚礼,现安排座位,已经某些人不能同时坐在新娘的对面,且夫妻不可同侧,求可行方案
// 解决方法:仍然2-sat建图解决
// 特别注意:新娘到新郎要连边,因为选出的必须是新郎
#include
#include
#define o 100000
#define _ 1000000
using namespace std;
void link( int, int );
void link2( int, int );
void tarjan( int );
void topsort( int );
void dfs( int );
int next[_], next2[_], g[_], g2[_];
int h[o], h2[o], dfn[o], low[o], stack[o], done[o], code[o], color[o], cfl[o], id[o];
int n, m, top, t, t2, tt, index, cnt;
bool ins[o];
bool ok;
int main( )
{
freopen( "3648.in", "r", stdin );
freopen( "3648.out", "w", stdout );
scanf( "%d%d", &n, &m );
int aa, bb;
char ch, ch2;
while( n != 0 )
{
memset( next, 0, sizeof( next ) );
memset( next2, 0, sizeof( next2 ) );
memset( h, 0, sizeof( h ) );
memset( h2, 0, sizeof( h2 ) );
memset( dfn, 0, sizeof( dfn ) );
memset( low, 0, sizeof( low ) );
memset( code, 0, sizeof( code ) );
memset( color, 0, sizeof( color ) );
memset( id, 0, sizeof( id ) );
memset( cfl, 0, sizeof( cfl ) );
t = t2 = tt = index = cnt = 0;
ok = true;
while( m-- )
{
scanf( "%d%c%d%c", &aa, &ch, &bb, &ch2 );
aa *= 2;
if( ch == 'w' ) aa ^= 1;
bb *= 2;
if( ch2 == 'w' ) bb ^= 1;
link( aa, bb^1 );
link( bb, aa^1 );
}
link( 1, 0 );
for( int i = 0; i < 2*n; i++ )
if( !dfn[i] ) tarjan( i );
for( int i = 0; i < 2*n; i++ )
if( code[i] == code[i^1] )
{
printf( "bad luck\n" );
ok = false;
break;
}
if( ok )
{
for( int i = 0; i < 2*n; i++ )
{
for( int k = h[i]; k; k = next[k] )
{
int j = g[k];
if( code[i] == code[j] ) continue;
link2( code[j], code[i] );
id[ code[i] ]++;
}
cfl[ code[i] ] = code[i^1];
cfl[ code[i^1] ] = code[i];
}
for( int i = 1; i <= cnt; i++ )
if( id[i] == 0 ) topsort( i );
for( int ii = 1; ii <= cnt; ii++ )
{
int i = done[ii];
if( color[i] != 0 ) continue;
color[i] = 1;
dfs( cfl[i] );
}
for( int i = 2; i < 2*n; i++ )
if( color[ code[i] ] == 2 )
if( ( i & 1 ) == 0 )
printf( "%dh ", i/2 );
else
printf( "%dw ", i/2 );
printf( "\n" );
}
scanf( "%d%d", &n, &m );
}
}
void link( int aa, int bb )
{
next[++t] = h[aa];
h[aa] = t;
g[t] = bb;
}
void link2( int aa, int bb )
{
next2[++t2] = h2[aa];
h2[aa] = t2;
g2[t2] = bb;
}
void tarjan( int i )
{
int j;
dfn[i] = low[i] = ++index;
stack[++top] = i;
ins[i] = true;
for( int k = h[i]; k; k = next[k] )
{
j = g[k];
if( !dfn[j] )
{
tarjan( j );
if( low[j] < low[i] ) low[i] = low[j];
}
else if( ins[j] && dfn[j] < low[i] )
low[i] = dfn[j];
}
if( dfn[i] == low[i] )
{
cnt++;
do
{
j = stack[top--];
ins[j] = false;
code[j] = cnt;
}
while( i != j );
}
}
void topsort( int i )
{
int j;
id[i] = -1;
done[++tt] = i;
for( int k = h2[i]; k; k = next2[k] )
{
j = g2[k];
id[j]--;
if( id[j] == 0 ) topsort( j );
}
}
void dfs( int i )
{
int j;
color[i] = 2;
for( int k = h2[i]; k; k = next2[k] )
{
j = g2[k];
if( color[j] == 0 ) dfs( j );
}
}