//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

#define shandom_ruffle random_shuffle

using ll=long long;
const int nax=57;
const int dlu=10;
ll mod;

int n=50;

ll pot[nax][nax];

ll wyn;

int jeszkol[nax][nax];

void ff()
{
	fflush(stdout);
}

int pyt(int a, int b, int x, int y)
{
	printf("? %d %d %d %d\n", a, x, b, y);
	ff();
	int v;
	scanf("%d", &v);
	return v;
}

int los(int a, int b)
{
	return (rand()%(b-a+1))+a;
}

void szuk(int a, int b, int x, int y, int w)
{
	if (!w)
		return;
	if ((a/dlu)==(b/dlu) && !jeszkol[x][a/dlu])
	{
		szuk(a, b, x+1, y, w);
		return;
	}
	if ((a/dlu)==(b/dlu) && !jeszkol[y][a/dlu])
	{
		szuk(a, b, x, y-1, w);
		return;
	}
	if (a==b)
	{
		int ile=0;
		for (int i=x; i<=y; i++)
			ile+=(jeszkol[i][a/dlu]>0);
		if (ile==w)
		{
			for (int j=x; j<=y; j++)
			{
				if (jeszkol[j][a/dlu])
				{
					wyn+=pot[a][j];
					jeszkol[j][a/dlu]--;
				}
			}
			return;
		}
	}
	if (w==(b-a+1)*(y-x+1))
	{
		for (int i=a; i<=b; i++)
		{
			for (int j=x; j<=y; j++)
			{
				wyn+=pot[i][j];
				jeszkol[j][i/dlu]--;
			}
		}
		return;
	}
	//~ if (x==y || (a!=b && (rand()&1)))
	if (a!=b)
	{
		int s=(a+b)>>1;
		//~ int s=los(a, b-1);
		int p=pyt(a, s, x, y);
		if (rand()&1)
		{
			szuk(a, s, x, y, p);
			szuk(s+1, b, x, y, w-p);
		}
		else
		{
			szuk(s+1, b, x, y, w-p);
			szuk(a, s, x, y, p);
		}
	}
	else
	{
		int s=(x+y)>>1;
		//~ int s=los(x, y-1);
		int p=pyt(a, b, x, s);
		if (rand()&1)
		{
			szuk(a, b, x, s, p);
			szuk(a, b, s+1, y, w-p);
		}
		else
		{
			szuk(a, b, s+1, y, w-p);
			szuk(a, b, x, s, p);
		}
	}
}

int main()
{
	int szit;
	scanf("%d%d%d%lld", &szit, &szit, &szit, &mod);
	ll trz=1;
	for (int i=0; i<n; i++)
	{
		for (int j=0; j<n; j++)
		{
			pot[i][j]=trz;
			trz=(trz*2)%mod;
		}
	}
	for (int i=0; i<n; i++)
		for (int j=0; j<nax; j++)
			if (dlu*j<n)
				jeszkol[i][j]=pyt(dlu*j, min(dlu*j+dlu-1, n-1), i, i);
	szuk(0, n-1, 0, n-1, 250);
	printf("! %lld\n", wyn%mod);
	ff();
	return 0;
}


Measured memory_bytes: 724