Problem: This is an interactive problem. Remember to flush your output while communicating with the testing program. You may use fflush(stdout) in C++, system.out.flush() in Java, stdout.flush() in Python or flush(output) in Pascal to flush the output. If you use some other programming language, consult its documentation. You may also refer to the guide on interactive problems: <https://codeforces.com/blog/entry/45307>.

The jury guessed some array a consisting of 6 integers. There are 6 special numbers — 4, 8, 15, 16, 23, 42 — and each of these numbers occurs in a exactly once (so, a is some permutation of these numbers).

You don't know anything about their order, but you are allowed to ask up to 4 queries. In each query, you may choose two indices i and j (1 ≤ i, j ≤ 6, i and j are not necessarily distinct), and you will get the value of a_i ⋅ a_j in return.

Can you guess the array a?

The array a is fixed beforehand in each test, the interaction program doesn't try to adapt to your queries.

Interaction

Before submitting the answer, you may ask up to 4 queries. To ask a query, print one line in the following format: ? i j, where i and j should be two integers such that 1 ≤ i, j ≤ 6. The line should be ended with a line break character. After submitting a query, flush the output and read the answer to your query — one line containing one integer a_i ⋅ a_j. If you submit an incorrect query (or ask more than 4 queries), the answer to it will be one string 0. After receiving such an answer, your program should terminate immediately — otherwise you may receive verdict "Runtime error", "Time limit exceeded" or some other verdict instead of "Wrong answer".

To give the answer, your program should print one line ! a_1 a_2 a_3 a_4 a_5 a_6 with a line break in the end. After that, it should flush the output and terminate gracefully.

Example

Input


16
64
345
672

Output


? 1 1
? 2 2
? 3 5
? 4 6
! 4 8 15 16 23 42

Note

If you want to submit a hack for this problem, your test should contain exactly six space-separated integers a_1, a_2, ..., a_6. Each of 6 special numbers should occur exactly once in the test. The test should be ended with a line break character.

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;
import java.math.*;
import java.lang.reflect.Array;

public class Main {
    static final int MOD = 1000000007; // 1e9 + 7
    static final boolean AUTO_FLUSH = false; // slow if true
    // int = num();         // long = ll();
    // string = next();     // a string line = line();
    // ---------------------------------- \\
    @SuppressWarnings("unchecked")
    void SOLVE_THE_PROBLEM() throws Exception {
        HashMap<Integer, Integer[]> map = new HashMap<>();
        int[] arr = {4, 8, 15, 16, 23, 42};
        for (int i = 0; i < 6; i++)
            for (int j = 0; j < 6; j++)
                for (int k = 0; k < 6; k++)
                    if (i != j && i != k && j != k)
                        map.put(arr[i]*arr[j]*arr[i]*arr[j] + arr[i]*arr[k]*arr[i]*arr[k], new Integer[] {arr[i], arr[j], arr[k]});
        int[] ans = new int[6];

        outln("? 1 2");
        _f();
        int res = num();
        outln("? 1 3");
        _f();
        int next = num();
        Integer[] a = map.get(res*res+next*next);
        ans[0] = a[0];
        ans[1] = res > next ? Math.max(a[1], a[2]) : Math.min(a[1], a[2]);
        ans[2] = res < next ? Math.max(a[1], a[2]) : Math.min(a[1], a[2]);

        outln("? 4 5");
        _f();
        res = num();
        outln("? 4 6");
        _f();
        next = num();
        a = map.get(res*res+next*next);
        ans[3] = a[0];
        ans[4] = res > next ? Math.max(a[1], a[2]) : Math.min(a[1], a[2]);
        ans[5] = res < next ? Math.max(a[1], a[2]) : Math.min(a[1], a[2]);
        /*int[] cnt = new int[2];
        int found4 = -1, found8 = -1;
        for (int i = 0; i < 6; i++) {
            if (ans[i] == 4) {
                cnt[0]++;
                found4 = i;
            }
            if (ans[i] == 8) {
                cnt[1]++;
                found8 = i;
            }
        }
        if (cnt[0] > 1) {
            if (found4 < 3)
                ans[3] = 8;
            else
                ans[0] = 8;
            ans[found8] = 16;
        }
        if (cnt[1] > 1) {
            if (found8 < 3)
                ans[3] = 4;
            else
                ans[0] = 4;
            ans[found4] = 16;
        }*/
        //> 8 23 4 8 15 42
        //! 4 23 16 8 15 42
        out("!");
        for (int num : ans)
            out(" " + num);
        outln();
    }
    void _f() {
        flush();System.out.flush();
    }
    // ---------------------------------- \\
    public static void main(String[] args) throws Exception {
        new Thread(null, () -> {
            try {
                startTime();
                new Main().SOLVE_THE_PROBLEM();
                boolean useEnter = TO_BE_PRINTED.length() == 0 || TO_BE_PRINTED.charAt(TO_BE_PRINTED.length() - 1) == '\n';
                flush();
                if (!useEnter)
                    log('\n');
                logTime();
                logMem();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "Main", 1<<26).start();
    }
    static void logTime() {
        log("Time: " + getTime() + "ms");
    }
    static void logMem() {
        log("Memory (End): " + (int) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 + " KB");
    }
    static long ll() {
        return Long.parseLong(next());
    }
    static int num() {
        return Integer.parseInt(next());
    }
    static void generateInputMode() throws Exception {
        System.setOut(new PrintStream(new FileOutputStream("F://PROGRAMMING/input.txt")));
    }
    static String line() {
        if (!tokenize())
            return null;
        INPUT_STREAM.setLength(0);
        if (STRING_TOKENIZER.hasMoreTokens())
            INPUT_STREAM.append(STRING_TOKENIZER.nextToken());
        while (STRING_TOKENIZER.hasMoreTokens())
            INPUT_STREAM.append(' ').append(STRING_TOKENIZER.nextToken());
        return INPUT_STREAM.length() == 0 ? null : INPUT_STREAM.toString();
    }
    static void startTime() {
        TIME_COMPLEXITY = System.currentTimeMillis();
    }
    static long getTime() {
        return System.currentTimeMillis() - TIME_COMPLEXITY;
    }
    static void flush() {
        System.out.print(TO_BE_PRINTED.toString());
        TO_BE_PRINTED.setLength(0);
    }
    static void out(Object o) {
        TO_BE_PRINTED.append(o.toString());
        if (AUTO_FLUSH)
            flush();
    }
    static void _log(String s) {
        System.err.print(s);
    }
    static void _logln(String s) {
        System.err.println(s);
    }
    static void _logln() {
        System.err.println();
    }
    static void outln(Object o) {
        out(o);
        outln();
    }
    static void outln() {
        TO_BE_PRINTED.append("\n");
        if (AUTO_FLUSH)
            flush();
    }
    static class Pair implements Comparable<Pair> {
        public int a, b;
        public Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }
        public static Pair of(int a, int b) {
            return new Pair(a, b);
        }
        public int compareTo(Pair p) {
            if (a == p.a)
                return Integer.compare(b, p.b);
            return Integer.compare(a, p.a);
        }
        public String toString() {
            return "[" + a + "," + b + "]";
        }
        public boolean equals(Pair p) {
            return p.a == a && p.b == b;
        }
    }
    static void logArr(Object val) {
        Class<?> valKlass = val.getClass();
        Object[] outputArray = null;
        for(Class<?> arrKlass : new Class<?>[] { int[].class, float[].class, double[].class, boolean[].class, 
            byte[].class, short[].class, long[].class, char[].class }) {
            if (valKlass.isAssignableFrom(arrKlass)) {
                int arrlength = Array.getLength(val);
                outputArray = new Object[arrlength];
                for(int i = 0; i < arrlength; ++i)
                    outputArray[i] = Array.get(val, i);
                break;
            }
        }
        if(outputArray == null)
            outputArray = (Object[])val;
        logArr0(outputArray);
    }
    static void logArr0(Object[] objs) {
        _log("* " + objs[0]);
        for (int i = 1; i < objs.length; i++)
            _log(objs[i].toString().equals("\n") ? "\n>" : (" " + objs[i]));
        _logln();
    }
    static void log(Object... objs) {
        logArr0(objs);
    }
    static String next() {
        return tokenize() ? STRING_TOKENIZER.nextToken() : null;
    }
    static boolean tokenize() {
        if (STRING_TOKENIZER == null || !STRING_TOKENIZER.hasMoreTokens()) {
            try {
                STRING_TOKENIZER = new StringTokenizer(STREAM_READER.readLine());
            } catch (Exception e) {
                return false;
            }
        }
        return true;
    }
    static long TIME_COMPLEXITY;
    static BufferedReader STREAM_READER = new BufferedReader(new InputStreamReader(System.in), 32768);
    static StringTokenizer STRING_TOKENIZER;
    static StringBuilder INPUT_STREAM = new StringBuilder(), TO_BE_PRINTED = new StringBuilder();
}