#include // #include // using namespace atcoder; #ifdef LOCAL #include #define dbg(...) debug::dbg(#__VA_ARGS__, __VA_ARGS__) #else #define dbg(...) void(0) #endif using namespace std; // #define int long long #define rep(i, a, b) for(int i=static_cast(a), i##_end__=static_cast(b); i < i##_end__; i++) #define rep_r(i, a, b) for(int i=static_cast(a), i##_end__=static_cast(b); i >= i##_end__; i--) #define fore(i, a) for(auto& i: a) #define all(x) std::begin(x), std::end(x) using ll = long long; // __int128; using ull = unsigned long long; template int siz(const C& c) { return static_cast(c.size()); } template constexpr int siz(const T (&)[N]) { return static_cast(N); } template inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } template constexpr T pow2(T x){ return x * x; } template constexpr T divceil(T x, S div) { return (x % div == 0) ? x / div : (x >= 0) ? (x / div) + 1 : -((-x) / div); } template constexpr T divfloor(T x, S div){ return (x % div == 0) ? x / div : (x >= 0) ? (x / div) : -((-x) / div) - 1; } constexpr long long INF = 1LL << 60; // 1.15e18 constexpr int MOD = (int)1e9 + 7; // 整数の三分探索を二分探索で実現 // 凸型関数で結果が最大となるIndexを探索。同じ値が複数ある場合は、一番左のIndexを返す // f(x) > f(x-1) となる最大のxを探索 // ※てっぺんの右側と左側の両方に平らな部分があるとうまく行かないことに注意 template T find_maximal(T l, T r, F f) { while(r - l > 1){ auto m = (l + r) / 2; (f(m) > f(m - 1) ? l : r) = m; } return l; } void _main() { int x = 0, y = 0, z = 0; int cord = 0; auto func = [&](int v){ int x2 = cord == 0 ? v : x, y2 = cord == 1 ? v : y, z2 = cord == 2 ? v : z; cout << "? " << x2 << " " << y2 << " " << z2 << endl; int D; cin >> D; return D; }; cord = 0; x = find_maximal(-100, 100, func); cord = 1; y = find_maximal(-100, 100, func); cord = 2; z = find_maximal(-100, 100, func); cout << "! " << x << " " << y << " " << z << endl; } signed main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); cerr << fixed << setprecision(15); _main(); }