#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#define LIB LIB123
#define LIBMAXLEN 1000
#define LIBMAXDWARFES 1000
#define LIBERROR 1254
#define LIBPROT 1324
#define LIBEND 1425
#define LIBINTERNALERROR 4352
#define LIBGREENHAVEWON 7136

char LIBinitialized = 0;

struct LIBlist {
  struct LIBlist *next;
  int i;
}*LIBp;

struct LIBdwarfes {
  int c;
  struct LIBlist *p[2];
}LIBd[LIBMAXDWARFES];

int LIBtype[LIBMAXLEN],LIBf,LIBl,LIBn,LIBact;
char LIBpos[LIBMAXLEN][LIBMAXDWARFES];
int LIBmov[LIBMAXLEN][LIBMAXDWARFES];
int LIBchecksum;

FILE *LIBout;

void LIBreport(int CODE, char *fmt, ...) {
  va_list ap;
  va_start( ap, fmt );

  fprintf( LIBout,"%d ",CODE);
  vfprintf( LIBout, fmt, ap );
  if ( fmt[ strlen(fmt)-1 ] != '\n' ) fprintf(LIBout,"\n");
  if (CODE==LIBERROR||CODE==LIBEND||CODE==LIBINTERNALERROR){
    fclose(LIBout);
    exit (0);
  }
}

void init() {
  int n,l,i,j,p;
  FILE *in = fopen("pearls.in","r");
  LIBout = fopen("pearls.out","w");

  if (!in) LIBreport(LIBERROR, "cannot open pearls.in");
  if (fscanf(in,"%d %d %d",&l,&n,&LIBf)!=3) LIBreport(LIBINTERNALERROR, "error in pearls.in");

  LIBinitialized = 1;
  LIBchecksum = n+l-LIBf;
  LIBact = 0;
  LIBn = n;
  LIBl = l;
  LIBf--;

  LIBreport(LIBPROT, "init()");
  for (i=0; i<l; i++){
    char c;
    if (fscanf(in," %c",&c)!=1 || c!='B' && c!='W' && (i<l-1 || c!='D'))
      LIBreport(LIBERROR,"Error in pearls.in");
    LIBtype[i] = (c == 'W');
  }

  for (i=0; i<n; i++) {
    if (fscanf(in,"%d",&LIBd[i].c)!=1) LIBreport(LIBINTERNALERROR,"Error in pearls.in");
    LIBpos[l-1][i] = LIBd[i].c;
    for (j=0; j<2; j++) {
      int len;
      LIBd[i].p[j] = NULL;
      if (fscanf(in,"%d",&len)!=1) LIBreport(LIBINTERNALERROR,"Error in pearls.in");
      while(len--) {
	int temp;
	if (fscanf(in,"%d",&temp)!=1) LIBreport(LIBINTERNALERROR,"Error in pearls.in");
	LIBp = (struct LIBlist *)malloc(sizeof(struct LIBlist));
	LIBp->i = temp-1;
	LIBp->next = LIBd[i].p[j];
	LIBd[i].p[j] = LIBp;
      }
    }
  }
  fclose(in);

  for (p=l-2; p>=0; p--) {
    int c = LIBtype[p];
    for (i=0; i<n; i++) {
      LIBpos[p][i] = 1-LIBd[i].c;
      LIBp = LIBd[i].p[c];
      while(LIBp!=NULL) {
	LIBmov[p][i] = LIBp->i;
	if (LIBpos[p+1][LIBp->i] == LIBd[i].c){
	  LIBpos[p][i] = LIBd[i].c;
	  break;
	}
	LIBp = LIBp->next;
      }
    }
  }
}

void finish() {
  if (!LIBinitialized) init();
  LIBreport(LIBPROT, "finish()");
  int i;
  if (LIBact!=LIBl-1) LIBreport(LIBERROR,"called finish() but end of game is not reached");
  if (LIBd[LIBf].c==1)
    LIBreport(LIBEND,"red dwarfs have won %d", LIBchecksum);
  LIBreport(LIBEND, "green dwarfs have won %d", LIBchecksum+LIBGREENHAVEWON);
}

int getNext() {
  if (!LIBinitialized) init();
  if (LIBact>=LIBl-1) LIBreport(LIBERROR,"too many calls to getNext()/setNext()");
  if (LIBd[LIBf].c==0)LIBreport(LIBERROR,"called getNext() but %d is a green dwarf", LIBf+1);
  LIBf = LIBmov[LIBact][LIBf];
  LIBreport(LIBPROT, "getNext() -> %d", LIBf+1);
  LIBact++;
  return LIBf+1;
}

void setNext(int dwarfes) {
  if (!LIBinitialized) init();
  if (LIBact>=LIBl-1) LIBreport(LIBERROR,"too many calls to getNext()/setNext()");
  if (LIBd[LIBf].c==1)LIBreport(LIBERROR,"called setNext() but %d is a red dwarf", LIBf+1);
  LIBp = LIBd[LIBf].p[LIBtype[LIBact]];
  while(LIBp!=NULL) {
    if (LIBp->i == dwarfes-1) {
      LIBf = LIBp->i;
      break;
    }
    LIBp = LIBp->next;
  }
  if (LIBp == NULL) {
    LIBreport(LIBERROR, "no dwarf with number %d in list of dwarf %d", dwarfes, LIBf+1);
  }
  LIBreport(LIBPROT, "setNext(%d)", dwarfes);
  LIBact++;
}
