#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <set>
#include <cassert>
#include <map>
#include <random>
#define pii pair<int,int>
#define f first
#define s second
using namespace std;
int mod = 1;
vector<pii> ask;
mt19937 mt_rand(time(0));
const int R= 14;
bool g[50][50];
int tests= 0;
map<pii, int> mem;
auto lasthit = clock();
int query(int x, int y) {
    if (mem[{x,y}] != 0 ) return mem[{x,y}] - 1;
    tests++;
    if (tests >= 30000) {
        assert(false);
        //while (true){}
    }
    if (mod==1) cout << "? " << x << ' ' << y << endl;
    lasthit = clock();
    int ans;
    ans = mt_rand()%2;
    mem[{x,y}] = ans+1;
   if (mod==0) return ans;
    char c;
    cin >> c;
    assert(c != '0');
    ans = 0;
    if (c == 'B') ans= 1;
    mem[{x,y}] = ans+1;
    return ans;
}
int find(vector<pii>& v, pii p) {
    for (int i = 0; i < v.size(); ++i) {
        if (v[i].f==p.f && v[i].s==p.s) return i;
    }
    return -1;
}
void dfs(pii p, set<pii>& bord, map<pii,int>& comp) {
    for (int dx = -1; dx <= 1; ++dx) {
        for (int dy = -1; dy <= 1; ++dy) {
            if (dx == 0 && dy == 0) continue;
            if (bord.find({p.f+dx,p.s+dy}) != bord.end() && comp[{p.f+dx,p.s+dy}] == 0) {
                comp[{p.f+dx,p.s+dy}] = comp[p];
                dfs({p.f+dx,p.s+dy},bord,comp);
            }
        }
    }
}
void ostov(pii p, set<pii>& bord, set<pii>& chosen, int n) {
    for (int dx = -1; dx <= 1; ++dx) {
        for (int dy = -1; dy <= 1; ++dy) {
            if (dx == 0 && dy == 0) continue;
            if (bord.find({p.f+dx,p.s+dy}) != bord.end() && chosen.find({p.f+dx,p.s+dy}) == chosen.end() && chosen.size() < n) {
                chosen.insert({p.f+dx,p.s+dy});
                ostov({p.f+dx,p.s+dy},bord,chosen, n);
            }
        }
    }
}
void solve(int n) {
    mem.clear();
    int col = query(0,0);
    set<pii> fig;
    set<pii> bord;
    set<pii> cbord;
    vector<pii> corn;
    vector<pii> sid;
    fig.insert({0,0});
    for (int dx = -1; dx <= 1; ++dx) {
        for (int dy = -1; dy <= 1; ++dy) {
            if (dx==0 && dy==0) continue;
            if (dx * dy != 0) {
                corn.push_back({dx,dy});
            }
            else {
                sid.push_back({dx,dy});
            }
            bord.insert({dx,dy});
        }
    }
    int iter = 0;
    while (fig.size() < n) {
        ++iter;
        if (cbord.size()>=n && iter % 10 == 0) {
            map<pii, int> comp;
            int ccc = 1;
            for (pii p: cbord) {
                //assert(query(p.f,p.s) == 1-col);
                if (comp[p] == 0) {
                    comp[p] = ccc;
                    ccc++;
                    dfs(p, cbord,comp);
                }
            }
            vector<int> num(ccc,0);
            for (pii p: cbord) {
                num[comp[p]]++;
            }
            int ma = 1;
            for (int i = 2; i < ccc; ++i) {
                if (num[i] > num[ma]) ma=i;
            }
            if (num[ma] >= n) {
                fig.clear();
                col=1-col;
                for (pii p: cbord) {
                    if (comp[p] == ma) fig.insert(p);
                }
                break;
            }
        }
        if (sid.size() > 0) {
            int q;
            //q = 0;
            q = mt_rand()%sid.size();
            pii p = sid[q];
            sid.erase(sid.begin() + q, sid.begin() + q + 1);
            if (query(p.f, p.s) == col) {
                fig.insert(p);
                bord.erase(p);
                for (int dx = -1; dx <= 1; ++dx) {
                    for (int dy = -1; dy <= 1; ++dy) {
                        if (dx == 0 && dy == 0) continue;
                        if (dx*dy == 0) {
                            int ind = find(corn, {p.f + dx, p.s+dy});
                            if (ind != -1) {
                                corn.erase(corn.begin() + ind, corn.begin() + ind + 1);
                                sid.push_back({p.f+dx,p.s+dy});
                                bord.insert({p.f+dx,p.s+dy});
                            }
                            else if (fig.find({p.f+dx, p.s+dy}) == fig.end() && bord.find({p.f+dx,p.s+dy}) == bord.end()) {
                                bord.insert({p.f+dx,p.s+dy});
                                sid.push_back({p.f+dx,p.s+dy});
                            }
                        }
                        else {
                            if (fig.find({p.f+dx, p.s+dy}) == fig.end() && bord.find({p.f+dx,p.s+dy}) == bord.end()) {
                                bord.insert({p.f+dx,p.s+dy});
                                corn.push_back({p.f+dx,p.s+dy});
                            }
                        }
                    }
                }
            }
            else {
                cbord.insert(p);
            }
        }
        else if (corn.size() > 0) {
            int q;
            //q = 0;
            q = mt_rand()%corn.size();
            pii p = corn[q];
            corn.erase(corn.begin() + q, corn.begin() + q + 1);
            if (query(p.f, p.s) == col) {
                fig.insert(p);
                bord.erase(p);
                for (int dx = -1; dx <= 1; ++dx) {
                    for (int dy = -1; dy <= 1; ++dy) {
                        if (dx == 0 && dy == 0) continue;
                        if (dx*dy == 0) {
                            int ind = find(corn, {p.f + dx, p.s+dy});
                            if (ind != -1) {
                                corn.erase(corn.begin() + ind, corn.begin() + ind + 1);
                                sid.push_back({p.f+dx,p.s+dy});
                            }
                            if (fig.find({p.f+dx, p.s+dy}) == fig.end() && bord.find({p.f+dx,p.s+dy}) == bord.end()) {
                                bord.insert({p.f+dx,p.s+dy});
                                sid.push_back({p.f+dx,p.s+dy});
                            }
                        }
                        else {if (fig.find({p.f+dx, p.s+dy}) == fig.end() && bord.find({p.f+dx,p.s+dy}) == bord.end()) {
                                bord.insert({p.f+dx,p.s+dy});
                                corn.push_back({p.f+dx,p.s+dy});
                            }
                        }
                    }
                }
            }
            else {
                cbord.insert(p);
            }
        }

        else {
          //  cerr << fig.size() << "!\n";
            col = 1-col;
            fig.clear();
            map<pii, int> comp;
            int ccc = 1;
            for (pii p: bord) {
                if (comp[p] == 0) {
                    comp[p] = ccc;
                    ccc++;
                    dfs(p, bord,comp);
                }
            }
            vector<int> num(ccc,0);
            for (pii p: bord) {
                num[comp[p]]++;
            }
            int ma = 1;
            for (int i = 2; i < ccc; ++i) {
                if (num[i] > num[ma]) ma=i;
            }
            for (pii p: bord) {
                if (comp[p] == ma) fig.insert(p);
            }
            bord.clear();
            corn.clear();
            cbord.clear();
            for (pii p: fig) {
                assert(query(p.f,p.s) == col);
                for (int dx = -1; dx <= 1; ++dx) {
                    for (int dy = -1; dy <= 1; ++dy) {
                        if (dx == 0 && dy == 0) continue;
                        if (dx*dy == 0) {
                            int ind = find(corn, {p.f + dx, p.s+dy});
                            if (ind != -1) {
                                corn.erase(corn.begin() + ind, corn.begin() + ind + 1);
                                sid.push_back({p.f+dx,p.s+dy});
                            }
                            if (fig.find({p.f+dx, p.s+dy}) == fig.end() && bord.find({p.f+dx,p.s+dy}) == bord.end()) {
                                bord.insert({p.f+dx,p.s+dy});
                                if (mem[{p.f+dx,p.s+dy}] == 0) sid.push_back({p.f+dx,p.s+dy});
                                else cbord.insert({p.f+dx,p.s+dy});
                            }
                        }
                        else {
                            if (fig.find({p.f+dx, p.s+dy}) == fig.end() && bord.find({p.f+dx,p.s+dy}) == bord.end()) {
                                bord.insert({p.f+dx,p.s+dy});
                                if (mem[{p.f+dx,p.s+dy}] == 0) corn.push_back({p.f+dx,p.s+dy});
                                else cbord.insert({p.f+dx,p.s+dy});
                            }
                        }
                    }
                }
            }
        }

    }
    if (fig.size() > n) {
        set<pii> ans;
        ostov(*fig.begin(),fig,ans,n);
        fig=ans;
    }
    for (pii p: fig) {
        if(query(p.f,p.s) != col) {
            assert(false);
        }
    }
    if (mod==1) {
        int count = 0;
        cout << "! ";
        if (col == 1) cout << "B ";
        else cout << "W ";
        for (pii p: fig) {
            count++;
            //if (count > n) break;
            cout << p.f << ' ' << p.s << ' ';
        }
        cout << endl;
    }



}

signed main() {
    //cin.tie(nullptr)->sync_with_stdio(false);
    // for (int x = -R; x <= R; ++x) {
    //     for (int y = -R; y <= R; ++y) {
    //         if (x*x + y*y <= R*R) {
    //             ask.push_back({x,y});
    //         }
    //     }
    // }
    // sort(ask.begin(),ask.end(),[&](pii a, pii b) {
    //     return a.f * a.f + a.s * a.s > b.f * b.f + b.s * b.s;
    // });
    // deque<pii> a;
    // for (auto p: ask) {
    //     a.push_back(p);
    // }
    // while (a.size() > 600) {
    //     a.pop_back();
    //     if (a.size()>600) a.pop_front();
    // }
    // ask.clear();
    // for (auto p: a) {
    //     ask.push_back(p);
    // }
    // bool v[30][30];
    // for (int i = 0; i < 30; ++i) {
    //     for (int j = 0; j < 30; ++j) {
    //         v[i][j] = false;
    //     }
    // }
    // for (pii p: ask) {
    //     v[p.f+R][p.s+R] = true;
    // }
    // for (int i = 0; i < 30; ++i) {
    //     for (int j = 0; j < 30; ++j) {
    //         cout << v[i][j];
    //     }
    //     cout << '\n';
    // }
    int t=50, n=300;
    if (mod==1) cin >> t >> n;
    while (t--) {
        solve(n);
    }
    cerr << tests;
   // cout << tests;
}