#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define ALL(C)     (C).begin(),(C).end()
#define pb         push_back
#define mp         make_pair

#define TRUE true
#define LIAR false

const int N = 600;

typedef pair<int,int> pii;

class Edge{
public:
  int t;
  bool isyes;
};

vector<Edge> edge[N];
bool vis[N];

void dfs(int now,bool istrue,int &cnt,vector<int> &trueset,int work){
  if (istrue){
    if (work == 0);
    if (work == 1)cnt++;
    if (work == 2)trueset.pb(now);
  }
  vis[now]=true;
  rep(i,edge[now].size()){
    int next=edge[now][i].t;
    if (vis[next])continue;
    if (edge[now][i].isyes)dfs(next,istrue,cnt,trueset,work);
    else dfs(next,!istrue,cnt,trueset,work);
  }
}


int table[1000][1000];
bool path[1000][1000];//used true(first) or liar(second)
vector<int> dp(vector<pii> &in,int numT){
  vector<int> used;
  int n =in.size();
  rep(i,n){
    rep(j,numT+1){
      table[i][j]=0;
      path[i][j]=false;
    }
  }


  table[0][in[0].first]++;
  path[0][in[0].first]=true;
  
  table[0][in[0].second]++;
  path[0][in[0].second]=false;
  
  REP(i,1,n){
    rep(j,numT+1){
      if (j-in[i].first>=0 &&table[i-1][j-in[i].first]){
	table[i][j]+=table[i-1][j-in[i].first];
	path[i][j]=true;
      }
      if (j-in[i].second>=0&&table[i-1][j-in[i].second]){
	table[i][j]+=table[i-1][j-in[i].second];
	path[i][j]=false;
      }
    }
  }
  

  if (table[n-1][numT] != 1){
    used.clear();
    return used;
  }

  int i=n-1,j=numT;
  while(i >=0){
    if (path[i][j] == true)j=j-in[i].first,used.pb(1);
    else j=j-in[i].second,used.pb(0);
    i--;
  }
  
  reverse(ALL(used));
  return used;
}

void solve(int n,int numT){
  //exceptional
  /*
  if (numT == n){
    rep(i,n)cout <<i+1<<endl;
    cout << "end"<<endl;
    return;
  }
  if (numT == 0){
    cout <<"end"<<endl;
  }
  */

  rep(i,n)vis[i]=false;
  int cnt=0;
  vector<int> dummy;
  vector<int> root;
  vector<pii> data;
  
  rep(i,n){
    if (vis[i])continue;
    root.pb(i);
    dfs(i,TRUE,cnt,dummy,0);
  }
  
  rep(i,root.size()){
    pii ins;
    int tmp=0;
    //root[i]=true
    rep(j,n)vis[j]=false;
    tmp=0;
    dfs(root[i],TRUE,tmp,dummy,1);
    ins.first=tmp;
    //root[i]=liar
    rep(j,n)vis[j]=false;
    tmp=0;
    dfs(root[i],LIAR,tmp,dummy,1);
    ins.second=tmp;
    data.pb(ins);
  }
  
  //check the "data"


  vector<int> rootset=  dp(data,numT);

  //if number of devine and devilish are same for some 
  //connected component, no answer
  if (rootset.size() == 0){
    cout <<"no"<<endl;
    return;
  }
  
  rep(i,n)vis[i]=false;
  
  vector<int>trueset;
  rep(i,rootset.size()){
    dfs(root[i],rootset[i]==1,cnt,trueset,2);
  }

  sort(ALL(trueset));
  rep(i,trueset.size()){
    cout << trueset[i]+1 << endl;
  }
  cout <<"end"<<endl;
  return;
}


main(){
  int m,p1,p2;
  while(cin>>m>>p1>>p2 ){
    if (m == 0 && p1 == 0 && p2 == 0)break;
    int n=p1+p2;
    rep(i,n)edge[i].clear();
    
    rep(i,m){
      int f,t;
      string q;
      bool isyes;
      cin>>f>>t>>q;
      f--;t--;
      if (q =="yes")isyes=true;
      else isyes=false;
      edge[f].pb((Edge){t,isyes});
      edge[t].pb((Edge){f,isyes});
    }

    solve(n,p1);
  }
  return false;
}

Measured memory_bytes: 0