Problem:
E: 最短経路の復元
物語
競技プログラマーは日々最短経路問題を解いている。BFS や、ベルマンフォード、ダイクストラ、ワーシャルフロイドと多くのアルゴリズムも知られている。
あなたはそんな中、どうしても解けない最短路問題があった。それはグラフを見ずに最短路問題を解けという問題だ！こんなもの通常の人類には解けるわけがないのだが、30 分だけ ivvivvi 神の天啓を受けることができるようになった。
ivvivvi 神は競技プログラミングにも最短経路問題にも精通しており、どんなグラフに対しても任意の 2 点間の最短経路長を定数時間で求める能力を持っている。あなたは ivvivvi 神の力を借りて最短経路問題を解こうと思ったが、残念ながらあなたの解くべき最短経路問題では具体的な経路を出力しなければならない。ivvivvi 神なら、最短経路の復元も容易だが、ivvivvi 神は非常に忙しいので、これ以上手を煩わせるわけには行けない。そこで、できるだけ少ない質問回数で自力で最短経路を復元することにした。
問題
3
つの整数
N
、
s
、そして、
t
が与えられる。このとき、頂点数
N
のグラフがあり、頂点数以外の辺数や頂点の隣接関係などのグラフに関する情報は与えられないが、
2
頂点
u
、
v
の距離を質問することができる。ここで、グラフの頂点番号は
1
以上
N
以下である。
5N
回以下の質問回数で
s
から
t
への最短路を発見し、最短路を表す頂点列を
1
つ出力せよ。
この問題では
2
頂点
u
、
v
間の距離をジャッジに質問しなければならない。
標準出力に次のように出力することで、
u
、
v
間の距離を質問することができる。
?
u
v
このように標準出力したあと、この答えは標準入力に
1
行の整数として与えられる。
この問題ではプログラムの行った質問の回数が
5N
回を超えると誤答（WA）と判定される。この問題では最後に頂点列、つまり整数列を出力する。頂点列
(x_1, ..., x_k)
を出力する出力形式は次のようである。
!
x_1
x_2
...
x_k
ここで、出力は
x_1 = s
、
x_k = t
を満たし、任意の
1 \leq i \leq k - 1
に対して、
x_i
と
x_{i + 1}
を直接結ぶ辺が存在する。
さらに、この最終的な解答は、一度しか行うことができない。この解答が正しい出力だったとき、正答とみなす。さらに、標準出力として上記の
2
つの記法と異なる出力や質問回数が
5N
回を超えた時はジャッジは
-1
を返す。この時、即座にプログラムを終了させない場合、ジャッジが WA を正しく判定することを保証しない。
また、標準出力を行う毎に、ストリームをフラッシュ (flush) する必要があることに注意されよ。主要な言語でのフラッシュ例を以下に示す。もちろん、これ以外の方法でフラッシュを行っても構わない。
C 言語:
#include <stdio.h>
fflush(stdout);
C++:
#include <iostream>
std::cout.flush();
Java:
System.out.flush();
Python:
print(end='', flush=True)
入力形式
入力として整数
3
つが与えられる。
N
s
t
制約
2 \leq N \leq 300
1 \leq s, t \leq N
s \neq t
問題において使用されるグラフ上の任意の 2 頂点
u
,
v
について、最短距離を求めたものの最大値は
10^9
以下である
問題において使用されるグラフは連結であることが保証される
入出力例
標準入力
標準出力
4 1 3
? 4 3
3
? 1 4
2
? 2 1
1
? 3 2
2
? 1 3
3
? 4 2
1
! 1 2 3
この入出力例では以下のグラフに対して 2 点間の距離を質問している。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=9167167167167167167;
const int INF=10000000;

#define rep(i,a) for (int i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}



void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	int t=1;
	//cin>>t;
	rep(i,t) solve();
}

void solve(){
	int N,S,T;
	cin>>N>>S>>T;
	S--,T--;
	vector<int> order(N);
	vector<int> dist(N);
	vector<int> ans={T};
	auto out=[](int a,int b)->void{
		cout<<"? "<<a+1<<" "<<b+1<<endl;
	};
	rep(i,N){
		if(i!=S){
			out(i,S);
			cin>>dist[i];
		}
		order[i]=i;
	}
	sort(all(order),[&](int l,int r){
		return dist[l]<dist[r];
	});
	for(int i=N-1;i>=0;i--){
		int a=order[i];
		if(dist[a]>=dist[T]) continue;
		out(T,a);
		int tmp;
		cin>>tmp;
		if(tmp+dist[a]==dist[T]){
			ans.push_back(a);
			T=a;
		}
	}
	reverse(all(ans));
	cout<<"!";
	for(auto x:ans) cout<<" "<<x+1;
	cout<<endl;
}
accuracy: 1
time_ms: 30
memory_kb: 5188
final_rank: 14

code_snippet: #line 1 "/home/yuruhiya/programming/library/template14.cpp"
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1e9;
constexpr long long inf_ll = 1e18, MOD = 1000000007;
constexpr long double PI = M_PI, EPS = 1e-12;

// --- input --- //
#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Input {
	static int gc() {
		return getchar_unlocked();
	}
	template <class T> static void i(T& v) {
		cin >> v;
	}
	static void i(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void i(bool& v) {
		v = in<char>() != '0';
	}
	static void i(string& v) {
		v.clear();
		char c;
		for (i(c); !isspace(c); c = gc()) v += c;
	}
	static void i(int& v) {
		bool neg = false;
		v = 0;
		char c;
		i(c);
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void i(long long& v) {
		bool neg = false;
		v = 0;
		char c;
		i(c);
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void i(double& v) {
		double dp = 1;
		bool neg = false, adp = false;
		v = 0;
		char c;
		i(c);
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.')
				adp = true;
			else if (adp)
				v += (c - '0') * (dp *= 0.1);
			else
				v = v * 10 + (c - '0');
		}
		if (neg) v = -v;
	}
	static void i(long double& v) {
		long double dp = 1;
		bool neg = false, adp = false;
		v = 0;
		char c;
		i(c);
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.')
				adp = true;
			else if (adp)
				v += (c - '0') * (dp *= 0.1);
			else
				v = v * 10 + (c - '0');
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void i(pair<T, U>& v) {
		i(v.first);
		i(v.second);
	}
	template <class T> static void i(vector<T>& v) {
		for (auto& e : v) i(e);
	}
	struct InputV {
		int n, m;
		InputV(int _n) : n(_n), m(0) {}
		InputV(const pair<int, int>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			i(v);
			return v;
		}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			i(v);
			return v;
		}
	};

public:
	static string read_line() {
		string v;
		char c;
		for (i(c); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> static T in() {
		T v;
		i(v);
		return v;
	}
	template <class T> operator T() const {
		return in<T>();
	}
	int operator--(int) const {
		return in<int>() - 1;
	}
	InputV operator[](int n) const {
		return InputV(n);
	}
	InputV operator[](const pair<int, int>& n) const {
		return InputV(n);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		i(h);
		operator()(forward<T>(t)...);
	}
} in;
#define input(T) Input::in<T>()
#define INT input(int)
#define LL input(long long)
#define STR input(string)
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)

// --- output --- //
struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};
	void p(int v) const {
		if (v < 0) putchar_unlocked('-'), v = -v;
		char b[10];
		int i = 0;
		while (v) b[i++] = '0' + v % 10, v /= 10;
		if (!i) b[i++] = '0';
		while (i--) putchar_unlocked(b[i]);
	}
	void p(long long v) const {
		if (v < 0) putchar_unlocked('-'), v = -v;
		char b[20];
		int i = 0;
		while (v) b[i++] = '0' + v % 10, v /= 10;
		if (!i) b[i++] = '0';
		while (i--) putchar_unlocked(b[i]);
	}
	void p(bool v) const {
		p(v ? B.t : B.f);
	}
	void p(char v) const {
		putchar_unlocked(v);
	}
	void p(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void p(double v) const {
		printf("%.20f", v);
	}
	void p(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void p(const T& v) const {
		cout << v;
	}
	template <class T, class U> void p(const pair<T, U>& v) const {
		p(v.first);
		p(D.d);
		p(v.second);
	}
	template <class T> void p(const vector<T>& v) const {
		rep(i, sz(v)) {
			if (i) p(D.d);
			p(v[i]);
		}
	}
	template <class T> void p(const vector<vector<T>>& v) const {
		rep(i, sz(v)) {
			if (i) p(D.l);
			p(v[i]);
		}
	}

public:
	Output& operator()() {
		p(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		p(h);
		p(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		p(h);
		p(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class It> Output& range(const It& l, const It& r) {
		for (It i = l; i != r; i++) {
			if (i != l) p(D.d);
			p(*i);
		}
		p(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;

// --- step --- //
template <class T> struct Step {
	class It {
		T a, b, c;

	public:
		constexpr It() : a(T()), b(T()), c(T()) {}
		constexpr It(T _b, T _c, T _s) : a(_b), b(_c), c(_s) {}
		constexpr It& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr It operator++(int) {
			It tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const T& operator*() const {
			return a;
		}
		constexpr const T* operator->() const {
			return &a;
		}
		constexpr bool operator==(const It& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const It& i) const {
			return !(b == i.b);
		}
		constexpr T start() const {
			return a;
		}
		constexpr T count() const {
			return b;
		}
		constexpr T step() const {
			return c;
		}
	};
	constexpr Step(T b, T c, T s) : be(b, c, s) {}
	constexpr It begin() const {
		return be;
	}
	constexpr It end() const {
		return en;
	}
	constexpr T start() const {
		return be.start();
	}
	constexpr T count() const {
		return be.count();
	}
	constexpr T step() const {
		return be.step();
	}
	constexpr T sum() const {
		return start() * count() + step() * (count() * (count() - 1) / 2);
	}
	operator vector<T>() const {
		return to_a();
	}
	template <class F> void each(const F& f) const {
		for (T i : *this) f(i);
	}
	auto to_a() const {
		vector<T> res;
		res.reserve(count());
		each([&](T i) { res.push_back(i); });
		return res;
	}
	template <class F, class U = decay_t<result_of_t<F(T)>>> auto map(const F& f) const {
		vector<U> res;
		res.reserve(count());
		each([&](T i) { res.push_back(f(i)); });
		return res;
	}
	template <class F> auto select(const F& f) const {
		vector<T> res;
		each([&](T i) {
			if (f(i)) res.push_back(i);
		});
		return res;
	}
	template <class F> int count_if(const F& f) const {
		int res = 0;
		each([&](T i) {
			if (f(i)) ++res;
		});
		return res;
	}
	template <class F> T find_if(const F& f) const {
		for (T i : *this)
			if (f(i)) return i;
		return 0;
	}
	template <class F> auto max_by(const F& f) const {
		auto v = map(f);
		return *max_element(v.begin(), v.end());
	}
	template <class F> auto min_by(const F& f) const {
		auto v = map(f);
		return *min_element(v.begin(), v.end());
	}
	template <class F> bool all_of(const F& f) const {
		for (T i : *this)
			if (!f(i)) return false;
		return true;
	}
	template <class F> bool any_of(const F& f) const {
		for (T i : *this)
			if (f(i)) return true;
		return false;
	}
	template <class F, class U = decay_t<result_of_t<F(T)>>> auto sum(const F& f) const {
		U res = 0;
		each([&](T i) { res += static_cast<U>(f(i)); });
		return res;
	}
	using value_type = T;
	using iterator = It;

private:
	It be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}

// --- functions --- //
inline namespace {
	template <class T> void Sort(T& a) {
		sort(all(a));
	}
	template <class T> void RSort(T& a) {
		sort(rall(a));
	}
	template <class T, class F> void Sort(T& a, const F& f) {
		sort(all(a), f);
	}
	template <class T, class F> void RSort(T& a, const F& f) {
		sort(rall(a), f);
	}
	template <class T> T Sorted(T a) {
		Sort(a);
		return a;
	}
	template <class T> T RSorted(T a) {
		RSort(a);
		return a;
	}
	template <class T, class F> T Sorted(T& a, const F& f) {
		Sort(a, f);
		return a;
	}
	template <class T, class F> T RSorted(T& a, const F& f) {
		RSort(a, f);
		return a;
	}
	template <class T, class F> void SortBy(T& a, const F& f) {
		sort(all(a), [&](const auto& x, const auto& y) { return f(x) < f(y); });
	}
	template <class T, class F> void RSortBy(T& a, const F& f) {
		sort(rall(a), [&](const auto& x, const auto& y) { return f(x) < f(y); });
	}
	template <class T> void Reverse(T& a) {
		reverse(all(a));
	}
	template <class T> void Unique(T& a) {
		a.erase(unique(all(a)), a.end());
	}
	template <class T> void Uniq(T& a) {
		Sort(a);
		Unique(a);
	}
	template <class T> void Rotate(T& a, int left) {
		rotate(a.begin(), a.begin() + left, a.end());
	}
	template <class T> T Reversed(T a) {
		Reverse(a);
		return a;
	}
	template <class T> T Uniqued(T a) {
		Unique(a);
		return a;
	}
	template <class T> T Uniqed(T a) {
		Uniq(a);
		return a;
	}
	template <class T> T Rotated(T a, int left) {
		Rotate(a, left);
		return a;
	}
	template <class T> auto Max(const T& a) {
		return *max_element(all(a));
	}
	template <class T> auto Min(const T& a) {
		return *min_element(all(a));
	}
	template <class T> int MaxPos(const T& a) {
		return max_element(all(a)) - a.begin();
	}
	template <class T> int MinPos(const T& a) {
		return min_element(all(a)) - a.begin();
	}
	template <class T, class F> auto MaxBy(const T& a, const F& f) {
		return *max_element(all(a),
		                    [&](const auto& x, const auto& y) { return f(x) < f(y); });
	}
	template <class T, class F> auto MinBy(const T& a, const F& f) {
		return *min_element(all(a),
		                    [&](const auto& x, const auto& y) { return f(x) < f(y); });
	}
	template <class T, class F> auto MaxOf(const T& a, const F& f) {
		return Max(Map(a, f));
	}
	template <class T, class F> auto MinOf(const T& a, const F& f) {
		return Min(Map(a, f));
	}
	template <class T, class U> int Count(const T& a, const U& v) {
		return count(all(a), v);
	}
	template <class T, class F> int CountIf(const T& a, const F& f) {
		return count_if(all(a), f);
	}
	template <class T, class U> int Find(const T& a, const U& v) {
		return find(all(a), v) - a.begin();
	}
	template <class T, class F> int FindIf(const T& a, const F& f) {
		return find_if(all(a), f) - a.begin();
	}
	template <class T, class U = typename T::value_type> U Sum(const T& a) {
		return accumulate(all(a), U());
	}
	template <class T, class U> bool Includes(const T& a, const U& v) {
		return find(all(a), v) != a.end();
	}
	template <class T, class F> auto Sum(const T& v, const F& f) {
		return accumulate(next(v.begin()), v.end(), f(*v.begin()),
		                  [&](auto a, auto b) { return a + f(b); });
	}
	template <class T, class U> int Lower(const T& a, const U& v) {
		return lower_bound(all(a), v) - a.begin();
	}
	template <class T, class U> int Upper(const T& a, const U& v) {
		return upper_bound(all(a), v) - a.begin();
	}
	template <class T, class F> void RemoveIf(T& a, const F& f) {
		a.erase(remove_if(all(a), f), a.end());
	}
	template <class F> auto Vector(size_t size, const F& f) {
		vector<decay_t<result_of_t<F(size_t)>>> res(size);
		for (size_t i = 0; i < size; ++i) res[i] = f(i);
		return res;
	}
	template <class T> auto Grid(size_t h, size_t w, const T& v = T()) {
		return vector<vector<T>>(h, vector<T>(w, v));
	}
	template <class T> auto Slice(const T& v, size_t i, size_t len) {
		return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
	}
	template <class T, class F> auto Each(const T& v, F&& f) {
		for (auto& i : v) f(i);
	}
	template <class T, class F> auto Select(const T& v, const F& f) {
		T res;
		for (const auto& e : v)
			if (f(e)) res.push_back(e);
		return res;
	}
	template <class T, class F> auto Map(const T& v, F&& f) {
		vector<decay_t<result_of_t<F(typename T::value_type)>>> res(v.size());
		size_t i = 0;
		for (const auto& e : v) res[i++] = f(e);
		return res;
	}
	template <class T, class F> auto MapIndex(const T& v, const F& f) {
		vector<decay_t<result_of_t<F(size_t, typename T::value_type)>>> res(v.size());
		size_t i = 0;
		for (auto it = v.begin(); it != v.end(); ++it, ++i) res[i] = f(i, *it);
		return res;
	}
	template <class T, class F> auto TrueIndex(const T& v, const F& f) {
		vector<size_t> res;
		for (size_t i = 0; i < v.size(); ++i)
			if (f(v[i])) res.push_back(i);
		return res;
	}
	template <class T, class U = typename T::value_type> auto Indexed(const T& v) {
		vector<pair<U, int>> res(v.size());
		for (int i = 0; i < (int)v.size(); ++i)
			res[i] = make_pair(static_cast<U>(v[i]), i);
		return res;
	}
	auto operator*(string s, size_t n) {
		string res;
		for (size_t i = 0; i < n; ++i) res += s;
		return res;
	}
	template <class T> auto& operator<<(vector<T>& v, const vector<T>& v2) {
		v.insert(v.end(), all(v2));
		return v;
	}
	template <class T> T Ceil(T n, T m) {
		return (n + m - 1) / m;
	}
	template <class T> T Ceil2(T n, T m) {
		return Ceil(n, m) * m;
	}
	template <class T> T Tri(T n) {
		return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
	}
	template <class T> T nC2(T n) {
		return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
	}
	template <class T> T Mid(const T& l, const T& r) {
		return l + (r - l) / 2;
	}
	template <class T> bool chmax(T& a, const T& b) {
		if (a < b) {
			a = b;
			return true;
		}
		return false;
	}
	template <class T> bool chmin(T& a, const T& b) {
		if (a > b) {
			a = b;
			return true;
		}
		return false;
	}
	template <class T> bool inRange(const T& v, const T& min, const T& max) {
		return min <= v && v < max;
	}
	template <class T> bool isSquere(T n) {
		T s = sqrt(n);
		return s * s == n || (s + 1) * (s + 1) == n;
	}
	template <class T = long long> T BIT(int b) {
		return T(1) << b;
	}
	template <class T> T Gcd(T n, T m) {
		return m ? Gcd(m, n % m) : n;
	}
	template <class T> T Lcm(T n, T m) {
		return n / Gcd(n, m) * m;
	}
	template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
		return accumulate(next(v.begin()), v.end(), U(*v.begin()), Gcd<U>);
	}
	template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
		return accumulate(next(v.begin()), v.end(), U(*v.begin()), Lcm<U>);
	}
	template <class T> T Pow(T a, T n) {
		T r = 1;
		while (n > 0) {
			if (n & 1) r *= a;
			a *= a;
			n /= 2;
		}
		return r;
	}
	template <class T> T Powmod(T a, T n, T m = MOD) {
		T r = 1;
		while (n > 0) {
			if (n & 1)
				r = r * a % m, n--;
			else
				a = a * a % m, n /= 2;
		}
		return r;
	}
}  // namespace

// --- dump --- //
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#else
#define dump(...) ((void)0)
#endif

// ---------------------------------------------------------------- //

#line 2 "a.cpp"

ll ask(int a, int b) {
	out('?', a + 1, b + 1).flush();
	ll answer = in;
	if (answer == -1) exit(1);
	return answer;
}

int main() {
	int n = in, s = in--, t = in--;
	ll dist = ask(s, t);

	vector<pair<ll, int>> a;
	a.emplace_back(dist, t);
	VL dist_s(n, inf);
	dist_s[s] = 0;
	dist_s[t] = dist;
	rep(i, n) {
		if (s != i && t != i) {
			int d1 = ask(s, i), d2 = ask(i, t);
			if (d1 + d2 == dist) {
				a.emplace_back(d1, i);
				dist_s[i] = d1;
			}
		}
	}
	sort(all(a));
	dump(a, dist_s);

	VI ans{s};
	for (auto p : a) {
		ll d;
		int i;
		tie(d, i) = p;
		if (dist_s[i] - dist_s[ans.back()] == ask(ans.back(), i)) {
			ans.push_back(i);
		}
		dump(ans);
	}
	for (int& x : ans) x++;
	out('!', ans).flush();
}
accuracy: 1
time_ms: 30
memory_kb: 5212
final_rank: 15

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-3, PI = acos(-1);
//ここから編集
int dp[201010];
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(6);
    
    int N, s, t; cin >> N >> s >> t;

    auto ask = [&](int a, int b){
        cout << "? " << a << " " << b << endl;
        int x;
        cin >> x;
        return x;
    };

    vector<int> ds(N+1);
    vector<int> dt(N+1);
    for(int i=1; i<=N; i++){
        if(i == s || i == t) continue;
        ds[i] = ask(s, i);
        dt[i] = ask(t, i);
    }

    int dist = ask(s, t);
    ds[t] = dt[s] = dist;

    vector<pair<int, int>> vp;
    for(int i=1; i<=N; i++){
        if(ds[i] + dt[i] == dist) vp.push_back({ds[i], i}); 
    }
    sort(all(vp));

    int pos = s;
    vector<int> ans;
    ans.push_back(pos);
    for(int i=1; i<vp.size(); i++){
        int u = vp[i].second;
        int d = ask(pos, u);

        if(ds[pos] + dt[u] + d == dist){
            ans.push_back(u);
            pos = u;
        }
    }
    cout << "!";
    for(auto x: ans) cout << " " << x;
    cout << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4676
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
  int n, s, t;
  cin >> n >> s >> t;
  
  cout << "? " << s << " " << t << endl;
  int dist; // distance between s and t
  cin >> dist;
  
  vector<pair<int, int>> x; // distance from s, node
  for (int i = 1; i <= n; i++) {
    if (i == s || i == t) continue;
    int d1, d2;
    cout << "? " << s << " " << i << endl;
    cin >> d1;
    cout << "? " << i << " " << t << endl;
    cin >> d2;
    if (d1 + d2 == dist) {
      x.emplace_back(make_pair(d1, i));
    }
  }
  
  sort(x.begin(), x.end());
  
  vector<pair<int, int>> ans;
  ans.emplace_back(make_pair(0, s));
  for (int i = 0; i < x.size(); i++) {
    int dd;
    cout << "? " << ans.back().second << " " << x.at(i).second << endl;
    cin >> dd;
    if (ans.back().first + dd == x.at(i).first) {
      ans.emplace_back(x.at(i));
    }
  }
  ans.emplace_back(make_pair(dist, t));
  
  cout << "!";
  for (int i = 0; i < ans.size(); i++) cout << " " << ans.at(i).second;
  cout << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 5184
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
typedef long long int ll;

#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define endl "\n"
const double EPS = 1e-7;
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
const double PI = acos(-1);
const int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

//-------------------------------------

using P = pair<int, int>;

void ask(int u, int v) { cout << "? " << u << " " << v << endl; }

int main() {
    // cin.tie(0);
    // ios::sync_with_stdio(false);
    int n, s, t;
    cin >> n >> s >> t;
    vector<int> ds(n + 1), dt(n + 1);
    for(int i = 1; i <= n; i++) {
        if(s == i) {
            continue;
        }
        ask(s, i);
        cin >> ds[i];
    }
    for(int i = 1; i <= n; i++) {
        if(i == t) {
            continue;
        }
        ask(i, t);
        cin >> dt[i];
    }
    vector<P> kouho;
    for(int i = 1; i <= n; i++) {
        if(i == s || i == t) {
            continue;
        }
        if(ds[i] + dt[i] == ds[t]) {
            kouho.emplace_back(P(ds[i], i));
        }
    }
    sort(ALL(kouho));
    vector<int> ans;
    if(kouho.size()) {
        ans.emplace_back(kouho[0].second);
    }
    for(int i = 1; i < kouho.size(); i++) {
        ask(ans.back(), kouho[i].second);
        int tmp;
        cin >> tmp;
        if(ds[ans.back()] + tmp == ds[kouho[i].second]) {
            ans.emplace_back(kouho[i].second);
        }
    }
    cout << "! " << s << " ";
    for(int i = 0; i < ans.size(); i++) {
        cout << ans[i] << " ";
    }
    cout << t << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 4672
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace::std;
using ll =long long;
#define int ll
#define rep(i,a,n) for(ll i=a;i<n;i++)
#define INF 1000000099
template<class T> using V=vector<T>;

vector<int> finddivisor(int x){
  vector<int> d;
  for(int i=1;i*i<=x;i++){
    if(x%i==0){
      d.push_back(i);
      if(i*i!=x)d.push_back(x/i);
    }
  }
  return d;
}

int quest(int x,int y){
  cout<<'?'<<' '<<x<<' '<<y<<endl;

  int res;cin>>res;
  if(res==-1)exit(0);
  return res;

}

V<ll> dfrs,dfrt;

signed main(){
  //cin.tie(0);
  //ios::sync_with_stdio(false);
  int n,s,t;cin>>n>>s>>t;
  int sps=quest(s,t);

  dfrs.assign(n+1,INF);
  dfrt.assign(n+1,INF);
  dfrs[s]=0;
  dfrt[t]=0;


  V<int> ans(1,s);
struct comp{
  bool operator ()(int  x,int y){
    return dfrs[x]>dfrs[y];
  }  
};

  priority_queue<int,vector<int>,decltype(comp())> q;

  rep(i,1,n+1){
    if(i==s || i==t)continue;

    dfrs[i]=quest(s,i);
    dfrt[i]=quest(i,t);
    if(dfrs[i]+dfrt[i]==sps){
      q.push(i);
    }
  }
  q.push(t);

  int now=q.top();q.pop();
  ans.push_back(now);

  while(q.size()){
    int nex=q.top(),dis;
    if(nex==t)dis=dfrt[now];
    else dis=quest(now,nex);

    q.pop();

    if(dfrs[now]+dis+dfrt[nex]==sps){
      ans.push_back(nex);
      now=nex;
    }
    if(now==t)break;
  }

  cout<<'!'<<' ';
  rep(i,0,(int)(ans.size()-1)){
    cout<<ans[i]<<' ';
  }
  cout<<ans.back()<<endl;
}
accuracy: 1
time_ms: 30
memory_kb: 4672
final_rank: 10

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<functional>

using namespace std;

typedef long long ll;

ll N;
int s, t;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

ll ask(int a, int b) {
	cout << "? " << a << " " << b << endl;
	cout.flush();
	ll ret;
	cin >> ret;
	return ret;
}

int main() {
	cin >> N >> s >> t;
	
	ll shortestpass = ask(s, t);
	
	for (int i = 1; i <= N; i++) {
		if (i == s || i == t) continue;
		ll tmp1 = ask(s, i), tmp2 = ask(i, t);
		if (tmp1 + tmp2 == shortestpass) {
			pq.push(make_pair(tmp1, i));
		}
	}

	vector<int> ans;
	ans.push_back(s);
	ll nowdis = 0;
	while (pq.size()) {
		auto now = pq.top(); pq.pop();
		ll tmp = ask(ans.back(), now.second);
		if (nowdis + tmp == now.first) {
			ans.push_back(now.second);
			nowdis += tmp;
		}
	}
	cout << "! ";
	for (int i = 0; i < ans.size(); i++) {
		cout << ans[i];
		cout << " ";
	}
	cout << t << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4668
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace::std;
using ll =long long;
#define int ll
#define rep(i,a,n) for(ll i=a;i<n;i++)
#define INF 1000000099
template<class T> using V=vector<T>;

vector<int> finddivisor(int x){
  vector<int> d;
  for(int i=1;i*i<=x;i++){
    if(x%i==0){
      d.push_back(i);
      if(i*i!=x)d.push_back(x/i);
    }
  }
  return d;
}

int quest(int x,int y){
  cout<<'?'<<' '<<x<<' '<<y<<'\n';
  cout.flush();

  int res;cin>>res;
  if(res==-1)exit(0);
  return res;

}

V<ll> dfrs,dfrt;

signed main(){
  //cin.tie(0);
  //ios::sync_with_stdio(false);
  int n,s,t;cin>>n>>s>>t;
  int sps=quest(s,t);

  dfrs.assign(n+1,INF);
  dfrt.assign(n+1,INF);
  dfrs[s]=0;
  dfrt[t]=0;


  V<int> ans(1,s);
struct comp{
  bool operator ()(int  x,int y){
    return dfrs[x]>dfrs[y];
  }  
};

  priority_queue<int,vector<int>,decltype(comp())> q;

  rep(i,1,n+1){
    if(i==s || i==t)continue;

    dfrs[i]=quest(s,i);
    dfrt[i]=quest(i,t);
    if(dfrs[i]+dfrt[i]==sps){
      q.push(i);
    }
  }
  q.push(t);

  int now=q.top();q.pop();
  ans.push_back(now);

  while(q.size()){
    int nex=q.top(),dis;
    if(nex==t)dis=dfrt[now];
    else dis=quest(now,nex);

    q.pop();

    if(dfrs[now]+dis+dfrt[nex]==sps){
      ans.push_back(nex);
      now=nex;
    }
    if(now==t)break;
  }

  cout<<'!'<<' ';
  rep(i,0,(int)(ans.size()-1)){
    cout<<ans[i]<<' ';
  }
  cout<<ans.back()<<'\n';
  cout.flush();
}
accuracy: 1
time_ms: 40
memory_kb: 4668
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using vec=vector<ll>;
#define For(i,a,b) for(i=a;i<(ll)b;i++)
#define rep(i,N) for(i=0;i<(ll)N;i++)
#define rep1(i,N) For(i,1,N)
#define print(a) cout<<a<<endl
#define pb push_back
#define output(v) do{bool f=0;for(auto outi:v){cout<<(f?" ":"")<<outi;f=1;}cout<<endl;}while(0);
#define all(v) (v).begin(),(v).end()
vec prime(ll N){
  ll i=2;
  vec res;
  while(i*i<=N){
    while(!(N%i)){
      res.pb(i);
      N/=i;
    }
    i++;
  }
  if(N!=1)res.pb(N);
  return res;
}
ll out(ll s,ll t){
  ll dist;
  cout<<"? "<<s<<" "<<t<<endl;
  cin>>dist;
  return dist;
}
struct gr{
  ll s,t,i;
};
int main(){
  ll i,j,N,s,t,dist;
  cin>>N>>s>>t;
  vec ans(1,s);
  dist=out(s,t);
  s--;t--;
  vector<gr> v(N),ev;
  rep(i,N){
    if(i==s){
      v[i]={0,dist,i};
    }else if(i==t){
      v[i]={dist,0,i};
    }else{
      v[i]={out(s+1,i+1),out(i+1,t+1),i};
    }
    if(v[i].s+v[i].t==dist)ev.pb(v[i]);
  }
  sort(all(ev),[](auto a,auto b){return a.s<b.s;});
  j=1;
  ans.pb(ev[1].i+1);
  dist-=ev[1].s;
  for(i=2;i<ev.size();i++){
    auto x=out(ev[i].i+1,ev[j].i+1);
    if(x+ev[i].t==dist){
      ans.pb(ev[i].i+1);
      j=i;
      dist-=x;
    }
  }
  cout<<"! ";
  output(ans);
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4668
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

long long n, s, t;
vector<vector<long long>> dist;

void solve();
long long query(long long x, long long y) {
  cout << "? " << x << " " << y << endl;
  long long i;
  cin >> i;
  return i;
}

int main() {
  cin >> n >> s >> t;
  dist.assign(n + 1, vector<long long>(n + 1, 0));
  solve();
  return 0;
}

void solve() {
  dist[s][t] = dist[t][s] = query(s, t);
  vector<long long> v, res;
  res.push_back(s);
  for(int i = 1; i <= n; ++i)
    if(i != s && i != t) {
      long long in1 = query(s, i), in2 = query(i, t);
      dist[s][i] = in1;
      dist[i][t] = in2;
      if(in1 + in2 == dist[s][t]) v.push_back(i);
    }
  auto f = [](long long &l, long long &r) {
    return dist[s][l] < dist[s][r];
  };
  int vsize = v.size();
  sort(v.begin(), v.end(), f);
  for(int i = 0; i < vsize; ++i) {
    long long now = query(res.back(), v[i]);
    dist[res.back()][v[i]] = now;
    if(dist[s][res.back()] + now == dist[s][v[i]])
      res.push_back(v[i]);
  }
  res.push_back(t);
  cout << "!";
  for(int i = 0; i < res.size(); ++i) cout << " " << res[i];
  cout << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 4672
final_rank: 19

code_snippet: #include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
#include <complex>
#include <numeric>
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long MAX = 5100000;
const long long INF = 1LL << 60;
const long long mod = 1000000007LL;
//const long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;



int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/
	ll N, s, t; scanf("%lld %lld %lld", &N, &s, &t);
	vector<ll> ds(N + 5), dt(N + 5);
	for (ll i = 1; i <= N; i++) {
		if (i == s) continue;
		cout << "? " << s << " " << i << endl;
		ll x; scanf("%lld", &x);
		ds[i] = x;
	}
	for (ll i = 1; i <= N; i++) {
		if (i == t) continue;
		cout << "? " << t << " " << i << endl;
		ll x; scanf("%lld", &x);
		dt[i] = x;
	}
	vector<pair<ll, ll>> v;
	for (ll i = 1; i <= N; i++) {
		if (i == s || i == t) continue;
		if (ds[i] + dt[i] == ds[t]) {
			v.emplace_back(ds[i], i);
		}
	}
	sort(v.begin(), v.end());
	vector<ll> res;
	if(v.size() > 0 ) res.push_back(v[0].second);
	for (ll i = 1; i < v.size(); i++) {
		cout << "? " << res.back() << " " << v[i].second << endl;
		ll x; scanf("%lld", &x);
		if (ds[res.back()] + x == ds[v[i].second]) {
			res.push_back(v[i].second);
		}
	}
	cout << "! " << s;
	for (ll i = 0; i < res.size(); i++) {
		cout << " " << res[i];
	}
	cout << " " << t << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4672
final_rank: 10

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>

#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 310

int memo[SIZE][SIZE];

int query(int a, int b) {
  if (a == b) return 0;
  if (memo[a][b]) return memo[a][b];

  int d;
  cout << "? " << a << " " << b << endl;
  cout.flush();

  cin >> d;
  return memo[a][b] = memo[b][a] = d;
}

int main(){
  int N, s, t;
  int ds[SIZE], dt[SIZE];

  cin >> N >> s >> t;

  int D = query(s, t);

  for (int i=1; i<=N; i++) {
    ds[i] = query(s, i);
    dt[i] = query(t, i);
  }

  vector<pair<int,int>> vec;

  for (int i=1; i<=N; i++) {
    if (ds[i] + dt[i] == D) {
      vec.push_back({ds[i], i});
    }
  }

  sort(vec.begin(), vec.end());

  vector<int> ans = {};
  int now = s;

  for (auto p : vec) {
    int to = p.second;

    if (query(now, to) == ds[to] - ds[now]) {
      now = to;
      ans.push_back(now);
    }
  }

  cout << "!";

  for (auto p : ans) {
    cout << " " << p;
  }
  cout << endl;

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4664
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
signed main(){
  Int n,s,t;
  cin>>n>>s>>t;

  auto ask=
    [&](Int a,Int b){
      cout<<"? "<<a<<" "<<b<<endl;
      Int x;
      cin>>x;
      return x;
    };

  vector<Int> ds(n+1,0);
  vector<Int> dt(n+1,0);

  for(Int i=1;i<=n;i++){
    if(i==s||i==t) continue;
    ds[i]=ask(s,i);
    dt[i]=ask(t,i);
  }

  Int dist=ask(s,t);
  ds[t]=dt[s]=dist;

  using P = pair<Int, Int>;
  vector<P> vp;
  for(Int i=1;i<=n;i++){
    if(i==s||i==t) continue;
    if(ds[i]+dt[i]>dist) continue;
    vp.emplace_back(ds[i],i);
  }

  if(vp.empty()){
    cout<<"! "<<s<<" "<<t<<endl;
    return 0;
  }

  vp.emplace_back(ds[t],t);
  sort(vp.begin(),vp.end());

  Int pos=s;
  vector<Int> ans;
  ans.emplace_back(pos);

  Int i=0;
  while(pos!=t){
    while(1){
      //cerr<<":::"<<i<<" "<<vp.size()<<endl;
      Int k=vp[i].second;
      i++;
      if(ask(pos,k)+dt[k]==dt[pos]){
        pos=k;
        break;
      }
    }
    ans.emplace_back(pos);
  }

  cout<<"!";
  for(Int x:ans) cout<<" "<<x;
  cout<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4648
final_rank: 1

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 2964.cc: Restore Shortest Path
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
#include<unistd.h>
 
using namespace std;

/* constant */

const int MAX_N = 300;
const int INF = 1 << 29;

/* typedef */

typedef pair<int,int> pii;

/* global variables */

int ds[MAX_N][MAX_N], xs[MAX_N];
pii ps[MAX_N];

/* subroutines */

int getdist(int i, int j) {
  if (ds[i][j] > 0) return ds[i][j];

  printf("? %d %d\n", i + 1, j + 1); fflush(stdout);

  int d;
  scanf("%d", &d);
  if (d < 0) exit(0);
  ds[i][j] = ds[j][i] = d;
  return d;
}

/* main */

int main() {
  int n, st, gl;
  scanf("%d%d%d", &n, &st, &gl);
  st--, gl--;

  //for (int i = 0; i < n; i++) fill(ds[i], ds[i] + n, INF);
  int gd = getdist(st, gl);

  ps[0] = pii(0, st), ps[1] = pii(gd, gl);
  int m = 2;

  for (int i = 0; i < n; i++)
    if (i != st && i != gl) {
      int d0 = getdist(st, i), d1 = getdist(i, gl);
      if (d0 + d1 == gd) ps[m++] = pii(d0, i);
    }
  sort(ps, ps + m);

  xs[0] = st;
  int pd = 0, px = st, k = 1;

  for (int i = 1; i < m; i++) {
    int di = ps[i].first, xi = ps[i].second;
    int dd = getdist(px, xi);
    if (pd + dd == di) {
      xs[k++] = xi;
      pd = di;
      px = xi;
    }
  }

  putchar('!');
  for (int i = 0; i < k; i++) printf(" %d", xs[i] + 1);
  putchar('\n'); fflush(stdout);

  //sleep(1);
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4664
final_rank: 6

code_snippet: #include<algorithm>
#include<cassert>
#include<climits>
#include<cmath>
#include<cstring>
#include<deque>
#include<functional>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

using lint = long long;
using P = pair<int, int>;
using LLP = pair<long long, long long>;

#define REP(i, x, n) for(int i = (x), i##_len = int(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = int(n) ; i < i##_len ; ++i)
#define reps(i, n) for(int i = 1, i##_len = int(n) ; i <= i##_len ; ++i)
#define rrep(i, n) for(int i = int(n) - 1 ; i >= 0 ; --i)
#define rreps(i, n) for(int i = int(n) ; i > 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())
#define TWINS(x) cout << ((x) ? "Yay!" : ":(") << endl

constexpr int IINF = (1 << 30) - 1;
constexpr long long LLINF = 1LL << 61;
constexpr double EPS = 1e-8;

const int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};

template<typename T>
bool chmax(T& a, T b, bool equal = false){
    if(a < b || equal && a == b){
        a = b;
        return true;
    }
    return false;
}

template<typename T>
bool chmin(T& a, T b, bool equal = false){
    if(b < a || equal && a == b){
        a = b;
        return true;
    }
    return false;
}

int query(int u, int v){
    cout << "? " << u << " " << v << endl;
    int res;
    cin >> res;
    return res;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, s, t;
    cin >> n >> s >> t;

    int cost = query(s, t);

    vector<int> a(n + 1, 0), b(n + 1, 0);
    a[t] = cost;
    b[s] = cost;
    map< int, vector<int> > mp;
    reps(i, n){
        if(i == s || i == t){
            continue;
        }
        a[i] = query(s, i);
        b[i] = query(i, t);
        if(a[i] + b[i] == cost){
            mp[a[i]].emplace_back(i);
        }
    }
    mp[cost].emplace_back(t);

    vector<int> ans = {s};
    for(auto it = mp.begin() ; it != mp.end() ; ++it){
        for(auto x : (*it).second){
            int q = query(ans.back(), x);
            if(q == a[x] - a[ans.back()]){
                ans.emplace_back(x);
                break;
            }
        }
    }

    cout << '!';
    rep(i, ans.size()){
        cout << ' ' << ans[i];
    }
    cout << endl;

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4652
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define F first
#define S second
#define all(v) v.begin(),v.end()
#define PB push_back
#define P pair<int,int>



signed main(){
  int d[400][400];
  rep(i,400){
    rep(j,400){
      if(i==j) continue;
      d[i][j]=INT_MAX;
    }
  }

  int n,s,t;
  cin>>n>>s>>t;
  s--;t--;

  rep(i,n){
    if(i==s) continue;
    cout<<"? "<<s+1<<' '<<i+1<<endl;
    cout.flush();
    int c;
    cin>>c;
    d[s][i]=c;
    d[i][s]=c;
  }

  rep(i,n){
    if(i==s||i==t) continue;
    cout<<"? "<<i+1<<' '<<t+1<<endl;
    cout.flush();
    int c;
    cin>>c;
    d[t][i]=c;
    d[i][t]=c;
  }

  vector<P> v;
  rep(i,n){
    if(i==s||i==t) continue;
    if(d[s][i]+d[i][t]==d[s][t]){
      v.PB(P(d[s][i],i));
    }
  }
  sort(all(v));

  vector<int> ans;
  ans.PB(s);
  if(v.size())
    ans.PB(v[0].S);

  int j=0;
  for(int i=1;i<(int)v.size();i++){
    cout<<"? "<<v[j].S+1<<' '<<v[i].S+1<<endl;
    cout.flush();
    int c;
    cin>>c;
    //cout<<v[0].F<<' '<<' '<<c<<' '<<d[v[i].S][t]<<endl;
    if(v[j].F+c+d[v[i].S][t]==d[s][t]){
      ans.PB(v[i].S);
      j=i;
    }
  }

  ans.PB(t);

  cout<<"!";
  rep(i,ans.size()){
    cout<<" "<<ans[i]+1;
  }
  cout<<endl;

}
accuracy: 1
time_ms: 30
memory_kb: 4648
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)n;i++)
#define F first
#define S second
#define all(v) v.begin(),v.end()
#define PB push_back
#define P pair<int,int>



signed main(){
  int d[400][400];
  rep(i,400){
    rep(j,400){
      if(i==j) continue;
      d[i][j]=INT_MAX;
    }
  }

  int n,s,t;
  cin>>n>>s>>t;
  s--;t--;

  rep(i,n){
    if(i==s) continue;
    cout<<"? "<<s+1<<' '<<i+1<<endl;
    cout.flush();
    int c;
    cin>>c;
    d[s][i]=c;
    d[i][s]=c;
  }

  rep(i,n){
    if(i==s||i==t) continue;
    cout<<"? "<<i+1<<' '<<t+1<<endl;
    cout.flush();
    int c;
    cin>>c;
    d[t][i]=c;
    d[i][t]=c;
  }

  vector<P> v;
  rep(i,n){
    if(i==s||i==t) continue;
    if(d[s][i]+d[i][t]==d[s][t]){
      v.PB(P(d[s][i],i));
    }
  }
  sort(all(v));

  vector<int> ans;
  ans.PB(s);
  if(v.size())
    ans.PB(v[0].S);

  for(int i=1;i<(int)v.size();i++){
    cout<<"? "<<v[0].S+1<<' '<<v[i].S+1<<endl;
    cout.flush();
    int c;
    cin>>c;
    //cout<<v[0].F<<' '<<' '<<c<<' '<<d[v[i].S][t]<<endl;
    if(v[0].F+c+d[v[i].S][t]==d[s][t])
      ans.PB(v[i].S);
  }

  ans.PB(t);

  cout<<"!";
  rep(i,ans.size()){
    cout<<" "<<ans[i]+1;
  }
  cout<<endl;

}
accuracy: 1
time_ms: 40
memory_kb: 4652
final_rank: 16

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 305

struct Info{
	Info(int arg_node_id,int arg_min_dist_from_S){
		node_id = arg_node_id;
		min_dist_from_S = arg_min_dist_from_S;
	}
	bool operator<(const struct Info &arg) const{

		return min_dist_from_S < arg.min_dist_from_S;
	}
	int node_id,min_dist_from_S;
};

int V;
int S,T;
int min_dist;
int min_dist_from_S[SIZE],min_dist_from_T[SIZE];

int main(){

	scanf("%d %d %d",&V,&S,&T);

	printf("? %d %d\n",S,T);
	cout.flush();
	scanf("%d",&min_dist);

	for(int i = 1; i <= V; i++){

		if(i == S || i == T)continue;
		printf("? %d %d\n",S,i);
		cout.flush();
		scanf("%d",&min_dist_from_S[i]);
	}

	for(int i = 1; i <= V; i++){

		if(i == S || i == T)continue;
		printf("? %d %d\n",T,i);
		cout.flush();
		scanf("%d",&min_dist_from_T[i]);
	}

	vector<Info> info;

	for(int i = 1; i <= V; i++){

		if(i == S || i == T)continue;

		if(min_dist_from_S[i]+min_dist_from_T[i] == min_dist){

			info.push_back(Info(i,min_dist_from_S[i]));
		}
	}
	sort(info.begin(),info.end());

	printf("! %d",S);

	for(int i = 0; i < info.size(); i++){

		printf(" %d",info[i].node_id);
	}

	printf(" %d\n",T);
	cout.flush();

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4664
final_rank: 17

code_snippet: /* Aa^~ kokoro ga pyonpyon suru n jaa^~
// ZZZXXkXkkkZ!``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ``` ```?Wfpppbpbbpbbpbbbkbkk
// ppbbbpbbpVr`` `` ` ` ` ` ```` `` ` ` ``  ` ` ` ` ` ` ` ` `  dppbbkkkkkkkkkkqkqkk
// HkqqqqqkkWr`` ` ` ``` ``` `?G, ` ` ``.JC!```` ` ` `` `` ````(Wpbkkkkkkkkqkkkkkqk
// mmmmmqqqqpr` `` `` ```````.+zT=`` `` 7TO-.```````` `` `` ```(yppbkkkkkkkkkkkkkkk
// ggmgmmqqqH$ ``````````....````` `  ````````.`````` `` ``````.yfpppbbbbkkkkqqqqqH
// gmmmmmqqqkW<```` `````...`````  .,.`  ````....````` ``````` (Wbqqmgmmgmggggggggg
// qmmmqqqqkkWk.``````````````````` ;:<`` `````.`````````````-_<-?WHHqmmmmmmgmmgggg
// @@@@@@@gggHH6- ``````````````` `` _ `` ```````````````` ._~~_.`-?Wkqmmmmmmmggg@g
// @@@@g@gggHY~.-<_- `````````````````````````````````` ._~~(<-``.`.(WHqqqmmggggmmm
// @@g@gggHH=.`..._<-___..```````````````````````. .-_~~~_(!``-.``.`` OHHWUWHmqHWXW
// gggggmqK1.``..~.. _<<+-(____..  ````````  ..__~~_((<<!.`.``` .``.`` j0C1XUHmHIdW
// ggmmqH0!,_``.>`````` _<<;<v<<<++((((((((((<<<<<<~_. (-.``~``.>..```  jOuWHHqHIdH
// gmmqkW!`(_ J>`    `` ` _~<`_~~~~<<<<<<<~~__````````` ?1. ._`(__```    zXWHg@HkXH
// gHHWS{``(lJ<!``.``.```(:+>`._`````.` <..`` - ``. `   _ ?&._.I`_`````` .XyVfppppW
// HHHSv``.(X:_..... _..(;+<!.(<..-.....-.-_..+_`..<.`.`..`_IJd}  .`..````jqg@@@@@@
// XHWZ{..<Jk~!.`.. (<.-(+>(_.(1.(_..`.`.`.<_.+<_..<<-..._..-zy>.`_`...```.WH@HHHHH
// bkWt~.-jCz(_..`.(+<.(;< ._-<=_(<_..-....(_.<1<..(<<.`._..-JUS-._.`...```dHmH9VUH
// WUUO..(f.(c...__+z<-(+~` _-+<_(><..__.`.(<._.z_.(1;_..__.(C(zT-(..`...``(WHR<+Xk
// kkkk._(_.->..._(z;:_><.._>_+_<(1>_._<...(v<<.(<.(+z<..-_(Z~_<_j+_..`...`(WHKz1ZW
// @@gR._+_..~..-<+z<<?<>```_.<_.(+1><_;_..(1_:`.<<??1z--(+Z!..<_.j<....`..(bgHAAQX
// @@mR.(j:..~.._<z!`.(>~``` ~(_.(+<1><><_.(((_`.<__`.<_.(X>...<_.(<.....`.JUWWWyWW
// @gmH_(zl..(.._+>```<+_````.~>``(+.<?>>_._(<```(<<``(__<>....<.._<.......dXkkkHHH
// mmqHl(dk_.(_.-=~`.`.1-..._~-1.``_:`(??<_~(`.--.&_.`.<(;<...._.._<..`..._Xg@@@@@@
// qHkpk(dX<.(;..j_```.(((JJ&a&-~``````.1<_```-(((e+.-(/`(>...._..(<......(Wmggg@@g
// HVHbWcz><__+_.(_.(dWWHHH@HHc~````````.+~`` (jHMMMHHHm&.?..._<..(<_..._.(WqqHHmHg
// 0>vWWkzZwl~<o.__`__~X@@HM@Hb ```.`.``. ```` d@@HHH@@K?76...(<..(<_...(_(ppWWWWHq
// X0XWHKXXw$<(z<.( `` WHHMHHHH_``````````````.WHHMNMHHH_`(...(<_.(z_..._<(fWVC174W
// XuXWHHWWz>__+z+.!`..??CZYCOX_`````````````.`~.OvTUZUS_`~.._+?_.(_~_.._zjO=1+~+jy
// kkkkkkkkX:._<z=1(_`` << ``->``.``.``.``.```` ?<`` (v!`._..(??_.(1._.._=dUOOzzzwX
// @@@@@@@@H<...1O=v<_...__ -_````````````````.`` `` ~.`` :.~+=?~.(;_(...jdQQQQQkkk
// H@@@@@@@H~...(==>.~~~~~....`.`````````.`````.`........->.(===~~<<.(...(dg@@@@@@@
// @@@H@@HHH_.__(=l>~.~~~~~....``.``.``.```..`......~~~~~(<_+=l=~_<.->..~_dqggggg@g
// @H@@@@MHH_._<(=l>...........```````````````.`...~~~~~~+<(=lz=~((j=z_..~jWqmmgggm
// @@H@@HHWH_._<(lll-.......```.````.``.`..`````........_z<+llZz~(lOO=<...(VYUUUW9Y
// @@HMMHWZf>~_=:=llw+.`````````.`.```__~~_``.`````.....(z+llOOz_zllOlz~..~<<1+dW>_
// MMM#MHHWXl~_=>1ltwOl&.`.``.`````.``````````````.````.(llttwtz(OltwOz<..__zwOwwOz
// HM#HMHUUI<._1z+ttOZttlt&....``.``.`.````.``...``...(zZtttOktzjttttwlz_._<(Xkkkkk
// HHHmHSZu:(_~+OztttXtttOZZttO+-..............-(+ztOttwttttd0tOZttttwOl<~.(_dMMHHH
// rvuuXuuI~~<~(uttttwvOwwwkQQHMMHHHHHHHHHMMMNmgey?OwwwrtttwXOtwttttttXtO-~.((wZyyy
// HHHHHHK>(~(-(dOrtrrl(QgMHMMMHHHHHHHHHHHHHHHH##HMNkX0rrrrXXrd%`` (Ctwwtz_~.<(Wg@H
// NNNNNHD(~(zo~zXrrrQdHHMMNMHHHHHHHHHHHHHHHHHHHHHH##HNmyrdKkwZ ` _``-zwrt1~~_<(MNM
// MMMMM#<<_jwr:(Z4QHHMMHMHHHHHHHHHHHHHHHHHHHHHHHHHHHH###NHSXZ>` ~````.OXtt>~._<?MM
*/

#include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define MT make_tuple
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second

template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class T>
istream& operator>>(istream& is, vector<T>& xs){
  for(auto& x: xs)
	is >> x;
  return is;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
ostream& operator<<(ostream& os, const vector<T>& xs){
  for(unsigned int i=0;i<xs.size();++i)
	os << (i?" ":"") << xs[i];
  return os;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}
void debug(istringstream&){}
template <char sep=',', class Head, class... Tail>
void debug(istringstream& iss, Head&& head, Tail&&... tail)
{
  string name;
  getline(iss, name, ',');
  cout << sep << name << "=" << head;
  debug(iss, forward<Tail>(tail)...);
}

#ifdef PYONPOI
#define DEBUG(...) \
  do{ \
    istringstream ss(#__VA_ARGS__); \
    debug<' '>(ss, __VA_ARGS__); \
    cout<<endl; \
  }while(0)
#else
#define DEBUG
#endif


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

int query(int u, int v){
  cout << "? " << u << " " << v << endl;
  int d;
  cin >> d;
  return d;
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, S, T;
  cin >> N >> S >> T;

  int D = query(S, T);
  map<int,int> dist;
  dist[0] = S;
  dist[D] = T;

  FOR(i,1,N+1){
    if(i == S || i == T) continue;
    int d1 = query(S, i);
    auto it = dist.upper_bound(d1);
    if(it == end(dist)) continue;

    int d2 = query(i, it->SS);
    if(d1 + d2 == it->FF){
      dist[d1] = i;
    }
  }

  cout << "!";
  for(auto p : dist){
    cout << " " << p.SS;
  }
  cout << endl;

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4660
final_rank: 5

code_snippet: #include<algorithm>
#include<climits>
#include<cmath>
#include<cstring>
#include<deque>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

using lint = long long;
using P = pair<int, int>;
using LLP = pair<long long, long long>;

#define REP(i, x, n) for(int i = (x), i##_len = int(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = int(n) ; i < i##_len ; ++i)
#define reps(i, n) for(int i = 1, i##_len = int(n) ; i <= i##_len ; ++i)
#define rrep(i, n) for(int i = int(n) - 1 ; i >= 0 ; --i)
#define rreps(i, n) for(int i = int(n) ; i > 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())
#define TWINS(x) cout << ((x) ? "Yay!" : ":(") << endl

const int IINF = (1 << 30) - 1;
const long long LLINF = 1LL << 61;
const int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};
const double EPS = 1e-8;

template<typename T>
bool chmax(T &a, T b){
    if(a < b){
        a = b;
        return true;
    }
    return false;
}

template<typename T>
bool chmin(T &a, T b){
    if(b < a){
        a = b;
        return true;
    }
    return false;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, s, t;
    cin >> n >> s >> t;

    cout << "? " << s << " " << t << endl;
    int c;
    cin >> c;

    vector< pair<P, int> > v;
    reps(i, n){
        if(i == s || i == t){
            continue;
        }
        int a, b;
        cout << "? " << s << " " << i << endl;
        cin >> a;
        cout << "? " << i << " " << t << endl;
        cin >> b;
        if(a + b == c){
            v.push_back({{a, b}, i});
        }
    }
    SORT(v);

    vector< P > ans;
    ans.emplace_back(s, 0);
    rep(i, v.size()){
        int a;
        cout << "? " << ans.back().first << " " << v[i].second << endl;
        cin >> a;
        if(ans.back().second + a + v[i].first.second == c){
            ans.emplace_back(v[i].second, v[i].first.first);
        }
    }
    ans.emplace_back(t, c);

    cout << "!";
    rep(i, ans.size()){
        cout << " " << ans[i].first;
    }
    cout << endl;

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4656
final_rank: 4