description: 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.
solution: //package round749;
  import java.io.*;
  import java.util.ArrayDeque;
  import java.util.Arrays;
  import java.util.InputMismatchException;
  import java.util.Queue;
  
  public class D {
  	InputStream is;
  	FastWriter out;
  	String INPUT = "";
  	
  	void solve()
  	{
  		int n = ni();
  
  		int[] ret = new int[n];
  		for(int i = 2;i <= n;i++){
  			int[] a = new int[n];
  			Arrays.fill(a, 1);
  			a[n-1] = i;
  			out.print("? ");
  			for(int v : a){
  				out.print(v + " ");
  			}
  			out.println();
  			out.flush();
  			int got = ni()-1;
  			if(got != -1){
  				ret[got] = i-1;
  			}else{
  				break;
  			}
  		}
  		for(int i = 2;i <= n;i++){
  			int[] a = new int[n];
  			Arrays.fill(a, i);
  			a[n-1] = 1;
  			out.print("? ");
  			for(int v : a){
  				out.print(v + " ");
  			}
  			out.println();
  			out.flush();
  			int got = ni()-1;
  			if(got != -1){
  				ret[got] = -(i-1);
  			}else{
  				break;
  			}
  		}
  
  		int min = 0;
  		for(int i = 0;i < n-1;i++){
  			min = Math.min(min, ret[i]);
  		}
  
  		int cha = 1-min;
  
  		for(int i = 0;i < n;i++){
  			ret[i] += cha;
  		}
  
  		out.print("! ");
  		for(int v : ret){
  			out.print(v + " ");
  		}
  		out.println();
  		out.flush();
  	}
  	
  	void run() throws Exception
  	{
  		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
  		out = new FastWriter(System.out);
  		
  		long s = System.currentTimeMillis();
  		solve();
  		out.flush();
  		tr(System.currentTimeMillis()-s+"ms");
  	}
  	
  	public static void main(String[] args) throws Exception { new D().run(); }
  	
  	private byte[] inbuf = new byte[1024];
  	public int lenbuf = 0, ptrbuf = 0;
  	
  	private int readByte()
  	{
  		if(lenbuf == -1)throw new InputMismatchException();
  		if(ptrbuf >= lenbuf){
  			ptrbuf = 0;
  			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
  			if(lenbuf <= 0)return -1;
  		}
  		return inbuf[ptrbuf++];
  	}
  	
  	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
  	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }
  	
  	private double nd() { return Double.parseDouble(ns()); }
  	private char nc() { return (char)skip(); }
  	
  	private String ns()
  	{
  		int b = skip();
  		StringBuilder sb = new StringBuilder();
  		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
  			sb.appendCodePoint(b);
  			b = readByte();
  		}
  		return sb.toString();
  	}
  	
  	private char[] ns(int n)
  	{
  		char[] buf = new char[n];
  		int b = skip(), p = 0;
  		while(p < n && !(isSpaceChar(b))){
  			buf[p++] = (char)b;
  			b = readByte();
  		}
  		return n == p ? buf : Arrays.copyOf(buf, p);
  	}
  
  	private int[] na(int n)
  	{
  		int[] a = new int[n];
  		for(int i = 0;i < n;i++)a[i] = ni();
  		return a;
  	}
  
  	private long[] nal(int n)
  	{
  		long[] a = new long[n];
  		for(int i = 0;i < n;i++)a[i] = nl();
  		return a;
  	}
  
  	private char[][] nm(int n, int m) {
  		char[][] map = new char[n][];
  		for(int i = 0;i < n;i++)map[i] = ns(m);
  		return map;
  	}
  
  	private int[][] nmi(int n, int m) {
  		int[][] map = new int[n][];
  		for(int i = 0;i < n;i++)map[i] = na(m);
  		return map;
  	}
  
  	private int ni() { return (int)nl(); }
  
  	private long nl()
  	{
  		long num = 0;
  		int b;
  		boolean minus = false;
  		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
  		if(b == '-'){
  			minus = true;
  			b = readByte();
  		}
  
  		while(true){
  			if(b >= '0' && b <= '9'){
  				num = num * 10 + (b - '0');
  			}else{
  				return minus ? -num : num;
  			}
  			b = readByte();
  		}
  	}
  
  	public static class FastWriter
  	{
  		private static final int BUF_SIZE = 1<<13;
  		private final byte[] buf = new byte[BUF_SIZE];
  		private final OutputStream out;
  		private int ptr = 0;
  
  		private FastWriter(){out = null;}
  
  		public FastWriter(OutputStream os)
  		{
  			this.out = os;
  		}
  
  		public FastWriter(String path)
  		{
  			try {
  				this.out = new FileOutputStream(path);
  			} catch (FileNotFoundException e) {
  				throw new RuntimeException("FastWriter");
  			}
  		}
  
  		public FastWriter write(byte b)
  		{
  			buf[ptr++] = b;
  			if(ptr == BUF_SIZE)innerflush();
  			return this;
  		}
  
  		public FastWriter write(char c)
  		{
  			return write((byte)c);
  		}
  
  		public FastWriter write(char[] s)
  		{
  			for(char c : s){
  				buf[ptr++] = (byte)c;
  				if(ptr == BUF_SIZE)innerflush();
  			}
  			return this;
  		}
  
  		public FastWriter write(String s)
  		{
  			s.chars().forEach(c -> {
  				buf[ptr++] = (byte)c;
  				if(ptr == BUF_SIZE)innerflush();
  			});
  			return this;
  		}
  
  		private static int countDigits(int l) {
  			if (l >= 1000000000) return 10;
  			if (l >= 100000000) return 9;
  			if (l >= 10000000) return 8;
  			if (l >= 1000000) return 7;
  			if (l >= 100000) return 6;
  			if (l >= 10000) return 5;
  			if (l >= 1000) return 4;
  			if (l >= 100) return 3;
  			if (l >= 10) return 2;
  			return 1;
  		}
  
  		public FastWriter write(int x)
  		{
  			if(x == Integer.MIN_VALUE){
  				return write((long)x);
  			}
  			if(ptr + 12 >= BUF_SIZE)innerflush();
  			if(x < 0){
  				write((byte)'-');
  				x = -x;
  			}
  			int d = countDigits(x);
  			for(int i = ptr + d - 1;i >= ptr;i--){
  				buf[i] = (byte)('0'+x%10);
  				x /= 10;
  			}
  			ptr += d;
  			return this;
  		}
  
  		private static int countDigits(long l) {
  			if (l >= 1000000000000000000L) return 19;
  			if (l >= 100000000000000000L) return 18;
  			if (l >= 10000000000000000L) return 17;
  			if (l >= 1000000000000000L) return 16;
  			if (l >= 100000000000000L) return 15;
  			if (l >= 10000000000000L) return 14;
  			if (l >= 1000000000000L) return 13;
  			if (l >= 100000000000L) return 12;
  			if (l >= 10000000000L) return 11;
  			if (l >= 1000000000L) return 10;
  			if (l >= 100000000L) return 9;
  			if (l >= 10000000L) return 8;
  			if (l >= 1000000L) return 7;
  			if (l >= 100000L) return 6;
  			if (l >= 10000L) return 5;
  			if (l >= 1000L) return 4;
  			if (l >= 100L) return 3;
  			if (l >= 10L) return 2;
  			return 1;
  		}
  
  		public FastWriter write(long x)
  		{
  			if(x == Long.MIN_VALUE){
  				return write("" + x);
  			}
  			if(ptr + 21 >= BUF_SIZE)innerflush();
  			if(x < 0){
  				write((byte)'-');
  				x = -x;
  			}
  			int d = countDigits(x);
  			for(int i = ptr + d - 1;i >= ptr;i--){
  				buf[i] = (byte)('0'+x%10);
  				x /= 10;
  			}
  			ptr += d;
  			return this;
  		}
  
  		public FastWriter write(double x, int precision)
  		{
  			if(x < 0){
  				write('-');
  				x = -x;
  			}
  			x += Math.pow(10, -precision)/2;
  			//		if(x < 0){ x = 0; }
  			write((long)x).write(".");
  			x -= (long)x;
  			for(int i = 0;i < precision;i++){
  				x *= 10;
  				write((char)('0'+(int)x));
  				x -= (int)x;
  			}
  			return this;
  		}
  
  		public FastWriter writeln(char c){
  			return write(c).writeln();
  		}
  
  		public FastWriter writeln(int x){
  			return write(x).writeln();
  		}
  
  		public FastWriter writeln(long x){
  			return write(x).writeln();
  		}
  
  		public FastWriter writeln(double x, int precision){
  			return write(x, precision).writeln();
  		}
  
  		public FastWriter write(int... xs)
  		{
  			boolean first = true;
  			for(int x : xs) {
  				if (!first) write(' ');
  				first = false;
  				write(x);
  			}
  			return this;
  		}
  
  		public FastWriter write(long... xs)
  		{
  			boolean first = true;
  			for(long x : xs) {
  				if (!first) write(' ');
  				first = false;
  				write(x);
  			}
  			return this;
  		}
  
  		public FastWriter writeln()
  		{
  			return write((byte)'\n');
  		}
  
  		public FastWriter writeln(int... xs)
  		{
  			return write(xs).writeln();
  		}
  
  		public FastWriter writeln(long... xs)
  		{
  			return write(xs).writeln();
  		}
  
  		public FastWriter writeln(char[] line)
  		{
  			return write(line).writeln();
  		}
  
  		public FastWriter writeln(char[]... map)
  		{
  			for(char[] line : map)write(line).writeln();
  			return this;
  		}
  
  		public FastWriter writeln(String s)
  		{
  			return write(s).writeln();
  		}
  
  		private void innerflush()
  		{
  			try {
  				out.write(buf, 0, ptr);
  				ptr = 0;
  			} catch (IOException e) {
  				throw new RuntimeException("innerflush");
  			}
  		}
  
  		public void flush()
  		{
  			innerflush();
  			try {
  				out.flush();
  			} catch (IOException e) {
  				throw new RuntimeException("flush");
  			}
  		}
  
  		public FastWriter print(byte b) { return write(b); }
  		public FastWriter print(char c) { return write(c); }
  		public FastWriter print(char[] s) { return write(s); }
  		public FastWriter print(String s) { return write(s); }
  		public FastWriter print(int x) { return write(x); }
  		public FastWriter print(long x) { return write(x); }
  		public FastWriter print(double x, int precision) { return write(x, precision); }
  		public FastWriter println(char c){ return writeln(c); }
  		public FastWriter println(int x){ return writeln(x); }
  		public FastWriter println(long x){ return writeln(x); }
  		public FastWriter println(double x, int precision){ return writeln(x, precision); }
  		public FastWriter print(int... xs) { return write(xs); }
  		public FastWriter print(long... xs) { return write(xs); }
  		public FastWriter println(int... xs) { return writeln(xs); }
  		public FastWriter println(long... xs) { return writeln(xs); }
  		public FastWriter println(char[] line) { return writeln(line); }
  		public FastWriter println(char[]... map) { return writeln(map); }
  		public FastWriter println(String s) { return writeln(s); }
  		public FastWriter println() { return writeln(); }
  	}
  
  	public void trnz(int... o)
  	{
  		for(int i = 0;i < o.length;i++)if(o[i] != 0)System.out.print(i+":"+o[i]+" ");
  		System.out.println();
  	}
  
  	// print ids which are 1
  	public void trt(long... o)
  	{
  		Queue<Integer> stands = new ArrayDeque<>();
  		for(int i = 0;i < o.length;i++){
  			for(long x = o[i];x != 0;x &= x-1)stands.add(i<<6|Long.numberOfTrailingZeros(x));
  		}
  		System.out.println(stands);
  	}
  
  	public void tf(boolean... r)
  	{
  		for(boolean x : r)System.out.print(x?'#':'.');
  		System.out.println();
  	}
  
  	public void tf(boolean[]... b)
  	{
  		for(boolean[] r : b) {
  			for(boolean x : r)System.out.print(x?'#':'.');
  			System.out.println();
  		}
  		System.out.println();
  	}
  
  	public void tf(long[]... b)
  	{
  		if(INPUT.length() != 0) {
  			for (long[] r : b) {
  				for (long x : r) {
  					for (int i = 0; i < 64; i++) {
  						System.out.print(x << ~i < 0 ? '#' : '.');
  					}
  				}
  				System.out.println();
  			}
  			System.out.println();
  		}
  	}
  
  	public void tf(long... b)
  	{
  		if(INPUT.length() != 0) {
  			for (long x : b) {
  				for (int i = 0; i < 64; i++) {
  					System.out.print(x << ~i < 0 ? '#' : '.');
  				}
  			}
  			System.out.println();
  		}
  	}
  
  	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
  	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
  }
  