#include<iostream>
struct position
{
short x = -1, y = -1;
};
struct checkerboard
{
char surface[200][200] = { 0 };
position air;
bool inning = false;
};
struct ps
{
short n = 0;
position p, pd[4];
};
position in(position to) {
to.x--;
to.y--;
return to;
}
position size;
position dp(position center, short direction) {
switch (direction) {
case 0:
if (center.y)
{
center.y--;
return center;
}
break;
case 1:
if (center.y < size.y)
{
center.y++;
return center;
}
break;
case 2:
if (center.x)
{
center.x--;
return center;
}
break;
case 3:
if (center.x < size.x)
{
center.x++;
return center;
}
}
center.x = center.y = -1;
return center;
}
char see(position center, short direction, checkerboard* source) {
if ((center = dp(center, direction)).y >= 0)
return source->surface[center.y][center.x];
return 0;
}
ps seek(position center, char need, checkerboard* source) {
position p[4];
short n = 0, i;
for (i = 0; i < 4; i++)
if (see(center, i, source) == need)
p[n++] = dp(center, i);
ps s;
if (n > 0)
if (n == 1)
{
s.n = 1;
s.p = p[0];
}
else
{
s.n = n;
for (i = 0; i < n; i++)
s.pd[i] = p[i];
}
return s;
}
checkerboard* tap(checkerboard* s, position play) {
static checkerboard source;
source = *s;
source.surface[source.air.y][source.air.x] = source.surface[play.y][play.x];
source.surface[play.y][play.x] = '.';
source.air = play;
source.inning = !source.inning;
return &source;
}
int main() {
using std::cin;
using std::cout;
using std::endl;
register short i, index = 0, index2 = 0, num_of_error = 0;
static short round, rounds, select[200] = { 0 }, round_of_error[200] = { 0 };
cin >> size.y >> size.x;
static checkerboard root, branch[200], cache;
for (i = 0; i < size.y; i++)
cin >> root.surface[i];
cin >> round;
rounds = round * 2;
static position play[200];
for (i = 0; i < rounds; i++)
cin >> play[i].y >> play[i].x;
size = in(size);
for (i = 0; i < rounds; i++)
play[i] = in(play[i]);
static ps h, z[200];
h = seek(play[0], '.', &root);
root.air = h.p;
bool win;
while (true)
{
cache = root;
while (true) {
h = seek(cache.air, 'O', &cache);
if (h.n)
if (h.n == 1)
{
cache = *tap(&cache, h.p);
g:
h = seek(cache.air, 'X', &cache);
if (h.n)
if (h.n == 1)
cache = *tap(&cache, h.p);
else
{
branch[index] = cache, z[index] = h, select[index++] = 1;
cache = *tap(&cache, h.pd[0]);
}
else
{
if (index > 0)
{
cut1:
if (index - 1)
{
if (!branch[index - 1].inning)
{
index--;
goto cut1;
}
}
else
if (!branch[0].inning)
{
win = true;
break;
}
if (select[index - 1] < z[index - 1].n)
cache = *tap(&branch[index - 1], z[index - 1].pd[select[index - 1]++]);
else
if (index - 1)
{
index--;
goto cut1;
}
else
{
win = true;
break;
}
}
else
{
win = true;
break;
}
}
}
else
{
branch[index] = cache, z[index] = h, select[index++] = 1;
cache = *tap(&cache, h.pd[0]);
goto g;
}
else
{
if (index > 0)
{
cut0:
if (index - 1)
{
if (branch[index - 1].inning)
{
index--;
goto cut0;
}
}
else
if (branch[0].inning)
{
win = false;
break;
}
if (select[index - 1] < z[index - 1].n)
{
cache = *tap(&branch[index - 1], z[index - 1].pd[select[index - 1]++]);
goto g;
}
else
if (index - 1)
{
index--;
goto cut0;
}
else
{
win = false;
break;
}
}
else
{
win = false;
break;
}
}
}
index = 0;
if (win)
{
root = *tap(&root, play[index2++]);
cache = root;
while (true) {
h = seek(cache.air, 'X', &cache);
if (h.n)
if (h.n == 1)
{
cache = *tap(&cache, h.p);
g2:
h = seek(cache.air, 'O', &cache);
if (h.n)
if (h.n == 1)
cache = *tap(&cache, h.p);
else
{
branch[index] = cache, z[index] = h, select[index++] = 1;
cache = *tap(&cache, h.pd[0]);
}
else
{
if (index > 0)
{
cut02:
if (index - 1)
{
if (branch[index - 1].inning)
{
index--;
goto cut02;
}
}
else
if (branch[0].inning)
{
win = true;
break;
}
if (select[index - 1] < z[index - 1].n)
cache = *tap(&branch[index - 1], z[index - 1].pd[select[index - 1]++]);
else
if (index - 1)
{
index--;
goto cut02;
}
else
{
win = true;
break;
}
}
else
{
win = true;
break;
}
}
}
else
{
branch[index] = cache, z[index] = h, select[index++] = 1;
cache = *tap(&cache, h.pd[0]);
goto g2;
}
else
{
if (index > 0)
{
cut12:
if (index - 1)
{
if (!branch[index - 1].inning)
{
index--;
goto cut12;
}
}
else
if (!branch[0].inning)
{
win = false;
break;
}
if (select[index - 1] < z[index - 1].n)
{
cache = *tap(&branch[index - 1], z[index - 1].pd[select[index - 1]++]);
goto g2;
}
else
if (index - 1)
{
index--;
goto cut12;
}
else
{
win = false;
break;
}
}
else
{
win = false;
break;
}
}
}
}
else
root = *tap(&root, play[index2++]);
root = *tap(&root, play[index2++]);
if (win)
round_of_error[num_of_error++] = index2 / 2;
if (index2 >= rounds)
break;
}
cout << num_of_error;
for (i = 0; i < num_of_error; i++)
cout << endl << round_of_error[i];
return 0;
}