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.io.*;
import java.util.*;
import java.math.*;
import static java.lang.Math.*;
import static java.util.Map.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;
import static java.lang.System.*;
public class Main
{
    public void tq() throws Exception
    {
        st=new StringTokenizer(bq.readLine());
        int tq=i();
        sb=new StringBuilder(2000000);
        o:
        while(tq-->0)
        {
            int n=i();
            int ar[]=ari(n);
            String s=s();
            int f[]=new int[n];
            LinkedList<Integer> a=new LinkedList<>();
            LinkedList<Integer> b=new LinkedList<>();
            int i=-1;
            int m[]=new int[n+1];
            for(char c:s.toCharArray())
            {
                i++;
                m[ar[i]]=i;
                if(c=='1')a.add(ar[i]);
                else b.add(ar[i]);
            }
            Collections.sort(a,reverseOrder());
            Collections.sort(b);
            int v=n;
            for(int e:a)
            {
                f[m[e]]=v--;
            }
            v=1;
            for(int e:b)f[m[e]]=v++;
            s(f);
        }
        p(sb);
    }
    long mod=1000000007l;
    int max=Integer.MAX_VALUE,min=Integer.MIN_VALUE;long maxl=Long.MAX_VALUE,minl=Long.MIN_VALUE;
    BufferedReader bq = new BufferedReader(new InputStreamReader(in));StringTokenizer st;StringBuilder sb;
    public static void main(String[] a)throws Exception{new Main().tq();}
    int di[][]={{-1,0},{1,0},{0,-1},{0,1}};
    int de[][]={{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{1,1},{-1,1},{1,-1}};
    void f(){out.flush();}
    boolean c(int x,int y,int n,int m){return x>=0&&x<n&&y>=0&&y<m;}
    int[] so(int ar[])
    {
        Integer r[] = new Integer[ar.length];
        for (int x = 0; x < ar.length; x++) r[x] = ar[x];
        sort(r);
        for (int x = 0; x < ar.length; x++) ar[x] = r[x];
        return ar;
    }
    long[] so(long ar[])
    {
        Long r[] = new Long[ar.length];
        for (int x = 0; x < ar.length; x++) r[x] = ar[x];
        sort(r);
        for (int x = 0; x < ar.length; x++) ar[x] = r[x];
        return ar;
    }
    char[] so(char ar[])
    {
        Character r[] = new Character[ar.length];
        for (int x = 0; x < ar.length; x++) r[x] = ar[x];
        sort(r);
        for (int x = 0; x < ar.length; x++) ar[x] = r[x];
        return ar;
    }
    void p(Object p) {out.print(p);}void pl(Object p) {out.println(p);}void pl() {out.println();}
    void s(String s) {sb.append(s);}
    void s(int s) {sb.append(s);}
    void s(long s) {sb.append(s);}
    void s(char s) {sb.append(s);}
    void s(double s) {sb.append(s);}
    void ss() {sb.append(' ');}
    void sl(String s) {s(s);sb.append("\n");}
    void sl(int s) {s(s);sb.append("\n");}
    void sl(long s) {s(s);sb.append("\n");}
    void sl(char s) {s(s);sb.append("\n");}
    void sl(double s) {s(s);sb.append("\n");}
    void sl() {sb.append("\n");}
    int l(int v) {return 31 - Integer.numberOfLeadingZeros(v);}
    long l(long v) {return 63 - Long.numberOfLeadingZeros(v);}
    int sq(int a) {return (int) sqrt(a);}
    long sq(long a) {return (long) sqrt(a);}
    int gcd(int a, int b)
    {
        while (b > 0)
        {
            int c = a % b;
            a = b;
            b = c;
        }
        return a;
    }
    long gcd(long a, long b)
    {
        while (b > 0l)
        {
            long c = a % b;
            a = b;
            b = c;
        }
        return a;
    }
    boolean pa(String s, int i, int j)
    {
        while (i < j) if (s.charAt(i++) != s.charAt(j--)) return false;
        return true;
    }
    boolean[] si(int n)
    {
        boolean bo[] = new boolean[n + 1];
        bo[0] = bo[1] = true;
        for (int x = 4; x <= n; x += 2) bo[x] = true;
        for (int x = 3; x * x <= n; x += 2)
        {
            if (!bo[x])
            {
                int vv = (x << 1);
                for (int y = x * x; y <= n; y += vv) bo[y] = true;
            }
        }
        return bo;
    }
    long mul(long a, long b, long m)
    {
        long r = 1l;
        a %= m;
        while (b > 0)
        {
            if ((b & 1) == 1) r = (r * a) % m;
            b >>= 1;
            a = (a * a) % m;
        }
        return r;
    }
    int i() throws IOException
    {
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        return Integer.parseInt(st.nextToken());
    }
    long l() throws IOException
    {
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        return Long.parseLong(st.nextToken());
    }
    String s() throws IOException
    {
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        return st.nextToken();
    }
    double d() throws IOException
    {
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        return Double.parseDouble(st.nextToken());
    }
    void s(int a[])
    {
        for (int e : a){sb.append(e);sb.append(' ');}
        sb.append("\n");
    }
    void s(long a[])
    {
        for (long e : a){sb.append(e);sb.append(' ');}
        sb.append("\n");
    }
    void s(char a[])
    {
        for (char e : a){sb.append(e);sb.append(' ');}
        sb.append("\n");
    }
    void s(int ar[][]) {for (int a[] : ar) s(a);}
    void s(long ar[][]) {for (long a[] : ar) s(a);}
    void s(char ar[][]) {for (char a[] : ar) s(a);}
    int[] ari(int n) throws IOException
    {
        int ar[] = new int[n];
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        for (int x = 0; x < n; x++) ar[x] = Integer.parseInt(st.nextToken());
        return ar;
    }
    long[] arl(int n) throws IOException
    {
        long ar[] = new long[n];
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        for (int x = 0; x < n; x++) ar[x] = Long.parseLong(st.nextToken());
        return ar;
    }
    char[] arc(int n) throws IOException
    {
        char ar[] = new char[n];
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        for (int x = 0; x < n; x++) ar[x] = st.nextToken().charAt(0);
        return ar;
    }
    double[] ard(int n) throws IOException
    {
        double ar[] = new double[n];
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        for (int x = 0; x < n; x++) ar[x] = Double.parseDouble(st.nextToken());
        return ar;
    }
    String[] ars(int n) throws IOException
    {
        String ar[] = new String[n];
        if (!st.hasMoreTokens()) st = new StringTokenizer(bq.readLine());
        for (int x = 0; x < n; x++) ar[x] = st.nextToken();
        return ar;
    }
    int[][] ari(int n, int m) throws IOException
    {
        int ar[][] = new int[n][m];
        for (int x = 0; x < n; x++)ar[x]=ari(m);
        return ar;
    }
    long[][] arl(int n, int m) throws IOException
    {
        long ar[][] = new long[n][m];
        for (int x = 0; x < n; x++)ar[x]=arl(m);
        return ar;
    }
    char[][] arc(int n, int m) throws IOException
    {
        char ar[][] = new char[n][m];
        for (int x = 0; x < n; x++)ar[x]=arc(m);
        return ar;
    }
    double[][] ard(int n, int m) throws IOException
    {
        double ar[][] = new double[n][m];
        for (int x = 0; x < n; x++)ar[x]=ard(m);
        return ar;
    }
    void p(int ar[])
    {
        sb = new StringBuilder(11 * ar.length);
        for (int a : ar) {sb.append(a);sb.append(' ');}
        out.println(sb);
    }
    void p(long ar[])
    {
        StringBuilder sb = new StringBuilder(20 * ar.length);
        for (long a : ar){sb.append(a);sb.append(' ');}
        out.println(sb);
    }
    void p(double ar[])
    {
        StringBuilder sb = new StringBuilder(22 * ar.length);
        for (double a : ar){sb.append(a);sb.append(' ');}
        out.println(sb);
    }
    void p(char ar[])
    {
        StringBuilder sb = new StringBuilder(2 * ar.length);
        for (char aa : ar){sb.append(aa);sb.append(' ');}
        out.println(sb);
    }
    void p(String ar[])
    {
        int c = 0;
        for (String s : ar) c += s.length() + 1;
        StringBuilder sb = new StringBuilder(c);
        for (String a : ar){sb.append(a);sb.append(' ');}
        out.println(sb);
    }
    void p(int ar[][])
    {
        StringBuilder sb = new StringBuilder(11 * ar.length * ar[0].length);
        for (int a[] : ar)
        {
            for (int aa : a){sb.append(aa);sb.append(' ');}
            sb.append("\n");
        }
        p(sb);
    }
    void p(long ar[][])
    {
        StringBuilder sb = new StringBuilder(20 * ar.length * ar[0].length);
        for (long a[] : ar)
        {
            for (long aa : a){sb.append(aa);sb.append(' ');}
            sb.append("\n");
        }
        p(sb);
    }
    void p(double ar[][])
    {
        StringBuilder sb = new StringBuilder(22 * ar.length * ar[0].length);
        for (double a[] : ar)
        {
            for (double aa : a){sb.append(aa);sb.append(' ');}
            sb.append("\n");
        }
        p(sb);
    }
    void p(char ar[][])
    {
        StringBuilder sb = new StringBuilder(2 * ar.length * ar[0].length);
        for (char a[] : ar)
        {
            for (char aa : a){sb.append(aa);sb.append(' ');}
            sb.append("\n");
        }
        p(sb);
    }
    void pl(Object... ar) {for (Object e : ar) p(e + " ");pl();}
}