#include #if __has_include() #include std::ostream &operator<<(std::ostream &os, const atcoder::modint998244353 &v) { os << v.val(); return os; } std::istream &operator>>(std::istream &is, atcoder::modint998244353 &v) { long long x; is >> x; v = x; return is; } std::ostream &operator<<(std::ostream &os, const atcoder::modint1000000007 &v) { os << v.val(); return os; } std::istream &operator>>(std::istream &is, atcoder::modint1000000007 &v) { long long x; is >> x; v = x; return is; } #endif using namespace std; using ll = long long; using pll = pair; #define el '\n'; #define rep(i, s, t) for (ll i = s; i < (ll)(t); i++) #define rrep(i, s, t) for (ll i = (ll)(t) - 1; i >= (ll)(s); i--) #define all(x) begin(x), end(x) #define eb emplace_back #define pb push_back #define TT template TT using vec = vector; TT using vvec = vec>; TT using vvvec = vec>; TT using minheap = priority_queue, greater>; TT using maxheap = priority_queue; TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; } TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; } TT bool rng(T l, T x, T r) { return l <= x && x < r; } TT T flr(T a, T b) { if (b < 0) a = -a, b = -b; return a >= 0 ? a / b : (a + 1) / b - 1; } TT T cil(T a, T b) { if (b < 0) a = -a, b = -b; return a > 0 ? (a - 1) / b + 1 : a / b; } TT T sqr(T x) { return x * x; } struct io_setup { io_setup() { ios::sync_with_stdio(false); std::cin.tie(nullptr); cout << fixed << setprecision(15); } } io_setup; template ostream &operator<<(ostream &os, const pair &p) { os << p.first << " " << p.second; return os; } TT ostream &operator<<(ostream &os, const vec &v) { for (size_t i = 0; i < v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template ostream &operator<<(ostream &os, const array &v) { for (size_t i = 0; i < n; i++) { os << v[i] << (i + 1 != n ? " " : ""); } return os; } template ostream &operator<<(ostream &os, const vvec &v) { for (size_t i = 0; i < v.size(); i++) { os << v[i] << (i + 1 != v.size() ? "\n" : ""); } return os; } TT istream &operator>>(istream &is, vec &v) { for (size_t i = 0; i < v.size(); i++) { is >> v[i]; } return is; } #if __has_include() #include #else #define dbg(...) true #define DBG(...) true #define OUT(...) true #endif template struct combination { vector fac, ifac, inv; long long N; combination() { fac.resize(2, 1); ifac.resize(2, 1); inv.resize(2, 1); N = 1; } void reserve(long long n) { expand(n); } T operator()(int n, int k) { return C(n, k); } T C(int n, int k) { if (n < k) return 0; if (n < 0 || k < 0) return 0; if (N < n) expand(n); return fac[n] * ifac[n - k] % mod * ifac[k] % mod; } T P(int n, int k) { if (n < k) return 0; if (n < 0 || k < 0) return 0; if (N < n) expand(n); return fac[n] * ifac[n - k] % mod; } T B(int n) { if (N < n) expand(n); return (n < 0 ? 0 : fac[n]); } T invB(int n) { if (N < n) expand(n); return (n < 0 ? 0 : ifac[n]); } T H(int n, int k) { return C(n + k - 1, k); } T Cn(int n) { return C(2 * n, n) * inv[n + 1] % mod; } private: constexpr static bool is_prime_constexpr(long long x) { if (x <= 1) return false; for (long long i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; } static_assert(is_prime_constexpr(mod), "mod must be prime"); long long extgcd(long long a, long long b, long long &x, long long &y) { if (b == 0) { x = 1; y = 0; return a; } auto d = extgcd(b, a % b, y, x); y -= a / b * x; return d; } long long modinv(long long a) { long long x, y; extgcd(a, mod, x, y); x %= mod; if (x < 0) x += mod; return x; } void expand(long long new_max_n) { if (new_max_n <= N) return; long long nx = N; // 2冪で大きくしていく。 while (nx < new_max_n) nx <<= 1; new_max_n = nx; long long pre = N; N = new_max_n; fac.resize(N + 1); ifac.resize(N + 1); inv.resize(N + 1); for (long long i = pre + 1; i <= N; i++) { fac[i] = fac[i - 1] * i % mod; } ifac[N] = modinv(fac[N]); inv[N] = ifac[N] * fac[N - 1] % mod; for (long long i = N - 1; i >= pre + 1; i--) { ifac[i] = ifac[i + 1] * (i + 1) % mod; inv[i] = ifac[i] * fac[i - 1] % mod; } return; } }; using combination998244353 = combination; using mint = atcoder::modint998244353; int main() { ll n, q; cin >> n >> q; vec B = {2, 4, 1, 3}; ll c = 0; auto cmp = [&](ll i, ll j) { assert(c != q); c++; dbg(B[i - 1], B[j - 1]); cout << "? " << i << " " << i << " " << j << " " << j << endl; int ret; cin >> ret; return ret == 1; }; vec A(n); iota(all(A), 1); auto ans = minmax_element(all(A), cmp); int i1 = *ans.first;// - A.begin(); int i2 = *ans.second;// - A.begin(); cout << "! " << i1 << " " << i1 << " " << i2 << " " << n << endl; } // 2 4 1 3