#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
#define owo(i,a, b) for(int i=(a);i<(b); ++i)
#define uwu(i,a, b) for(int i=(a)-1; i>=(b); --i)
#define senpai push_back
#define ttgl pair<int, int>
#define ayaya cout<<"ayaya~"<<endl
 
using namespace std;
using ll = long long;
using ld = long double;
ll MOD = 998244353;
const ll root = 3;
ll binpow(ll a,ll b){ll res=1;while(b){if(b&1)res=(res*a)%MOD;a=(a*a)%MOD;b>>=1;}return res;}
ll modInv(ll a){return binpow(a, MOD-2);}
const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const ll NINFLL = 0xc0c0c0c0c0c0c0c0;
const int mxN = 1001;
vector<ttgl> factor(int a) {
    vector<ttgl> res;
    for(int i = 2; i*i <= a; ++i) {
        if(a%i==0) {
            res.senpai({i, 1});
            a/=i;
            while(a%i==0) {
                res.back().second++;
                a/=i;
            }
        }
    }
    if(a > 1)res.senpai({a, 1});
    return res;
}
int cdiv(int a) {
    int res = 0;
    for(int i = 1; i <= a; ++i) {
        if(a%i==0)res++;
    }
    return res;
}
bool query(int h, int w, int x1, int y1, int x2, int y2) {
    cout<<"? "<<h<<" "<<w<<" "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
    bool res;
    cin>>res;
    return res;
}

int n, m;
int main() {
    //freopen("file.in", "r", stdin);
    //freopen("file.out", "w", stdout);
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    cin.tie(0)->sync_with_stdio(0);
    cin>>n>>m;
    vector<ttgl> nf = factor(n);
    vector<ttgl> mf = factor(m);
    ll cm = m;
    for(auto p: mf) {
        while(p.second) {
            p.second--;
            bool ok = 1;
            ll nxt = cm / p.first;
            int curr = 1;
            while(curr*2 <= p.first) {
                if(!ok)break;
                ok &= query(n, nxt*curr, 1, 1, 1, 1+nxt*curr);
                curr*=2;
            }
            int lft = p.first-curr;
            if(ok && lft) {
                ok &= query(n, nxt*lft, 1, 1, 1, cm-nxt*lft+1);
            }
            if(ok) {
                cm = nxt;
                continue;
            }
            break;
        }
    }
    ll cn = n;
    for(auto p: nf) {
        while(p.second) {
            p.second--;
            bool ok = 1;
            ll nxt = cn / p.first;
            int curr = 1;
            while(curr*2 <= p.first) {
                if(!ok)break;
                ok &= query(nxt*curr, m, 1, 1, 1+nxt*curr, 1);
                curr*=2;
            }
            int lft = p.first-curr;
            if(ok && lft) {
                ok &= query(nxt*lft, m, 1, 1, cn-nxt*lft+1, 1);
            }
            if(ok) {
                cn = nxt;
                continue;
            }
            break;
        }
    }
    cout<<"! "<<cdiv(n/cn)*cdiv(m/cm)<<endl;
    return 0;
}