Berland Music is a music streaming service built specifically to support Berland local artist. Its developers are currently working on a song recommendation module.

So imagine Monocarp got recommended n songs, numbered from 1 to n. The i-th song had its predicted rating equal to p_i, where 1 ≤ p_i ≤ n and every integer from 1 to n appears exactly once. In other words, p is a permutation.

After listening to each of them, Monocarp pressed either a like or a dislike button. Let his vote sequence be represented with a string s, such that s_i=0 means that he disliked the i-th song, and s_i=1 means that he liked it.

Now the service has to re-evaluate the song ratings in such a way that:

  * the new ratings q_1, q_2, ..., q_n still form a permutation (1 ≤ q_i ≤ n; each integer from 1 to n appears exactly once); 
  * every song that Monocarp liked should have a greater rating than every song that Monocarp disliked (formally, for all i, j such that s_i=1 and s_j=0, q_i>q_j should hold). 



Among all valid permutations q find the one that has the smallest value of ∑_{i=1}^n |p_i-q_i|, where |x| is an absolute value of x.

Print the permutation q_1, q_2, ..., q_n. If there are multiple answers, you can print any of them.

Input

The first line contains a single integer t (1 ≤ t ≤ 10^4) — the number of testcases.

The first line of each testcase contains a single integer n (1 ≤ n ≤ 2 ⋅ 10^5) — the number of songs.

The second line of each testcase contains n integers p_1, p_2, ..., p_n (1 ≤ p_i ≤ n) — the permutation of the predicted ratings.

The third line contains a single string s, consisting of n characters. Each character is either a 0 or a 1. 0 means that Monocarp disliked the song, and 1 means that he liked it.

The sum of n over all testcases doesn't exceed 2 ⋅ 10^5.

Output

For each testcase, print a permutation q — the re-evaluated ratings of the songs. If there are multiple answers such that ∑_{i=1}^n |p_i-q_i| is minimum possible, you can print any of them.

Example

Input


3
2
1 2
10
3
3 1 2
111
8
2 3 1 8 5 4 7 6
01110001


Output


2 1
3 1 2
1 6 5 8 3 2 4 7

Note

In the first testcase, there exists only one permutation q such that each liked song is rating higher than each disliked song: song 1 gets rating 2 and song 2 gets rating 1. ∑_{i=1}^n |p_i-q_i|=|1-2|+|2-1|=2.

In the second testcase, Monocarp liked all songs, so all permutations could work. The permutation with the minimum sum of absolute differences is the permutation equal to p. Its cost is 0.
1
7
1 2 3 4 5 6 7
0101010
 3
2
1 2
10
7
1 2 3 4 5 6 7
0101010
8
2 3 1 8 5 4 7 6
01110001
 1
50
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
10101010101010101010101010101010101010101010101010

1 5 2 6 3 7 4
 2 1
1 5 2 6 3 7 4
1 6 5 8 3 2 4 7
 26 1 27 2 28 3 29 4 30 5 31 6 32 7 33 8 34 9 35 10 36 11 37 12 38 13 39 14 40 15 41 16 42 17 43 18 44 19 45 20 46 21 47 22 48 23 49 24 50 25

// हर हर महादेव
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.BigInteger;
import java.text.DecimalFormat;

public final class Solution {

    static int inf = Integer.MAX_VALUE;
    static long mod = 1000000000 + 7;
  
 static void ne(Scanner sc, BufferedWriter op) throws Exception {
   int n=sc.nextInt();
   int[] arr= new int[n];
   for(int i=0;i<n;i++){
       arr[i]=sc.nextInt();
   }
   String s=sc.next();
   int curr=n;
   int[] ans= new int[n];
    ArrayList<pp> one= new ArrayList<>();
    ArrayList<pp> zero= new ArrayList<>();
   for(int i=0;i<n;i++){
      if(s.charAt(i)=='1'){
          one.add(new pp(arr[i],1,i));
      }else{
          zero.add(new pp(arr[i],0,i));
      }
   }
   Collections.sort(one,new comp());
   Collections.sort(zero,new cc());
   for(int i=0;i<one.size();i++){
       pp p=one.get(i);
       ans[p.ind]=curr--;
   }
   for(int i=0;i<zero.size();i++){
       pp p=zero.get(i);
       ans[p.ind]=curr--;
   }
   for(int i=0;i<n;i++){
       op.write(ans[i]+" ");
   }
   op.write("\n");
    

 }
 
  
     public static boolean isKthSet(int n, int k)
    {
        if ((n & (1 << (k - 1))) > 0)
           return true;
        else
            return false;
    }
  

    public static void main(String[] args) throws Exception {
        BufferedWriter op = new BufferedWriter(new OutputStreamWriter(System.out));
        // Reader sc = new Reader();
     
        Scanner sc= new Scanner(System.in);
        int t = sc.nextInt();
        while (t-->0){ ne(sc, op); }
        
        // ne(sc,op);
           
                   
        op.flush();
    }

    static void print(Object o) {
        System.out.println(String.valueOf(o));
    }
    static int[] toIntArr(String s){
        int[] val= new int[s.length()];
        for(int i=0;i<s.length();i++){
            val[i]=s.charAt(i)-'a';
        }
        return val;
    }

    static void  sort(int[] arr){
        ArrayList<Integer> list= new ArrayList<>();
        for(int i=0;i<arr.length;i++){
            list.add(arr[i]);

        }
        Collections.sort(list);
        for(int i=0;i<arr.length;i++){
            arr[i]=list.get(i);
        }
    }
       static void  sort(long[] arr){
        ArrayList<Long> list= new ArrayList<>();
        for(int i=0;i<arr.length;i++){
            list.add(arr[i]);

        }
        Collections.sort(list);
        for(int i=0;i<arr.length;i++){
            arr[i]=list.get(i);
        }
    }

}
class comp implements Comparator<pp>{
     public int compare(pp p1,pp p2){
         if(p1.no<p2.no){
             return 1;
         }else{
             return -1;
         }
     }
 }
  class cc implements Comparator<pp>{
     public int compare(pp p1,pp p2){
         if(p1.no<p2.no){
             return -1;
         }else{
             return 1;
         }
     }
 }
  class pp{
      int no;
      int f;
      int ind;
      pp(int no,int f, int ind){
          this.no=no;
          this.f=f;
          this.ind=ind;
      }
  }



// return -1 to put no ahed in array
class pair {
    int  xx;
    int yy;
    pair(int xx, int yy ) {
        this.xx = xx;
        this.yy = yy;
    }
}


class sortY implements Comparator<pair> {
    public int compare(pair p1, pair p2) {
        if (p1.yy > p2.yy) {
            return 1;
        } else if (p1.yy == p2.yy) {
            if (p1.xx > p2.xx) {
                return 1;
            } else if (p1.xx < p2.xx) {
                return -1;
            }
            return 0;

        }
        return -1;
    }
}

class sortX implements Comparator<pair> {
    public int compare(pair p1, pair p2) {
        if (p1.xx > p2.xx) {
            return 1;
        } else if (p1.xx == p2.xx) {
            if (p1.yy > p2.yy) {
                return 1;
            } else if (p1.yy < p2.yy) {
                return -1;
            }
            return 0;

        }
        return -1;
    }
}

class debug {

    static void print1d(long[] arr) {
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }

    }

    static void print1d(int[] arr) {
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(i+" = "+arr[i]);
        }

    }

    static void print1d(boolean[] arr) {
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(i + "= " + arr[i]);
        }

    }

    static void print2d(int[][] arr) {
        System.out.println();
        int n = arr.length;
        int n2 = arr[0].length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n2; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }

    }
       static void print2d(boolean[][] arr) {
        System.out.println();
        int n = arr.length;
        int n2 = arr[0].length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n2; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }

    }

    static void print2d(long[][] arr) {
        System.out.println();
        int n = arr.length;
        int n2 = arr[0].length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n2; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }

    }
     static void printPair(ArrayList<pair> list) {
        if(list.size()==0){
            System.out.println("empty list");
            return;
        }
       System.out.println();
       for(int i=0;i<list.size();i++){
          System.out.println(list.get(i).xx+"-"+list.get(i).yy);
       }
    }

}

class Reader {
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader() {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException {
        byte[] buf = new byte[64]; // line length
        int cnt = 0, c;
        while ((c = read()) != -1) {
            if (c == '\n') {
                if (cnt != 0) {
                    break;
                } else {
                    continue;
                }
            }
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException {
        int ret = 0;
        byte c = read();
        while (c <= ' ') {
            c = read();
        }
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');

        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();

        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');

        if (c == '.') {
            while ((c = read()) >= '0' && c <= '9') {
                ret += (c - '0') / (div *= 10);
            }
        }

        if (neg)
            return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException {
        if (din == null)
            return;
        din.close();
    }
}
 class MultiTreeSet<E> {
	TreeMap<E, Integer> freqTreeMap = new TreeMap<E, Integer>();
	int size;
 
	public MultiTreeSet() {}
 
	public MultiTreeSet(Collection<? extends E> c) {
		for(E element : c)
			add(element);
	}
 
	public int size() {
		return size;
	}
 
	public void add(E element) {
		Integer freq = freqTreeMap.get(element);
		if(freq==null)
			freqTreeMap.put(element, 1);
		else
			freqTreeMap.put(element,freq+1);
		++size;
	}
 
	public void remove(E element) {
		Integer freq = freqTreeMap.get(element);
		if(freq!=null) {
			if(freq==1)
				freqTreeMap.remove(element);
			else
				freqTreeMap.put(element, freq-1);
			--size;
		}
	}
 
	public int get(E element) {
		Integer freq = freqTreeMap.get(element);
		if(freq==null)
			return 0;
		return freq;
	}
 
	public boolean contains(E element) {
		return get(element)>0;
	}
 
	public boolean isEmpty() {
		return size==0;
	}
 
	public E first() {
		return freqTreeMap.firstKey();
	}
 
	public E last() {
		return freqTreeMap.lastKey();
	}
 
	public E ceiling(E element) {
		return freqTreeMap.ceilingKey(element);
	}
 
	public E floor(E element) {
		return freqTreeMap.floorKey(element);
	}
 
	public E higher(E element) {
		return freqTreeMap.higherKey(element);
	}
 
	public E lower(E element) {
		return freqTreeMap.lowerKey(element);
	}
}
 