import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author __shangu__
 */
public class Main {
  public static void main(String[] args) {
    InputStream inputStream = System.in;
    OutputStream outputStream = System.out;
    InputReader in = new InputReader(inputStream);
    PrintWriter out = new PrintWriter(outputStream);
    DThreeReligions solver = new DThreeReligions();
    solver.solve(1, in, out);
    out.close();
  }

  static class DThreeReligions {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
      int n = in.nextInt(), nop = in.nextInt();
      String ln = in.nextLine();
      int[] lastocc = new int[30];
      int[][] nextocc = new int[n + 1][30];
      Arrays.fill(lastocc, Integer.MAX_VALUE);
      for (int i = n - 1; i >= 0; --i) {
        nextocc[i + 1] = lastocc.clone();
        lastocc[ln.charAt(i) - 'a'] = i + 1;
      }
      nextocc[0] = lastocc.clone();

      StringBuilder word[] = new StringBuilder[3];
      int[][][] dp = new int[260][260][260];
      int[] len = new int[3];
      for (int i = 0; i < 3; ++i) word[i] = new StringBuilder();
      for (int i = 0; i < nop; ++i) {
        char op = in.next().charAt(0);
        int rel = in.nextInt() - 1;
        if (op == '-') {
          word[rel].deleteCharAt(word[rel].length() - 1);
          --len[rel];
          out.println(dp[len[0]][len[1]][len[2]] == Integer.MAX_VALUE ? "NO" : "YES");
        } else {
          char ch = in.next().charAt(0);
          ++len[rel];
          word[rel].append(ch);
          switch (rel) {
            case 0:
              for (int j = 0; j <= len[1]; ++j) {
                for (int k = 0; k <= len[2]; ++k) {
                  int a = dp[len[0] - 1][j][k] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[len[0] - 1][j][k]][word[0].charAt(len[0] - 1) - 'a'];
                  int b = k == 0 || dp[len[0]][j][k - 1] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[len[0]][j][k - 1]][word[2].charAt(k - 1) - 'a'];
                  int c = j == 0 || dp[len[0]][j - 1][k] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[len[0]][j - 1][k]][word[1].charAt(j - 1) - 'a'];
                  dp[len[0]][j][k] = Integer.min(a, Integer.min(b, c));
                }
              }
              break;
            case 1:
//            dp[0][len[1]][0] = dp[0][len[1] - 1][0] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[0][len[1] - 1][0]][i1];
              for (int j = 0; j <= len[0]; ++j) {
                for (int k = 0; k <= len[2]; ++k) {
                  int a = dp[j][len[1] - 1][k] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[j][len[1] - 1][k]][word[1].charAt(len[1] - 1) - 'a'];
                  int b = k == 0 || dp[j][len[1]][k - 1] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[j][len[1]][k - 1]][word[2].charAt(k - 1) - 'a'];
                  int c = j == 0 || dp[j - 1][len[1]][k] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[j - 1][len[1]][k]][word[0].charAt(j - 1) - 'a'];
                  dp[j][len[1]][k] = Integer.min(a, Integer.min(b, c));
                }
              }
              break;
            default:
//            dp[0][0][len[2]] = dp[0][0][len[2] - 1] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[0][0][len[2] - 1]][i1];
              for (int j = 0; j <= len[0]; ++j) {
                for (int k = 0; k <= len[1]; ++k) {
                  int a = dp[j][k][len[2] - 1] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[j][k][len[2] - 1]][word[2].charAt(len[2] - 1) - 'a'];
                  int b = k == 0 || dp[j][k - 1][len[2]] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[j][k - 1][len[2]]][word[1].charAt(k - 1) - 'a'];
                  int c = j == 0 || dp[j - 1][k][len[2]] == Integer.MAX_VALUE ? Integer.MAX_VALUE : nextocc[dp[j - 1][k][len[2]]][word[0].charAt(j - 1) - 'a'];
                  dp[j][k][len[2]] = Integer.min(a, Integer.min(b, c));
                }
              }
          }
          out.println(dp[len[0]][len[1]][len[2]] == Integer.MAX_VALUE ? "NO" : "YES");
        }
      }
    }

  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
      reader = new BufferedReader(new InputStreamReader(stream), 32768);
      tokenizer = null;
    }

    public String next() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          tokenizer = new StringTokenizer(reader.readLine());
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
      return tokenizer.nextToken();
    }

    public int nextInt() {
      return Integer.parseInt(next());
    }

    public String nextLine() {
      String str = "";
      try {
        str = reader.readLine();
      } catch (IOException e) {
        e.printStackTrace();
      }
      return str;
    }

  }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[n+1][26];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=new char[n];
        in.next(s);
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<26;j++) next[i][j]=bs(pos[j],i);
        }

        int[][][]dp=new int[300][300][300];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;

        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.nextChar()=='+'){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.nextChar();
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            dp[i][j][k]=0x3f3f3f3f;
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i-1][j][k]][a[1][i-1]-'a']);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j-1][k]][a[2][j-1]-'a']);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j][k-1]][a[3][k-1]-'a']);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    int bs(ArrayList<Integer>b,int pos){
        if(b.size()==0)return 0x3f3f3f3f;
        int l=0,r=b.size()-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(b.get(mid)<=pos)l=mid+1;
            else r=mid;
        }
        if(b.get(l)<=pos)return 0x3f3f3f3f;
        else return b.get(l);
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }*/
    class InputReader implements Closeable {
        private InputStreamReader reader;
        private char[] buf;
        private int len, now;

        public InputReader(InputStream stream) {
            reader = new InputStreamReader(stream);
            buf = new char[1024];
            len = 0;
            now = 0;
        }

        public String next() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (!isSpaceChar(buf[now])) {
                sb.append(buf[now]);
                if (!move()) break;
            }
            return sb.toString();
        }

        public int next(char[] s) throws IOException {
            if (!hasNext()) throw new NullPointerException();
            int len = 0;
            while (!isSpaceChar(buf[now]) && len < s.length) {
                s[len++] = buf[now];
                if (!move()) break;
            }
            return len;
        }

        public int nextInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public long nextLong() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            long ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public int nextHexInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isHex(buf[now])) ans = (ans << 4) + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public char nextChar() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            char tmp = buf[now];
            move();
            return tmp;
        }

        public String nextLine() throws IOException {
            if (!hasNextLine()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (buf[now] != '\n') {
                sb.append(buf[now]);
                if (!move()) return sb.toString();
            }
            now++;
            return sb.toString();
        }

        public boolean hasNext() throws IOException {
            return skip();
        }

        public boolean hasNextLine() throws IOException {
            return now < len || refill();
        }

        public void close() throws IOException {
            reader.close();
        }

        private boolean move() throws IOException {
            now++;
            return hasNextLine();
        }

        private boolean skip() throws IOException {
            if (!hasNextLine()) return false;
            while (isSpaceChar(buf[now])) {
                if (!move()) return false;
            }
            return true;
        }

        private boolean isSpaceChar(char c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isNum(char c) {
            return c >= '0' && c <= '9';
        }

        private boolean isHex(char c) {
            return c >= '0' && c <= '9' || c >= 'A' && c <= 'F';
        }

        private int toNum(char c) {
            if (c >= '0' && c <= '9') return c - '0';
            else if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
            else return c - 'a' + 10;
        }

        private boolean refill() throws IOException {
            len = reader.read(buf);
            now = 0;
            return len > 0;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[n+1][26];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=in.next().toCharArray();
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<26;j++) next[i][j]=bs(pos[j],i);
        }

        int[][][]dp=new int[300][300][300];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;

        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.next().equals("+")){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.next().charAt(0);
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i-1][j][k]][a[1][i-1]-'a']);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j-1][k]][a[2][j-1]-'a']);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j][k-1]][a[3][k-1]-'a']);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            dp[i][j][k]=0x3f3f3f3f;
                        }
                    }
                }
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    int bs(ArrayList<Integer>b,int pos){
        if(b.size()==0)return 0x3f3f3f3f;
        int l=0,r=b.size()-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(b.get(mid)<=pos)l=mid+1;
            else r=mid;
        }
        if(b.get(l)<=pos)return 0x3f3f3f3f;
        else return b.get(l);
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[n+1][26];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=in.next().toCharArray();
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<26;j++) next[i][j]=bs(pos[j],i);
        }
        for(int i=0;i<q;i++){
            if(in.next().equals("+")){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.next().charAt(0);
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(judge())out.println("YES");
            else out.print("NO");
        }
        out.flush();
    }
    boolean judge(){
        /*
        int[]now=new int[4];
        int cur=0;
        ArrayList<State>jump=new ArrayList<>(),j1=new ArrayList<>();
        while (now[1]<len[1]||now[2]<len[2]||now[3]<len[3]){
            jump.clear();
            j1.clear();
            if(now[1]<len[1])jump.add(new State(1,next[cur][a[1][now[1]]],now[1]+1));
            if(now[2]<len[2])jump.add(new State(2,next[cur][a[2][now[2]]],now[2]+1));
            if(now[3]<len[3])jump.add(new State(3,next[cur][a[3][now[3]]],now[3]+1));
            Collections.sort(jump);
            if(jump.get(0).s==-1)return false;
        }
        */
        int[][][]dp=new int[len[1]+1][len[2]+1][len[3]+1];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;
        for(int i=0;i<=len[1];i++){
            for(int j=0;j<=len[2];j++){
                for(int k=0;k<=len[3];k++){
                    if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i-1][j][k]][a[1][i-1]-'a']);
                    if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j-1][k]][a[2][j-1]-'a']);
                    if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j][k-1]][a[3][k-1]-'a']);
                }
            }
        }
        return dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f;
    }
    int bs(ArrayList<Integer>b,int pos){
        if(b.size()==0)return 0x3f3f3f3f;
        int l=0,r=b.size()-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(b.get(mid)<pos)l=mid+1;
            else r=mid;
        }
        if(b.get(l)<pos)return 0x3f3f3f3f;
        else return b.get(l);
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[n+1][26];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=in.next().toCharArray();
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<26;j++) next[i][j]=bs(pos[j],i);
        }

        int[][][]dp=new int[300][300][300];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;

        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.next().equals("+")){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.next().charAt(0);
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i-1][j][k]][a[1][i-1]-'a']);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j-1][k]][a[2][j-1]-'a']);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j][k-1]][a[3][k-1]-'a']);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    int bs(ArrayList<Integer>b,int pos){
        if(b.size()==0)return 0x3f3f3f3f;
        int l=0,r=b.size()-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(b.get(mid)<=pos)l=mid+1;
            else r=mid;
        }
        if(b.get(l)<=pos)return 0x3f3f3f3f;
        else return b.get(l);
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[n+1][26];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=in.next().toCharArray();
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<26;j++) next[i][j]=bs(pos[j],i);
        }
        for(int i=0;i<q;i++){
            if(in.next().equals("+")){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.next().charAt(0);
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(judge())out.println("YES");
            else out.print("NO");
        }
        out.flush();
    }
    boolean judge(){
        /*
        int[]now=new int[4];
        int cur=0;
        ArrayList<State>jump=new ArrayList<>(),j1=new ArrayList<>();
        while (now[1]<len[1]||now[2]<len[2]||now[3]<len[3]){
            jump.clear();
            j1.clear();
            if(now[1]<len[1])jump.add(new State(1,next[cur][a[1][now[1]]],now[1]+1));
            if(now[2]<len[2])jump.add(new State(2,next[cur][a[2][now[2]]],now[2]+1));
            if(now[3]<len[3])jump.add(new State(3,next[cur][a[3][now[3]]],now[3]+1));
            Collections.sort(jump);
            if(jump.get(0).s==-1)return false;
        }
        */
        int[][][]dp=new int[len[1]+1][len[2]+1][len[3]+1];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;
        for(int i=0;i<=len[1];i++){
            for(int j=0;j<=len[2];j++){
                for(int k=0;k<=len[3];k++){
                    if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i-1][j][k]][a[1][i]-'a']);
                    if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j-1][k]][a[2][j]-'a']);
                    if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j][k-1]][a[3][k]-'a']);
                }
            }
        }
        return dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f;
    }
    int bs(ArrayList<Integer>b,int pos){
        if(b.size()==0)return 0x3f3f3f3f;
        int l=0,r=b.size()-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(b.get(mid)<pos)l=mid+1;
            else r=mid;
        }
        if(b.get(l)<pos)return 0x3f3f3f3f;
        else return b.get(l);
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[n+1][26];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=in.next().toCharArray();
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        for(int i=0;i<=n;i++){
            for(int j=0;j<26;j++) next[i][j]=bs(pos[j],i);
        }
        for(int i=0;i<q;i++){
            if(in.next().equals("+")){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.next().charAt(0);
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(judge())out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    boolean judge(){
        /*
        int[]now=new int[4];
        int cur=0;
        ArrayList<State>jump=new ArrayList<>(),j1=new ArrayList<>();
        while (now[1]<len[1]||now[2]<len[2]||now[3]<len[3]){
            jump.clear();
            j1.clear();
            if(now[1]<len[1])jump.add(new State(1,next[cur][a[1][now[1]]],now[1]+1));
            if(now[2]<len[2])jump.add(new State(2,next[cur][a[2][now[2]]],now[2]+1));
            if(now[3]<len[3])jump.add(new State(3,next[cur][a[3][now[3]]],now[3]+1));
            Collections.sort(jump);
            if(jump.get(0).s==-1)return false;
        }
        */
        int[][][]dp=new int[len[1]+1][len[2]+1][len[3]+1];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;
        for(int i=0;i<=len[1];i++){
            for(int j=0;j<=len[2];j++){
                for(int k=0;k<=len[3];k++){
                    if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i-1][j][k]][a[1][i-1]-'a']);
                    if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j-1][k]][a[2][j-1]-'a']);
                    if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[dp[i][j][k-1]][a[3][k-1]-'a']);
                }
            }
        }
        return dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f;
    }
    int bs(ArrayList<Integer>b,int pos){
        if(b.size()==0)return 0x3f3f3f3f;
        int l=0,r=b.size()-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(b.get(mid)<=pos)l=mid+1;
            else r=mid;
        }
        if(b.get(l)<=pos)return 0x3f3f3f3f;
        else return b.get(l);
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[26][n+1];
        char[]s=new char[n];
        in.next(s);
        int[]last=new int[26];
        Arrays.fill(last,0x3f3f3f3f);
        for(int i=n;i>=0;i--){
            for(int j=0;j<26;j++) next[j][i]=last[j];
            if(i>0)
            last[s[i-1]-'a']=i;
        }

        int[][][]dp=new int[300][300][300];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;

        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.nextChar()=='+'){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.nextChar();
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            dp[i][j][k]=0x3f3f3f3f;
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[1][i-1]-'a'][dp[i-1][j][k]]);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[2][j-1]-'a'][dp[i][j-1][k]]);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[3][k-1]-'a'][dp[i][j][k-1]]);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }*/
    class InputReader implements Closeable {
        private InputStreamReader reader;
        private char[] buf;
        private int len, now;

        public InputReader(InputStream stream) {
            reader = new InputStreamReader(stream);
            buf = new char[1024];
            len = 0;
            now = 0;
        }

        public String next() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (!isSpaceChar(buf[now])) {
                sb.append(buf[now]);
                if (!move()) break;
            }
            return sb.toString();
        }

        public int next(char[] s) throws IOException {
            if (!hasNext()) throw new NullPointerException();
            int len = 0;
            while (!isSpaceChar(buf[now]) && len < s.length) {
                s[len++] = buf[now];
                if (!move()) break;
            }
            return len;
        }

        public int nextInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public long nextLong() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            long ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public int nextHexInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isHex(buf[now])) ans = (ans << 4) + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public char nextChar() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            char tmp = buf[now];
            move();
            return tmp;
        }

        public String nextLine() throws IOException {
            if (!hasNextLine()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (buf[now] != '\n') {
                sb.append(buf[now]);
                if (!move()) return sb.toString();
            }
            now++;
            return sb.toString();
        }

        public boolean hasNext() throws IOException {
            return skip();
        }

        public boolean hasNextLine() throws IOException {
            return now < len || refill();
        }

        public void close() throws IOException {
            reader.close();
        }

        private boolean move() throws IOException {
            now++;
            return hasNextLine();
        }

        private boolean skip() throws IOException {
            if (!hasNextLine()) return false;
            while (isSpaceChar(buf[now])) {
                if (!move()) return false;
            }
            return true;
        }

        private boolean isSpaceChar(char c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isNum(char c) {
            return c >= '0' && c <= '9';
        }

        private boolean isHex(char c) {
            return c >= '0' && c <= '9' || c >= 'A' && c <= 'F';
        }

        private int toNum(char c) {
            if (c >= '0' && c <= '9') return c - '0';
            else if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
            else return c - 'a' + 10;
        }

        private boolean refill() throws IOException {
            len = reader.read(buf);
            now = 0;
            return len > 0;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    ArrayList<Integer>pos[]=new ArrayList[26];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[26][n+1];
        for(int i=0;i<26;i++)pos[i]=new ArrayList<>();
        char[]s=new char[n];
        in.next(s);
        for(int i=0;i<n;i++){
            pos[s[i]-'a'].add(i+1);
        }
        int[]last=new int[26];
        Arrays.fill(last,0x3f3f3f3f);
        for(int i=n;i>=0;i--){
            for(int j=0;j<26;j++) next[j][i]=last[j];
            if(i>0)
            last[s[i-1]-'a']=i;
        }

        int[][][]dp=new int[300][300][300];
        for(int[][]x:dp){
            for(int[]y:x)Arrays.fill(y,0x3f3f3f3f);
        }
        dp[0][0][0]=0;

        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.nextChar()=='+'){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.nextChar();
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            dp[i][j][k]=0x3f3f3f3f;
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[1][i-1]-'a'][dp[i-1][j][k]]);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[2][j-1]-'a'][dp[i][j-1][k]]);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[3][k-1]-'a'][dp[i][j][k-1]]);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }*/
    class InputReader implements Closeable {
        private InputStreamReader reader;
        private char[] buf;
        private int len, now;

        public InputReader(InputStream stream) {
            reader = new InputStreamReader(stream);
            buf = new char[1024];
            len = 0;
            now = 0;
        }

        public String next() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (!isSpaceChar(buf[now])) {
                sb.append(buf[now]);
                if (!move()) break;
            }
            return sb.toString();
        }

        public int next(char[] s) throws IOException {
            if (!hasNext()) throw new NullPointerException();
            int len = 0;
            while (!isSpaceChar(buf[now]) && len < s.length) {
                s[len++] = buf[now];
                if (!move()) break;
            }
            return len;
        }

        public int nextInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public long nextLong() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            long ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public int nextHexInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isHex(buf[now])) ans = (ans << 4) + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public char nextChar() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            char tmp = buf[now];
            move();
            return tmp;
        }

        public String nextLine() throws IOException {
            if (!hasNextLine()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (buf[now] != '\n') {
                sb.append(buf[now]);
                if (!move()) return sb.toString();
            }
            now++;
            return sb.toString();
        }

        public boolean hasNext() throws IOException {
            return skip();
        }

        public boolean hasNextLine() throws IOException {
            return now < len || refill();
        }

        public void close() throws IOException {
            reader.close();
        }

        private boolean move() throws IOException {
            now++;
            return hasNextLine();
        }

        private boolean skip() throws IOException {
            if (!hasNextLine()) return false;
            while (isSpaceChar(buf[now])) {
                if (!move()) return false;
            }
            return true;
        }

        private boolean isSpaceChar(char c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isNum(char c) {
            return c >= '0' && c <= '9';
        }

        private boolean isHex(char c) {
            return c >= '0' && c <= '9' || c >= 'A' && c <= 'F';
        }

        private int toNum(char c) {
            if (c >= '0' && c <= '9') return c - '0';
            else if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
            else return c - 'a' + 10;
        }

        private boolean refill() throws IOException {
            len = reader.read(buf);
            now = 0;
            return len > 0;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[26][n+1];
        char[]s=new char[n];
        in.next(s);
        int[]last=new int[26];
        Arrays.fill(last,0x3f3f3f3f);
        for(int i=n;i>=0;i--){
            for(int j=0;j<26;j++) next[j][i]=last[j];
            if(i>0)
            last[s[i-1]-'a']=i;
        }

        int[][][]dp=new int[251][251][251];
        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.nextChar()=='+'){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.nextChar();
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            dp[i][j][k]=0x3f3f3f3f;
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[1][i-1]-'a'][dp[i-1][j][k]]);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[2][j-1]-'a'][dp[i][j-1][k]]);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[3][k-1]-'a'][dp[i][j][k-1]]);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }*/
    class InputReader implements Closeable {
        private InputStreamReader reader;
        private char[] buf;
        private int len, now;

        public InputReader(InputStream stream) {
            reader = new InputStreamReader(stream);
            buf = new char[1024*1024];
            len = 0;
            now = 0;
        }

        public String next() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (!isSpaceChar(buf[now])) {
                sb.append(buf[now]);
                if (!move()) break;
            }
            return sb.toString();
        }

        public int next(char[] s) throws IOException {
            if (!hasNext()) throw new NullPointerException();
            int len = 0;
            while (!isSpaceChar(buf[now]) && len < s.length) {
                s[len++] = buf[now];
                if (!move()) break;
            }
            return len;
        }

        public int nextInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public long nextLong() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            long ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public int nextHexInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isHex(buf[now])) ans = (ans << 4) + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public char nextChar() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            char tmp = buf[now];
            move();
            return tmp;
        }

        public String nextLine() throws IOException {
            if (!hasNextLine()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (buf[now] != '\n') {
                sb.append(buf[now]);
                if (!move()) return sb.toString();
            }
            now++;
            return sb.toString();
        }

        public boolean hasNext() throws IOException {
            return skip();
        }

        public boolean hasNextLine() throws IOException {
            return now < len || refill();
        }

        public void close() throws IOException {
            reader.close();
        }

        private boolean move() throws IOException {
            now++;
            return hasNextLine();
        }

        private boolean skip() throws IOException {
            if (!hasNextLine()) return false;
            while (isSpaceChar(buf[now])) {
                if (!move()) return false;
            }
            return true;
        }

        private boolean isSpaceChar(char c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isNum(char c) {
            return c >= '0' && c <= '9';
        }

        private boolean isHex(char c) {
            return c >= '0' && c <= '9' || c >= 'A' && c <= 'F';
        }

        private int toNum(char c) {
            if (c >= '0' && c <= '9') return c - '0';
            else if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
            else return c - 'a' + 10;
        }

        private boolean refill() throws IOException {
            len = reader.read(buf);
            now = 0;
            return len > 0;
        }
    }
}


import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int[][]next;
    char[][]a=new char[4][300];
    int[]len=new int[4];
    int n;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();int q=in.nextInt();
        next=new int[26][n+1];
        char[]s=new char[n];
        in.next(s);
        int[]last=new int[26];
        Arrays.fill(last,0x3f3f3f3f);
        for(int i=n;i>=0;i--){
            for(int j=0;j<26;j++) next[j][i]=last[j];
            if(i>0)
            last[s[i-1]-'a']=i;
        }

        int[][][]dp=new int[251][251][251];
        int i,j,k;
        for(int t=0;t<q;t++){
            if(in.nextChar()=='+'){
                int tmp=in.nextInt();
                a[tmp][len[tmp]++]=in.nextChar();
                for(i=tmp==1?len[tmp]:0;i<=len[1];i++){
                    for(j=tmp==2?len[tmp]:0;j<=len[2];j++){
                        for(k=tmp==3?len[tmp]:0;k<=len[3];k++){
                            dp[i][j][k]=0x3f3f3f3f;
                            if(i>0&&dp[i-1][j][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[1][i-1]-'a'][dp[i-1][j][k]]);
                            if(j>0&&dp[i][j-1][k]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[2][j-1]-'a'][dp[i][j-1][k]]);
                            if(k>0&&dp[i][j][k-1]!=0x3f3f3f3f) dp[i][j][k]=Math.min(dp[i][j][k],next[a[3][k-1]-'a'][dp[i][j][k-1]]);
                        }
                    }
                }
            }else {
                int tmp=in.nextInt();
                len[tmp]--;
            }
            if(dp[len[1]][len[2]][len[3]]!=0x3f3f3f3f)out.println("YES");
            else out.println("NO");
        }
        out.flush();
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }*/
    class InputReader implements Closeable {
        private InputStreamReader reader;
        private char[] buf;
        private int len, now;

        public InputReader(InputStream stream) {
            reader = new InputStreamReader(stream);
            buf = new char[1024];
            len = 0;
            now = 0;
        }

        public String next() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (!isSpaceChar(buf[now])) {
                sb.append(buf[now]);
                if (!move()) break;
            }
            return sb.toString();
        }

        public int next(char[] s) throws IOException {
            if (!hasNext()) throw new NullPointerException();
            int len = 0;
            while (!isSpaceChar(buf[now]) && len < s.length) {
                s[len++] = buf[now];
                if (!move()) break;
            }
            return len;
        }

        public int nextInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public long nextLong() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            long ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isNum(buf[now])) ans = ans * 10 + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public int nextHexInt() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            boolean x = false;
            if (buf[now] == '-') {
                x = true;
                if (!move()) throw new NumberFormatException();
            }
            int ans = 0;
            while (!isSpaceChar(buf[now])) {
                if (isHex(buf[now])) ans = (ans << 4) + toNum(buf[now]);
                else throw new NumberFormatException();
                if (!move()) break;
            }
            return (x ? -1 : 1) * ans;
        }

        public char nextChar() throws IOException {
            if (!hasNext()) throw new NullPointerException();
            char tmp = buf[now];
            move();
            return tmp;
        }

        public String nextLine() throws IOException {
            if (!hasNextLine()) throw new NullPointerException();
            StringBuilder sb = new StringBuilder();
            while (buf[now] != '\n') {
                sb.append(buf[now]);
                if (!move()) return sb.toString();
            }
            now++;
            return sb.toString();
        }

        public boolean hasNext() throws IOException {
            return skip();
        }

        public boolean hasNextLine() throws IOException {
            return now < len || refill();
        }

        public void close() throws IOException {
            reader.close();
        }

        private boolean move() throws IOException {
            now++;
            return hasNextLine();
        }

        private boolean skip() throws IOException {
            if (!hasNextLine()) return false;
            while (isSpaceChar(buf[now])) {
                if (!move()) return false;
            }
            return true;
        }

        private boolean isSpaceChar(char c) {
            return !(c >= 33 && c <= 126);
        }

        private boolean isNum(char c) {
            return c >= '0' && c <= '9';
        }

        private boolean isHex(char c) {
            return c >= '0' && c <= '9' || c >= 'A' && c <= 'F';
        }

        private int toNum(char c) {
            if (c >= '0' && c <= '9') return c - '0';
            else if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
            else return c - 'a' + 10;
        }

        private boolean refill() throws IOException {
            len = reader.read(buf);
            now = 0;
            return len > 0;
        }
    }
}


import java.io.*;
import java.util.*;

public class D {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Solver solver = new Solver();
        solver.solve(in, out);
        out.close();
    }

    private static class Solver {

        private int[][][] dp;
        private StringBuilder[] rels;
        private int inf = 123456789;

        private int min(int a, int b) {
            return a > b ? b : a;
        }

        private void solve(InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int q = in.nextInt();

            char[] s = in.next().toCharArray();

            int[][] nxt = new int[n + 1][26];
            for (int i = 0; i < 26; i++)
                nxt[n][i] = inf;

            for (int i = n - 1; i >= 0; i--) {
                for (int j = 0; j < 26; j++)
                    nxt[i][j] = nxt[i + 1][j];

                nxt[i][s[i] - 'a'] = i + 1;
            }

            dp = new int[256][256][256];

            rels = new StringBuilder[4];
            for (int i = 1; i <= 3; i++)
                rels[i] = new StringBuilder();

            while (q-- > 0) {
                char t = in.next().charAt(0);
                int r = in.nextInt();

                if (t == '+') {
                    rels[r].append(in.next().charAt(0));

                    int mini = r == 1 ? rels[r].length() : 0;
                    int minj = r == 2 ? rels[r].length() : 0;
                    int mink = r == 3 ? rels[r].length() : 0;
                    for (int i = mini; i <= rels[1].length(); i++) {
                        for (int j = minj; j <= rels[2].length(); j++) {
                            for (int k = mink; k <= rels[3].length(); k++) {
                                dp[i][j][k] = inf;
                                if (i > 0 && dp[i - 1][j][k] != inf)
                                    dp[i][j][k] = min(dp[i][j][k], nxt[dp[i - 1][j][k]][rels[1].charAt(i - 1) - 'a']);
                                if (j > 0 && dp[i][j - 1][k] != inf)
                                    dp[i][j][k] = min(dp[i][j][k], nxt[dp[i][j - 1][k]][rels[2].charAt(j - 1) - 'a']);
                                if (k > 0 && dp[i][j][k - 1] != inf)
                                    dp[i][j][k] = min(dp[i][j][k], nxt[dp[i][j][k - 1]][rels[3].charAt(k - 1) - 'a']);
                            }
                        }
                    }
                } else {
                    rels[r].deleteCharAt(rels[r].length() - 1);
                }

                if (dp[rels[1].length()][rels[2].length()][rels[3].length()] != inf) {
                    out.println("YES");
                } else {
                    out.println("NO");
                }
            }
        }
    }

    private static class InputReader {
        private BufferedReader br;
        private StringTokenizer st;

        public InputReader(InputStream stream) {
            br = new BufferedReader(new InputStreamReader(stream));
        }

        private int nextInt() {
            return Integer.parseInt(next());
        }

        private long nextLong() {
            return Long.parseLong(next());
        }

        private double nextDouble() {
            return Double.parseDouble(next());
        }

        private String nextLine() {
            String s = "";
            try {
                s = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return s;
        }

        private String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static String str;
	public static int[][] nexts;
	public static int[] lasts;
	public static int N, Q;

	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		N = s.nextInt();
		Q = s.nextInt();
		str = s.next();
		nexts = new int[26][N + 3];
		lasts = new int[26];
		Arrays.fill(lasts, N + 2);
		for (int k = 0; k < 26; k++) {
			nexts[k][N + 2] = lasts[k];
			nexts[k][N + 1] = lasts[k];
		}
		for (int i = N; i >= 1; i--) {
			char c = str.charAt(i - 1);
			lasts[c - 'a'] = i;
			for (int k = 0; k < 26; k++) {
				nexts[k][i] = lasts[k];
			}
		}
		for (int k = 0; k < 26; k++) {
			nexts[k][0] = lasts[k];
		}
		int[][][] dp = new int[252][252][252];
		String A = "";
		String B = "";
		String C = "";
		StringBuilder sb = new StringBuilder();
		for (int iter = 0; iter < Q; iter++) {
			String type = s.next();
			int number = s.nextInt();
			if (type.charAt(0) == '+') {
				String letter = s.next();
				if (number == 1) {
					A += letter;
				} else if (number == 2) {
					B += letter;
				} else {
					C += letter;
				}
			} else {
				if (number == 1) {
					A = A.substring(0, A.length() - 1);
				} else if (number == 2) {
					B = B.substring(0, B.length() - 1);
				} else {
					C = C.substring(0, C.length() - 1);
				}
			}
			int lengthA = A.length();
			int lengthB = B.length();
			int lengthC = C.length();
			if (type.charAt(0) == '+') {
				if (number == 1) {
					for (int a = lengthA; a <= lengthA; a++) {
						for (int b = 0; b <= lengthB; b++) {
							for (int c = 0; c <= lengthC; c++) {
								if (a == 0 && b == 0 && c == 0) {
									continue;
								}
								int min = N + 1;
								if (a > 0) {
									min = Math.min(min, nexts[A.charAt(a - 1) - 'a'][dp[a - 1][b][c] + 1]);
								}
								if (b > 0) {
									min = Math.min(min, nexts[B.charAt(b - 1) - 'a'][dp[a][b - 1][c] + 1]);
								}
								if (c > 0) {
									min = Math.min(min, nexts[C.charAt(c - 1) - 'a'][dp[a][b][c - 1] + 1]);
								}
								dp[a][b][c] = min;
							}
						}
					}
				} else if (number == 2) {
					for (int a = 0; a <= lengthA; a++) {
						for (int b = lengthB; b <= lengthB; b++) {
							for (int c = 0; c <= lengthC; c++) {
								if (a == 0 && b == 0 && c == 0) {
									continue;
								}
								int min = N + 1;
								if (a > 0) {
									min = Math.min(min, nexts[A.charAt(a - 1) - 'a'][dp[a - 1][b][c] + 1]);
								}
								if (b > 0) {
									min = Math.min(min, nexts[B.charAt(b - 1) - 'a'][dp[a][b - 1][c] + 1]);
								}
								if (c > 0) {
									min = Math.min(min, nexts[C.charAt(c - 1) - 'a'][dp[a][b][c - 1] + 1]);
								}
								dp[a][b][c] = min;
							}
						}
					}
				} else {
					for (int a = 0; a <= lengthA; a++) {
						for (int b = 0; b <= lengthB; b++) {
							for (int c = lengthC; c <= lengthC; c++) {
								if (a == 0 && b == 0 && c == 0) {
									continue;
								}
								int min = N + 1;
								if (a > 0) {
									min = Math.min(min, nexts[A.charAt(a - 1) - 'a'][dp[a - 1][b][c] + 1]);
								}
								if (b > 0) {
									min = Math.min(min, nexts[B.charAt(b - 1) - 'a'][dp[a][b - 1][c] + 1]);
								}
								if (c > 0) {
									min = Math.min(min, nexts[C.charAt(c - 1) - 'a'][dp[a][b][c - 1] + 1]);
								}
								dp[a][b][c] = min;
							}
						}
					}
				}
			}
			if (dp[lengthA][lengthB][lengthC] < N + 1) {
				sb.append("YES").append("\n");
			} else {
				sb.append("NO").append("\n");
			}
		}
		System.out.print(sb.toString());
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.ArrayList;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        private int[][][] dp;
        private int[][] charStats;
        private ArrayList<Character>[] religions;
        private int wordLen;

        public void solve(int testNumber, Scanner in, PrintWriter out) {
            wordLen = in.nextInt();
            int evoCount = in.nextInt();
            String word = in.next();

            charStats = new int[wordLen + 2][26];

            for (int ch = 0; ch < 26; ch++) {
                charStats[wordLen][ch] = wordLen;
                charStats[wordLen + 1][ch] = wordLen;
                for (int i = wordLen - 1; i >= 0; i--) {
                    if (word.charAt(i) == 'a' + ch) {
                        charStats[i][ch] = i;
                    } else {
                        charStats[i][ch] = charStats[i + 1][ch];
                    }
                }
            }

            int maxReligionLen = 251;
            dp = new int[maxReligionLen][maxReligionLen][maxReligionLen];
            dp[0][0][0] = -1;

            religions = new ArrayList[3];
            for (int i = 0; i < religions.length; i++) {
                religions[i] = new ArrayList<>();
            }

            while (evoCount > 0) {
                evoCount--;

                String sign = in.next();
                int religionId = in.nextInt() - 1;
                ArrayList<Character> modReligion = religions[religionId];
                if (sign.equals("+")) {
                    char newChar = in.next().charAt(0);

                    modReligion.add(newChar);

                    int r0Len = religions[0].size();
                    int r1Len = religions[1].size();
                    int r2Len = religions[2].size();

                    int[] mod = new int[]{1, 1, 1};
                    mod[religionId] = 0;
                    for (int r0 = mod[0] == 0 ? r0Len : 0; r0 <= r0Len; r0++) {
                        for (int r1 = mod[1] == 0 ? r1Len : 0; r1 <= r1Len; r1++) {
                            for (int r2 = mod[2] == 0 ? r2Len : 0; r2 <= r2Len; r2++) {
                                recompute(r0, r1, r2);
                            }
                        }
                    }

//                if (religionId == 0) {
//
//                    for (int r1 = 0; r1 <= r1Len; r1++) {
//                        for (int r2 = 0; r2 <= r2Len; r2++) {
//                            recompute(r0Len, r1, r2);
//                        }
//                    }
//                } else if (religionId == 1) {
//                    for (int r0 = 0; r0 <= r0Len; r0++) {
//                        for (int r2 = 0; r2 <= r2Len; r2++) {
//                            recompute(r0, r1Len, r2);
//                        }
//                    }
//                } else { // religionId == 2
//                    for (int r0 = 0; r0 <= r0Len; r0++) {
//                        for (int r1 = 0; r1 <= r1Len; r1++) {
//                            recompute(r0, r1, r2Len);
//                        }
//                    }
//                }

                } else { // sign == '-'
                    modReligion.remove(modReligion.size() - 1);
                }

                if (dp[religions[0].size()][religions[1].size()][religions[2].size()] != wordLen) {
                    out.println("YES");
                } else {
                    out.println("NO");
                }
            }
        }

        private void recompute(int r0Len, int r1Len, int r2Len) {
            if (r0Len == 0 && r1Len == 0 && r2Len == 0) {
                return;
            }

            int withLastCharAsRel0 = r0Len - 1 >= 0 ?
                    charStats[dp[r0Len - 1][r1Len][r2Len] + 1][religions[0].get(r0Len - 1) - 'a'] : wordLen;
            int withLastCharAsRel1 = r1Len - 1 >= 0 ?
                    charStats[dp[r0Len][r1Len - 1][r2Len] + 1][religions[1].get(r1Len - 1) - 'a'] : wordLen;
            int withLastCharAsRel2 = r2Len - 1 >= 0 ?
                    charStats[dp[r0Len][r1Len][r2Len - 1] + 1][religions[2].get(r2Len - 1) - 'a'] : wordLen;
            dp[r0Len][r1Len][r2Len] = Math.min(withLastCharAsRel0,
                                               Math.min(withLastCharAsRel1, withLastCharAsRel2));
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Collections;
import java.util.ArrayList;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        private ArrayList<Character>[] religions;
        private ArrayList<Integer>[] charPos;
        private HashSet<Integer> filled;

        public void solve(int testNumber, Scanner in, PrintWriter out) {
            int wordLen = in.nextInt();
            int evoCount = in.nextInt();
            String word = in.next();

            religions = new ArrayList[3];
            for (int i = 0; i < religions.length; i++) {
                religions[i] = new ArrayList<>();
            }

            charPos = new ArrayList[26];
            for (int i = 0; i < charPos.length; i++) {
                charPos[i] = new ArrayList<>();
            }

            for (int i = 0; i < word.length(); i++) {
                char ch = word.charAt(i);
                int charIdx = ch - 'a';
                charPos[charIdx].add(i);
            }
            filled = new HashSet<>();
            while (evoCount > 0) {
                evoCount--;
                filled.clear();

                String sign = in.next();
                int religId = in.nextInt() - 1;
                if (sign.equals("+")) {
                    char newChar = in.next().charAt(0);
                    religions[religId].add(newChar);
                } else { // -
                    religions[religId].remove(religions[religId].size() - 1); //remove last
                }

                if (tryToFill(0, 0, 0)) {
                    out.println("YES");
                } else {
                    out.println("NO");
                }
            }
        }

        private boolean tryToFill(int religId, int charIdx, int wordStart) {
            if (religId == religions.length) {
                return true;
            }

            if (charIdx == religions[religId].size()) {
                return tryToFill(religId + 1, 0, 0);
            }

            char ch = religions[religId].get(charIdx);
            ArrayList<Integer> charPositions = charPos[ch - 'a'];
            int startCharPosIdx = Collections.binarySearch(charPositions, wordStart);
            if (startCharPosIdx < 0) {
                startCharPosIdx = (-startCharPosIdx) - 1;
            }
            for (int i = startCharPosIdx; i < charPositions.size(); i++) {
                int charPosition = charPositions.get(i);
                if (!filled.contains(charPosition)) {
                    filled.add(charPosition);
                    if (tryToFill(religId, charIdx + 1, charPosition + 1)) {
                        return true;
                    }
                    filled.remove(charPosition);
                }
            }

            return false;
        }

    }
}


import java.util.*;
import java.io.*;

public class DD {
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int N = scanner.nextInt()+1;
        int Q = scanner.nextInt();
        char[] word = ("a" + scanner.next()).toCharArray();
        ArrayList<Pair>[] rels = new ArrayList[3];
        for(int i = 0; i < 3; i++) {
            rels[i] = new ArrayList<>();
            rels[i].add(new Pair(0, 'a'));
        }
        int[] prev = new int[26];
        Arrays.fill(prev, -1);
        int[][] ptrs = new int[word.length][26];
        for(int[] dd: ptrs) Arrays.fill(dd, -1);
        for(int i = word.length-1; i >= 0; i--) {
            for(int j = 0; j < 26; j++) ptrs[i][j] = prev[j];
            prev[word[i]-'a'] = i;
        }
        boolean[] occ = new boolean[N];
        top:
        while(Q-->0) {
            String type = scanner.next();
            if (type.equals("+")) {
                int rel = scanner.nextInt()-1;
                char cChar = scanner.next().charAt(0);
                int tLoc = rels[rel].get(rels[rel].size()-1).loc;
                if (tLoc == -1 || ptrs[tLoc][cChar-'a'] == -1) {
                    rels[rel].add(new Pair(-1, cChar));
                    out.println("NO");
                    continue;
                }
                int next = ptrs[tLoc][cChar-'a'];
                if (!occ[next]) {
                    rels[rel].add(new Pair(next, cChar));
                    occ[next] = true;
                }
                else {
                    while(next != -1 && occ[next]) next = ptrs[next][cChar-'a'];
                    if (next == -1) {
                        rels[rel].add(new Pair(-1, cChar));
                        out.println("NO");
                        continue top;
                    }
                    else {
                        rels[rel].add(new Pair(next, cChar));
                        occ[next] = true;
                    }
                }
                for(int i = 0; i < 3; i++) {
                    if (rels[i].get(rels[i].size()-1).loc == -1) {
                        out.println("NO");
                        continue top;
                    }
                }
                out.println("YES");
            }
            else {
                int rel = scanner.nextInt()-1;
                char rem = rels[rel].get(rels[rel].size()-1).val;
                int remLoc = rels[rel].get(rels[rel].size()-1).loc;
                occ[remLoc] = false;
                rels[rel].remove(rels[rel].size()-1);
                outer:
                for(int i = 0; i < 3; i++) {
                    if (i == rel) continue;
                    int j;
                    for(j = 0; j < rels[i].size()-1; j++) {
                        if (rels[i].get(j+1).loc == -1 ||
                                (ptrs[rels[i].get(j).loc][rels[i].get(j).val-'a'] < rels[i].get(j+1).loc
                                        && ptrs[rels[i].get(j).loc][rels[i].get(j).val-'a'] != -1 &&
                                        !occ[ptrs[rels[i].get(j).loc][rels[i].get(j).val-'a']])) {
                            break;
                        }
                    }
//                    for(j = rels[i].size()-1; j >= 0; j--) {
//                        if (rels[i].get(j).loc != -1) {
//                            if (rels[i].get(j).val == rem) break;
//                            else continue outer;
//                        }
//                    }
                    while(j + 1 < rels[i].size()) {
                        char cChar = rels[i].get(j+1).val;
                        int curLoc = rels[i].get(j).loc;
                        int next = ptrs[curLoc][cChar-'a'];
                        if (next == -1) break;
                        while(next != -1 && occ[next]) next = ptrs[next][cChar-'a'];
                        if (next == -1) break;
                        rels[i].set(j+1, new Pair(next, cChar));
                        occ[next] = true;
                        j++;
                    }
                }
                for(int i = 0; i < 3; i++) if (rels[i].get(rels[rel].size()-1).loc == -1) {
                    out.println("NO");
                    continue top;
                }
                out.println("YES");
            }
        }
        out.flush();
    }

    public static class Pair {
        int loc;
        char val;
        public Pair(int ll, char vv) {
            loc = ll; val = vv;
        }
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }

        public FastScanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextInt();
            }
            return a;
        }
    }
}


import java.lang.reflect.Array;
import java.util.*;
import java.io.*;

public class DDD {
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int N = scanner.nextInt()+1;
        int Q = scanner.nextInt();
        boolean[] occ = new boolean[N];
        char[] word = ("a" + scanner.next()).toCharArray();
        ArrayList<Character>[] rels = new ArrayList[3];
        for(int i = 0; i < 3; i++) rels[i] = new ArrayList<>();
        int[] prev = new int[26];
        int fill = 2 * N;
        Arrays.fill(prev, fill);
        int[][] ptrs = new int[N][26];
        for(int[] dd: ptrs) Arrays.fill(dd, fill);
        for(int i = N-1; i>= 0; i--) {
            for(int j = 0; j < 26; j++) ptrs[i][j] = prev[j];
            prev[word[i]-'a'] = i;
        }
        top:
        while(Q-->0) {
            String type = scanner.next();
            if (type.equals("+")) {
                int rel = scanner.nextInt()-1;
                char car = scanner.next().charAt(0);
                rels[rel].add(car);
            }
            else {
                int rel = scanner.nextInt()-1;
                rels[rel].remove(rels[rel].size()-1);
            }
            //Try placements
            outer:
            for(int i = 0; i < 3; i++) {
                Arrays.fill(occ, false);
                int cur = 0;
                int prevLoc = 0;
                while (cur < rels[i].size()) {
                    char curChar = rels[i].get(cur);
                    int next = ptrs[prevLoc][curChar-'a'];
                    if (next == fill) continue outer;
                    occ[next] = true;
                    prevLoc = next;
                    cur++;
                }
                for(int j = 0; j < 3; j++) {
                    if (i == j) continue;
                    cur = 0;
                    prevLoc = 0;
                    while(cur < rels[j].size()) {
                        int curChar = rels[j].get(cur) -'a';
                        int next = ptrs[prevLoc][curChar];
                        while(next != fill && occ[next]) next = ptrs[next][curChar];
                        if (next == fill) continue outer;
                        occ[next] = true;
                        prevLoc = next;
                        cur++;
                    }
                    int rem = 3-i -j;
                    cur = 0;
                    prevLoc = 0;
                    while(cur < rels[rem].size()) {
                        int curChar = rels[rem].get(cur) - 'a';
                        int next = ptrs[prevLoc][curChar];
                        while(next != fill && occ[next]) next = ptrs[next][curChar];
                        if (next == fill) continue outer;
                        occ[next] = true;
                        prevLoc = next;
                        cur++;
                    }
                    out.println("YES");
                    continue top;
                }
            }
            out.println("NO");
        }
        out.flush();
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }

        public FastScanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextInt();
            }
            return a;
        }
    }
}


import java.util.*;
import java.io.*;

public class ThreeReligions {
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int N = scanner.nextInt();
        int Q = scanner.nextInt();
        int[][][] dp = new int[255][255][255];
        dp[0][0][0] = -1;
        char[] word = scanner.next().toCharArray();
        ArrayList<Character>[] rels = new ArrayList[3];
        for(int i = 0; i < 3; i++) rels[i] = new ArrayList<>();
        int[][] ptrs = new int[N+2][26];
        for(int i = 0; i < 26; i++) ptrs[N+1][i] = ptrs[N][i] = N;
        for(int i = N-1; i>=0; i--) {
            for(int j = 0; j < 26; j++) {
                char curChar = (char)(j + 'a');
                if (word[i] == curChar) ptrs[i][j] = i;
                else ptrs[i][j] = ptrs[i+1][j];
            }
        }
        while(Q-->0) {
            String type = scanner.next();
            int rel = scanner.nextInt()-1;
            if (type.equals("+")) {
                char c = scanner.next().charAt(0);
                rels[rel].add(c);
                int[] sz = new int[3];
                sz[rel] = rels[rel].size();
                for(int i = sz[0]; i <= rels[0].size(); i++) {
                    for(int j = sz[1]; j <= rels[1].size(); j++) {
                        for(int k = sz[2]; k <= rels[2].size(); k++) {
                            dp[i][j][k] = N;
                            if (i > 0) dp[i][j][k] = Math.min(dp[i][j][k], ptrs[dp[i-1][j][k]+1][rels[0].get(i-1)-'a']);
                            if (j > 0) dp[i][j][k] = Math.min(dp[i][j][k], ptrs[dp[i][j-1][k]+1][rels[1].get(j-1)-'a']);
                            if (k > 0) dp[i][j][k] = Math.min(dp[i][j][k], ptrs[dp[i][j][k-1]+1][rels[2].get(k-1)-'a']);
                        }
                    }
                }
            }
            else rels[rel].remove(rels[rel].size()-1);
            if (dp[rels[0].size()][rels[1].size()][rels[2].size()] < N) out.println("YES");
            else out.println("NO");
        }

        out.flush();
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }

        public FastScanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextInt();
            }
            return a;
        }
    }
}


import java.util.*;
import java.math.*;

// **** D. Three Religions ****

public class D {
	static char [] in = new char [1000000];
	static class AL extends ArrayList<Integer>{ public AL(int a){super(a);}};
	static int [][] pos;
	static int [] ptr;
	public static void main (String [] arg) throws Throwable {
		int n = nextInt();
		int q = nextInt();
		char [] word = next().toCharArray();
		pos = new int [26][word.length];
		ptr = new int [26];
		for (int i = 0; i<word.length; ++i) {
			int tmp = word[i] - 'a';
			pos[tmp][ptr[tmp]] = i;
			ptr[tmp]++;
		}
		AL[] R = new AL[3];
		for (int i = 0; i<3; ++i) R[i] = new AL(q);
		StringBuilder ans = new StringBuilder(q*4);
		boolean can = true;

		int [] pr = new int [3];
		int [][][] dp = new int [251][251][251];
		dp[0][0][0] = -1;
		for (int iii = 0; iii<q; ++iii) {
			String s = next();
			int r = nextInt()-1;
			if (s.charAt(0) == '-') {
				pr[r]--;
				R[r].remove(R[r].size()-1);
			} else {
				String c = next();
				R[r].add( c.charAt(0) - 'a');
				pr[r]++;
				int x0 = pr[r];
				int x1 = (r+1)%3;
				int x2 = (r+2)%3;
				int MIN = Integer.MAX_VALUE;

				for (int i = 0; i <= pr[x1]; ++i) {
					for (int j = 0; j <= pr[x2]; ++j) {
						int tmp1 = (r == 0) ? dp[x0-1][i][j] : (r == 1) ? dp[j][x0-1][i] : dp[i][j][x0-1];
						int tmp2 = (i == 0) ? Integer.MAX_VALUE : (r == 0) ? dp[x0][i-1][j] : (r == 1) ? dp[j][x0][i-1] : dp[i-1][j][x0];
						int tmp3 = (j == 0) ? Integer.MAX_VALUE : (r == 0) ? dp[x0][i][j-1] : (r == 1) ? dp[j-1][x0][i] : dp[i][j-1][x0];

						int R0 = rSearch(tmp1, R[r].get(R[r].size()-1), r);
						int R1 = (i == 0) ? Integer.MAX_VALUE : rSearch(tmp2, R[x1].get(R[x1].size()-1), x1);
						int R2 = (j == 0) ? Integer.MAX_VALUE : rSearch(tmp3, R[x2].get(R[x2].size()-1), x2);
						if (r == 0) dp[x0][i][j] = Math.min(R0, Math.min(R1,R2));
						if (r == 1) dp[j][x0][i] = Math.min(R0, Math.min(R1,R2));
						if (r == 2) dp[i][j][x0] = Math.min(R0, Math.min(R1,R2));
					}
				}
				//System.err.println("VALUE after step " + iii + " is " + dp[pr[0]][pr[1]][pr[2]]);
			}
			can = (dp[pr[0]][pr[1]][pr[2]] != Integer.MAX_VALUE);
			if (ans.length() != 0) ans = ans.append("\n");
			ans = ans.append(can ? "YES" : "NO");
		}
		System.out.println(ans);
	}
	public static int rSearch(int last_pos , int c , int debug) {
		if (last_pos == Integer.MAX_VALUE) return Integer.MAX_VALUE;
		if (ptr[c] == 0) return Integer.MAX_VALUE;
		int j = Arrays.binarySearch(pos[c], 0, ptr[c], last_pos+1);
		if (j < 0) {
			j = -j - 1;
		}
		if (j >= ptr[c]) return Integer.MAX_VALUE;
		//System.err.println("Searching " + ((char)('a'+c)) + " after " + last_pos + " for religion " + debug +" and ans is " + pos[c][j]);
		return pos[c][j];
	}

	/************** FAST IO CODE FOLLOWS *****************/
	public static long nextLong() throws Throwable {
		long i = System.in.read();boolean neg = false;while (i < 45) i = System.in.read();if (i == 45) {neg=true;i=48;}i = i - 48;
		int j = System.in.read();while (j > 32) {i*=10;i+=j-48;j = System.in.read();}return (neg) ? -i : i;
	}
	public static int nextInt() throws Throwable {return (int)nextLong();}
	public static String next() throws Throwable {
		int i = 0; while (i < 40 && i != -1) i = System.in.read(); int cptr = 0; while (i >= 40) { in[cptr++] = (char)i; i = System.in.read();}
		return new String(in, 0,cptr);
	}
	/**** LIBRARIES ****/
	public static long gcdL(long a, long b) {while (b != 0) {long tmp = b;b = (a % b);a = tmp;}return a;}
	public static int gcd(int a, int b) {while (b != 0) {int tmp = b;b = (a % b);a = tmp;}return a;}
	public static int[] sieve(int LIM) {
		int i,count = 0;
		boolean [] b = new boolean [LIM];
		for (i = 2;i<LIM; ++i) if (!b[i]) {count++; for (int j = i<<1; j<LIM; j+=i) b[j] = true;}
		int [] primes = new int[count];
		for (i = 2,count=0;i<LIM;++i) if (!b[i]) primes[count++] = i;
		return primes;
	}
	public static int[] numPrimeFactors(int LIM) {
		int i,count = 0;
		int [] b = new int [LIM];
		for (i = 2;i<LIM; ++i) if (b[i] == 0) {count++; for (int j = i; j<LIM; j+=i) b[j]++;}
		return b;
	}
}
/*
				//int i = pr[0];
				//int j = pr[1];
				//int k = pr[2];
				int x0 = pr[r] - 1;
				int x1 = (r+1)%3;
				int x2 = (r+2)%3;
				int MIN = Integer.MAX_VALUE;

				for (int i = 0; i < Math.max(1,pr[x1]); ++i) {
					for (int j = 0; j < Math.max(1, pr[x2]); ++j) {
						int tmp = (r == 0) ? dp[x0][i][j] : (r == 1) ? dp[j][x0][i] : dp[i][j][x0];
						int rval = rSearch(tmp,
					}
				}
				*/
/* Full Problem Text:

During the archaeological research in the Middle East you found the traces of three ancient religions: First religion, Second religion and Third religion.
You compiled the information on the evolution of each of these beliefs, and you now wonder if the followers of each religion could coexist in peace.
The Word of Universe is a long word containing the lowercase English characters only.
At each moment of time, each of the religion beliefs could be described by a word consisting of lowercase English characters.
The three religions can coexist in peace if their descriptions form disjoint subsequences of the Word of Universe.
More formally, one can paint some of the characters of the Word of Universe in three colors: 1, 2, 3, so that each character is painted in at most one color, and the description of the i-th religion can be constructed from the Word of Universe by removing all characters that aren't painted in color i.
The religions however evolve.
In the beginning, each religion description is empty.
Every once in a while, either a character is appended to the end of the description of a single religion, or the last character is dropped from the description.
After each change, determine if the religions could coexist in peace.

 */