It turns out that the meaning of life is a permutation p_1, p_2, …, p_n of the integers 1, 2, …, n (2 ≤ n ≤ 100). Omkar, having created all life, knows this permutation, and will allow you to figure it out using some queries.

A query consists of an array a_1, a_2, …, a_n of integers between 1 and n. a is not required to be a permutation. Omkar will first compute the pairwise sum of a and p, meaning that he will compute an array s where s_j = p_j + a_j for all j = 1, 2, …, n. Then, he will find the smallest index k such that s_k occurs more than once in s, and answer with k. If there is no such index k, then he will answer with 0.

You can perform at most 2n queries. Figure out the meaning of life p.

Interaction

Start the interaction by reading single integer n (2 ≤ n ≤ 100) — the length of the permutation p.

You can then make queries. A query consists of a single line "? \enspace a_1 \enspace a_2 \enspace … \enspace a_n" (1 ≤ a_j ≤ n).

The answer to each query will be a single integer k as described above (0 ≤ k ≤ n).

After making a query do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

  * fflush(stdout) or cout.flush() in C++;
  * System.out.flush() in Java;
  * flush(output) in Pascal;
  * stdout.flush() in Python;
  * see documentation for other languages.



To output your answer, print a single line "! \enspace p_1 \enspace p_2 \enspace … \enspace p_n" then terminate.

You can make at most 2n queries. Outputting the answer does not count as a query.

Hack Format

To hack, first output a line containing n (2 ≤ n ≤ 100), then output another line containing the hidden permutation p_1, p_2, …, p_n of numbers from 1 to n.

Example

Input


5

2

0

1


Output



? 4 4 2 3 2

? 3 5 1 5 5

? 5 2 4 3 1

! 3 2 1 5 4

Note

In the sample, the hidden permutation p is [3, 2, 1, 5, 4]. Three queries were made.

The first query is a = [4, 4, 2, 3, 2]. This yields s = [3 + 4, 2 + 4, 1 + 2, 5 + 3, 4 + 2] = [7, 6, 3, 8, 6]. 6 is the only number that appears more than once, and it appears first at index 2, making the answer to the query 2.

The second query is a = [3, 5, 1, 5, 5]. This yields s = [3 + 3, 2 + 5, 1 + 1, 5 + 5, 4 + 5] = [6, 7, 2, 10, 9]. There are no numbers that appear more than once here, so the answer to the query is 0.

The third query is a = [5, 2, 4, 3, 1]. This yields s = [3 + 5, 2 + 2, 1 + 4, 5 + 3, 4 + 1] = [8, 4, 5, 8, 5]. 5 and 8 both occur more than once here. 5 first appears at index 3, while 8 first appears at index 1, and 1 < 3, making the answer to the query 1.

Note that the sample is only meant to provide an example of how the interaction works; it is not guaranteed that the above queries represent a correct strategy with which to determine the answer.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.LinkedBlockingDeque;

import javax.print.attribute.HashAttributeSet;
import javax.swing.JLabel;

import java.io.PrintStream;
import java.sql.Blob;
        
    public class Solution {

        public static boolean Local(){
            try{ 
                return System.getenv("LOCAL_SYS")!=null;
            }catch(Exception e){
                return false;
            }
        }   

        public static boolean LOCAL;

        static class FastScanner {

                BufferedReader br;
                StringTokenizer st ;

                FastScanner(){
                    br =  new BufferedReader(new InputStreamReader(System.in));
                    st = new StringTokenizer("");
                }

                FastScanner(String file) {

                    try{
                        br =  new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                        st = new StringTokenizer("");
                    }catch(FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        System.out.println("file not found");
                        e.printStackTrace();
                    }
                    
                }
                

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

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

                long nextLong() {
                    return Long.parseLong(next());
                }
                String readLine() throws IOException{
                    return br.readLine();
                }
            }
                                
        static class Pair<T,X> {

            T first;
            X second;
            
            Pair(T first,X second){
                this.first = first;
                this.second = second;
            }

            @Override
            public int hashCode(){
                return Objects.hash(first,second);
            }

            @Override
            public boolean equals(Object obj){
                return obj.hashCode() == this.hashCode();
            }

        }


        static PrintStream debug = null;

        static class TreeNode{
            TreeNode left;
            TreeNode right;
            int l;
            int r;
            long gcd;
            TreeNode(int l,int r){
                this.l = l;
                this.r = r;
                this.gcd = 0;
                this.left = null;
                this.right = null;
            }
        }

        static long mod = (long)(Math.pow(10,9) + 7); 
        

        public static void main(String[] args) throws Exception {
            
            FastScanner s = new FastScanner();

            LOCAL = Local();

            
            if(LOCAL){
               // s = new FastScanner("src/input.txt");
                PrintStream o = new PrintStream("src/sampleout.txt");
                debug = new PrintStream("src/debug.txt");
                //System.setOut(o);
            }

            long mod = 1000000007;
            
            int tcr = 1;// s.nextInt();     
        
            StringBuilder sb = new StringBuilder();

            int dx[] = {0,0,-1,1,1,-1,1,-1};
            int dy[] = {-1,1,0,0,1,1,-1,-1};
            
        
            for(int tc=0;tc<tcr;tc++){
                
                int n = s.nextInt();

                int query[] = new int[n];
                
                Arrays.fill(query,1);

                int ans[] = new int[n];

                int next = 1;
                int index1 = -1;
                for(int i = n;i>=1;i--){
                    query[n-1] = i;
                    ask(query);
                    int tans = s.nextInt();
                    if(tans != 0){
                        ans[n-1] = n - i + 1;break;
                    }
                }

                query[n-1] = 1;

                if(ans[n-1] == 0){
                    ans[n-1] = n;
                }
                Arrays.fill(query,ans[n-1]);
                for(int i = 1;i<=n;i++){
                    if(ans[n-1] == i){continue;}
                    query[n-1] = i;
                    ask(query);
                    int tans = s.nextInt();
                    tans--;
                    ans[tans] = i;
                }

                sb.append("! ");


                for(int i=0;i<n;i++){
                    sb.append(ans[i]+" ");
                }
                sb.append('\n');








                
            }
            
            print(sb.toString());
        }

        public static void ask(int arr[]){
            StringBuilder sb = new StringBuilder();
            sb.append("? ");
            for(int i=0;i<arr.length;i++){
                sb.append(arr[i]+" ");
            }
            sb.append('\n');
            println(sb.toString());
        }

        public static boolean isPrime(int n){
            for(int i=2;(i*i)<=n;i++){
                if((n%i) == 0){
                    return false;
                }    
            }
            return true;
        }

        public static TreeNode buildTree(int l,int r,List<Long> arr){
            
            if(l>r){return null;}
         //   println(l+" "+r);
            if(l == r){
                TreeNode ans = new TreeNode(l,r);
                ans.gcd = arr.get(l);
                return ans;
            }

            TreeNode curr = new TreeNode(l,r);
            
            int mid = (l + r)/2;
            
            curr.left =  buildTree(l, mid, arr);
            
            curr.right = buildTree(mid+1,r, arr);
            
            long gcd = 0;
            
            if(curr.left != null){
                gcd = gcd(gcd,curr.left.gcd);
            }
            
            if(curr.right != null){
                gcd = gcd(gcd,curr.right.gcd);
            }
            curr.gcd = gcd;
            return curr;
        }

        public static long query(TreeNode node,int l,int r){
            
            if(l > r){
                return 0;
            }

         //   println(l+" "+r+" "+node);

            // if(node == null){
            //     return 0;
            // }

            if(node.l == l && node.r == r){
                return node.gcd;
            }

            int mid = (node.l + node.r)/2;

            int ls = l;
            int le = Math.min(r,mid);
            int rs = Math.max(l,mid+1);
            int re = r;

            return gcd(query(node.left,ls,le),query(node.right,rs,re));
        }

        
        static long getPairsCount(int n, long sum,long arr[])
        {
            HashMap<Long, Integer> hm = new HashMap<>();
        
        
            for (int i = 0; i < n; i++) {
                
                if (!hm.containsKey(arr[i])){
                    hm.put(arr[i], 0);
                    }
        
                hm.put(arr[i], hm.get(arr[i]) + 1);
            }
            long twice_count = 0;
            for (int i = 0; i < n; i++) {
                if (hm.get(sum - arr[i]) != null){
                    twice_count += hm.get(sum - arr[i]);
                }
        
                
                if (sum - arr[i] == arr[i]){
                    twice_count--;
                }
            }
        
            // return the half of twice_count
            return twice_count / 2l;
        }
        public static long ncr(int n,int r,long fact[]){
            if(r==0){return 1l;}
            long ans = fact[n];
            long denom = mulmod(fact[r], fact[n-r], mod);
            ans = mulmod(ans,modpow(denom,mod-2, mod),mod);
            return ans;
        }

        public static List<long[]> prime_factors(long n){

            List<long[]> list = new ArrayList<>();
            
            for(long i=2;i<=(Math.sqrt(n));i++){

                if(n % i == 0){
                    
                    int cnt = 0;
                    
                    while( (n % i) == 0){
                        n = n/i;
                        cnt++;
                        
                    }

                    list.add(new long[]{i,cnt});
                }
            }


            if(n!=1){
                list.add(new long[]{n,1l});
            }

            return list;

        }

        public static boolean check(int arr[]){
            for(int i=1;i<arr.length;i++){
                if(arr[i] < arr[i-1]){
                    return false;
                }
            }
            return true;
        }


        public static boolean inRange(int r1,int r2,int val){
            return ((val >= r1) && (val <= r2));
        }

        static int len(long num){
            return Long.toString(num).length();
        }

        static long mulmod(long a, long b,long mod)
        {
            long ans = 0l;
            
            while(b > 0l){
                long curr = (b & 1l);
                if(curr == 1l){
                    ans = ((ans % mod) + a) % mod;
                }
                
                a = (a + a) % mod;

                b = b >> 1;
            }

            return ans;
        }


        public static void dbg(PrintStream ps,Object... o) throws Exception{
            if(ps == null){
                return;
            }
            Debug.dbg(ps,o);
        }

        public static long modpow(long num,long pow,long mod){

            long val = num;
            long ans = 1l;

            while(pow > 0l){
                
                long bit = pow & 1l;

                if(bit == 1){
                    ans = (ans * (val%mod))%mod;
                }

                val = (val * val) % mod;
                pow = pow >> 1;
            }

            return ans;

        }

        public static char get(int n){
            return (char)('a' + n);
        }

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

        public static int[] sort(int arr[]){
            List<Integer> list = new ArrayList<>();
            for(int n : arr){list.add(n);}
            Collections.sort(list);
            for(int i=0;i<arr.length;i++){
                arr[i] = list.get(i);
            }
            return arr;
        }

        // return the (index + 1)
        // where index is the pos of just smaller element
        // i.e count of elemets strictly less than num
        public static int justSmaller(long arr[],long num){
            //  System.out.println(num+"@");
            int st = 0;
            int e = arr.length - 1;

            int ans = -1;

            while(st <= e){

                int mid = (st + e)/2;

                if(arr[mid] >= num){
                    e = mid - 1;
                }else{
                    ans = mid;
                    st = mid + 1;
                }

            }


            return ans + 1;

        }
        public static int justSmaller(int arr[],int num){
            //  System.out.println(num+"@");
            int st = 0;
            int e = arr.length - 1;

            int ans = -1;

            while(st <= e){

                int mid = (st + e)/2;

                if(arr[mid] >= num){
                    e = mid - 1;
                }else{
                    ans = mid;
                    st = mid + 1;
                }

            }


            return ans + 1;

        }
        
        //return (index of just greater element)
        //count of elements smaller than or equal to num

        public static int justGreater(long arr[],long num){
            int st = 0;
            int e = arr.length - 1;

            int ans = arr.length;

            while(st <= e){
                
                int mid = (st + e)/2;

                if(arr[mid] <= num){
                    st = mid + 1;
                }else{
                    ans = mid;
                    e = mid - 1;
                }
            }

            return ans;

        }

        public static int justGreater(int arr[],int num){
            int st = 0;
            int e = arr.length - 1;

            int ans = arr.length;

            while(st <= e){
                
                int mid = (st + e)/2;

                if(arr[mid] <= num){
                    st = mid + 1;
                }else{
                    ans = mid;
                    e = mid - 1;
                }
            }

            return ans;

        }

        

        public static void println(Object obj){
            System.out.println(obj.toString());
        }

        public static void print(Object obj){
            System.out.print(obj.toString());
        }

        public static int gcd(int a,int b){
            if(b == 0){return a;}
            return gcd(b,a%b);
        }

        public static long gcd(long a,long b){
            if(b == 0l){
                return a;
            }

            return gcd(b,a%b);
        }

        public static int find(int parent[],int v){
            if(parent[v] == v){
                return v;
            }
            
            return parent[v] = find(parent, parent[v]);
        }



        public static List<Integer> sieve(){
        
                List<Integer> prime = new ArrayList<>();

                int arr[] = new int[300001];

            Arrays.fill(arr,1);

            arr[1] = 0;
            arr[2] = 1;

            for(int i=2;i<300001;i++){
                
                if(arr[i] == 1){
                    
                    prime.add(i);

                    for(long j = (i*1l*i);j<300001;j+=i){
                        arr[(int)j] = 0;
                    }
                }
            }

            return prime;
        }

        static boolean isPower(long n,long a){
            
            long log = (long)(Math.log(n)/Math.log(a));

            long power = (long)Math.pow(a,log);

            if(power == n){return true;}

            return false;
        }


        private static int mergeAndCount(int[] arr, int l,int m, int r)
        {

            // Left subarray
            int[] left =  Arrays.copyOfRange(arr, l, m + 1);

            // Right subarray
            int[] right = Arrays.copyOfRange(arr, m + 1, r + 1);

            int i = 0, j = 0, k = l, swaps = 0;

            while (i < left.length && j < right.length) {
                if (left[i] <= right[j])
                    arr[k++] = left[i++];
                else {
                    arr[k++] = right[j++];
                    swaps += (m + 1) - (l + i);
                }
            }
            while (i < left.length)
                arr[k++] = left[i++];
            while (j < right.length)
                arr[k++] = right[j++];
            return swaps;
        }

        // Merge sort function
        private static int mergeSortAndCount(int[] arr, int l,int r)
        {

            // Keeps track of the inversion count at a
            // particular node of the recursion tree
            int count = 0;

            if (l < r) {
                int m = (l + r) / 2;

                // Total inversion count = left subarray count
                // + right subarray count + merge count

                // Left subarray count
                count += mergeSortAndCount(arr, l, m);

                // Right subarray count
                count += mergeSortAndCount(arr, m + 1, r);

                // Merge count
                count += mergeAndCount(arr, l, m, r);
            }

            return count;
        }

        static class Debug{
            //change to System.getProperty("ONLINE_JUDGE")==null; for CodeForces
            public static final boolean LOCAL = System.getProperty("ONLINE_JUDGE")==null;

            

            private static <T> String ts(T t) {
                if(t==null) {
                    return "null";
                }
                try {
                    return ts((Iterable) t);
                }catch(ClassCastException e) {
                    if(t instanceof int[]) {
                        String s = Arrays.toString((int[]) t);
                        return "{"+s.substring(1, s.length()-1)+"}\n";
                    }else if(t instanceof long[]) {
                        String s = Arrays.toString((long[]) t);
                        return "{"+s.substring(1, s.length()-1)+"}\n";
                    }else if(t instanceof char[]) {
                        String s = Arrays.toString((char[]) t);
                        return "{"+s.substring(1, s.length()-1)+"}\n";
                    }else if(t instanceof double[]) {
                        String s = Arrays.toString((double[]) t);
                        return "{"+s.substring(1, s.length()-1)+"}\n";
                    }else if(t instanceof boolean[]) {
                        String s = Arrays.toString((boolean[]) t);
                        return "{"+s.substring(1, s.length()-1)+"}\n";
                    }
                    try {
                        return ts((Object[]) t);
                    }catch(ClassCastException e1) {
                        return t.toString();
                    }
                }
            }
            private static <T> String ts(T[] arr) {
                StringBuilder ret = new StringBuilder();
                ret.append("{");
                boolean first = true;
                for(T t: arr) {
                    if(!first) {
                        ret.append(", ");
                    }
                    first = false;
                    ret.append(ts(t));
                }
                ret.append("}");
                return ret.toString();
            }
            private static <T> String ts(Iterable<T> iter) {
                StringBuilder ret = new StringBuilder();
                ret.append("{");
                boolean first = true;
                for(T t: iter) {
                    if(!first) {
                        ret.append(", ");
                    }
                    first = false;
                    ret.append(ts(t));
                }
                ret.append("}");
                return ret.toString();
            }
            public static void dbg(PrintStream ps,Object... o) throws Exception {
                if(LOCAL) {
                    System.setErr(ps);
                    System.err.print("Line #"+Thread.currentThread().getStackTrace()[2].getLineNumber()+": [");
                    for(int i = 0; i<o.length; i++) {
                        if(i!=0) {
                            System.err.print(", ");
                        }
                        System.err.print(ts(o[i]));
                    }
                    System.err.println("]");
                }
            }
    }

    }


    