Problem: This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.

Output the final string after applying the queries.

Input

The first line will contain two integers n, q (1 ≤ n ≤ 105, 0 ≤ q ≤ 50 000), the length of the string and the number of queries respectively. 

Next line contains a string S itself. It contains only lowercase English letters.

Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n, <image>).

Output

Output one line, the string S after applying the queries.

Examples

Input

10 5
abacdabcda
7 10 0
5 8 1
1 4 0
3 6 0
7 10 1


Output

cbcaaaabdd

Input

10 1
agjucbvdfk
1 10 1


Output

abcdfgjkuv

Note

First sample test explanation:

<image>

<image>

<image>

<image>

<image>

Solution (in JAVA):

Solution:

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

public class E
{
   public static void main(String[] args) throws Exception
   {
      PrintWriter out = new PrintWriter(System.out);
      new E(new FastScanner(System.in), out);
      out.close();
   }

   public E(FastScanner in, PrintWriter out)
   {
      int N = in.nextInt();
      int Q = in.nextInt();

      String s = in.next();
      TreeSet<Node> ts = new TreeSet<>();
      for (int i=0; i<N; i++)
         ts.add(new Node(i, i, s.charAt(i)));
      
      Comparator<Node> cmp1 = new Comparator<Node>(){
            public int compare(Node a, Node b)
            {
               return Character.compare(a.c, b.c);
            }
         };

      Comparator<Node> cmp2 = new Comparator<Node>(){
            public int compare(Node a, Node b)
            {
               return Character.compare(b.c, a.c);
            }
         };

      ArrayList<Node> tmp = new ArrayList<>();
      while (Q-->0)
      {
         int a = in.nextInt()-1;
         int b = in.nextInt()-1;
         int t = in.nextInt();
         
         Node stab = new Node(a, a, '-');
         tmp.clear();
         while (true)
         {
            Node mx = ts.ceiling(stab);
            if (mx == null) break;
            if (mx.a > b) break;

            ts.remove(mx);
            if (mx.a < a)
            {
               ts.add(new Node(mx.a, a-1, mx.c));
               mx = new Node(a, mx.b, mx.c);
            }

            if (mx.b > b)
            {
               ts.add(new Node(b+1, mx.b, mx.c));
               mx = new Node(mx.a, b, mx.c);
               tmp.add(mx);
               break;
            }

            tmp.add(mx);
         }

         if (t == 1)
            Collections.sort(tmp, cmp1);
         else
            Collections.sort(tmp, cmp2);

         int ptr = 0;
         while (ptr < tmp.size())
         {
            Node st = tmp.get(ptr);
            int aa = a;
            while (ptr < tmp.size() && tmp.get(ptr).c == st.c)
            {
               a += tmp.get(ptr).b-tmp.get(ptr).a+1;
               ptr++;
            }
            ts.add(new Node(aa, a-1, st.c));
         }
      }

      for (Node cur : ts)
         for (int u=cur.a; u<=cur.b; u++)
            out.print(cur.c);
      out.println();
   }
}

class Node implements Comparable<Node>
{
   int a, b;
   char c;

   Node(int aa, int bb, char cc)
   {
      a=aa; b=bb; c=cc;
   }

   public int compareTo(Node rhs)
   {
      if (b >= rhs.a && a <= rhs.b)
         return 0;
      return Integer.compare(a, rhs.a);
   }

   public String toString()
   {
      return String.format("<%d,%d,%c>", a, b, c);
   }
}

class FastScanner{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    
    public FastScanner(InputStream stream)
    {
        this.stream = stream;
    }
    
    int read()
    {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars){
            curChar = 0;
            try{
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }
    
    boolean isSpaceChar(int c)
    {
        return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
    }
    
    boolean isEndline(int c)
    {
        return c=='\n'||c=='\r'||c==-1;
    }
    
    int nextInt()
    {
        return Integer.parseInt(next());
    }
    
    long nextLong()
    {
        return Long.parseLong(next());
    }
    
    double nextDouble()
    {
        return Double.parseDouble(next());
    }
    
    String next(){
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isSpaceChar(c));
        return res.toString();
    }
    
    String nextLine(){
        int c = read();
        while (isEndline(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isEndline(c));
        return res.toString();
    }
}