#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;

namespace {

const string ALPH = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const int DEFAULT_PAYLOAD = 240;

struct Candidate {
    int r, c;
};

int N, NUM_AGENTS, AGENT_ID, MAX_MSG_LEN;

string command(const string &line) {
    cout << line << '\n' << flush;
    string reply;
    if (!getline(cin, reply)) exit(0);
    return reply;
}

void finish_no_reply(const string &line) {
    cout << line << '\n' << flush;
    exit(0);
}

long long count_for_agent(long long total, int id) {
    if (id >= total) return 0;
    return (total - 1 - id) / NUM_AGENTS + 1;
}

int encoded_len(long long bits) {
    return (int)((bits + 5) / 6);
}

int payload_limit() {
    return max(1, min(DEFAULT_PAYLOAD, MAX_MSG_LEN));
}

int chunk_count(long long bits) {
    int chars = encoded_len(bits);
    int payload = payload_limit();
    return (chars + payload - 1) / payload;
}

Candidate candidate_at(long long idx, int m) {
    long long horizontal = 1LL * m * (m - 1);
    if (idx < horizontal) {
        int i = (int)(idx / (m - 1));
        int j = (int)(idx % (m - 1));
        return {2 * i + 1, 2 * j + 2};
    }
    idx -= horizontal;
    int i = (int)(idx / m);
    int j = (int)(idx % m);
    return {2 * i + 2, 2 * j + 1};
}

string encode_bits(const vector<unsigned char> &bits) {
    string out;
    out.reserve((bits.size() + 5) / 6);
    for (size_t i = 0; i < bits.size(); i += 6) {
        int value = 0;
        for (int b = 0; b < 6 && i + b < bits.size(); ++b) {
            value |= (int(bits[i + b]) << b);
        }
        out.push_back(ALPH[value]);
    }
    return out;
}

vector<unsigned char> decode_bits(const string &text, long long need) {
    static int inv[256];
    static bool ready = false;
    if (!ready) {
        fill(begin(inv), end(inv), -1);
        for (int i = 0; i < (int)ALPH.size(); ++i) inv[(unsigned char)ALPH[i]] = i;
        ready = true;
    }

    vector<unsigned char> bits;
    bits.reserve((size_t)need);
    for (unsigned char ch : text) {
        int value = inv[ch];
        if (value < 0) continue;
        for (int b = 0; b < 6 && (long long)bits.size() < need; ++b) {
            bits.push_back((value >> b) & 1);
        }
    }
    bits.resize((size_t)need, 0);
    return bits;
}

void fill_agent_edges(int id, const vector<unsigned char> &bits, vector<unsigned char> &edge_open) {
    long long pos = 0;
    for (long long idx = id; idx < (long long)edge_open.size(); idx += NUM_AGENTS) {
        edge_open[(size_t)idx] = bits[(size_t)pos++];
    }
}

string build_answer(const vector<unsigned char> &edge_open, int m) {
    if (m == 1) return "";

    int rooms = m * m;
    int horizontal = m * (m - 1);
    vector<int> parent(rooms, -1);
    vector<char> step(rooms, '?');
    queue<int> q;
    parent[0] = 0;
    q.push(0);

    auto push = [&](int from, int to, char ch) {
        if (to < 0 || to >= rooms || parent[to] != -1) return;
        parent[to] = from;
        step[to] = ch;
        q.push(to);
    };

    while (!q.empty()) {
        int v = q.front();
        q.pop();
        if (v == rooms - 1) break;
        int i = v / m;
        int j = v % m;

        if (j > 0 && edge_open[(size_t)(i * (m - 1) + (j - 1))]) push(v, v - 1, 'L');
        if (j + 1 < m && edge_open[(size_t)(i * (m - 1) + j)]) push(v, v + 1, 'R');
        if (i > 0 && edge_open[(size_t)(horizontal + (i - 1) * m + j)]) push(v, v - m, 'U');
        if (i + 1 < m && edge_open[(size_t)(horizontal + i * m + j)]) push(v, v + m, 'D');
    }

    string room_steps;
    for (int cur = rooms - 1; cur != 0; cur = parent[cur]) {
        if (cur < 0 || parent[cur] < 0) finish_no_reply("halt");
        room_steps.push_back(step[cur]);
    }
    reverse(room_steps.begin(), room_steps.end());

    string answer;
    answer.reserve(room_steps.size() * 2);
    for (char ch : room_steps) {
        answer.push_back(ch);
        answer.push_back(ch);
    }
    return answer;
}

}  // namespace

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    if (!(cin >> N >> NUM_AGENTS >> AGENT_ID >> MAX_MSG_LEN)) return 0;
    string dummy;
    getline(cin, dummy);

    if (N == 1) {
        if (AGENT_ID == 0) finish_no_reply("!");
        finish_no_reply("halt");
    }

    int m = (N + 1) / 2;
    long long total_edges = 2LL * m * (m - 1);

    vector<unsigned char> my_bits;
    my_bits.reserve((size_t)count_for_agent(total_edges, AGENT_ID));
    for (long long idx = AGENT_ID; idx < total_edges; idx += NUM_AGENTS) {
        Candidate cand = candidate_at(idx, m);
        string reply = command("? " + to_string(cand.r) + " " + to_string(cand.c));
        my_bits.push_back(!reply.empty() && reply[0] == '1');
    }

    string packed = encode_bits(my_bits);
    int payload = payload_limit();

    if (AGENT_ID != 0) {
        for (int pos = 0; pos < (int)packed.size(); pos += payload) {
            command("> 0 " + packed.substr(pos, payload));
        }
        finish_no_reply("halt");
    }

    vector<unsigned char> edge_open((size_t)total_edges, 0);
    fill_agent_edges(0, my_bits, edge_open);

    int expected_messages = 0;
    vector<int> expected_chunks(NUM_AGENTS, 0);
    for (int id = 1; id < NUM_AGENTS; ++id) {
        expected_chunks[id] = chunk_count(count_for_agent(total_edges, id));
        expected_messages += expected_chunks[id];
    }

    vector<string> received(NUM_AGENTS);
    vector<int> got_chunks(NUM_AGENTS, 0);
    if (expected_messages > 0) command(".");

    int got_messages = 0;
    while (got_messages < expected_messages) {
        string reply = command("< ?");
        if (reply == "- -") continue;

        size_t sp = reply.find(' ');
        if (sp == string::npos) continue;
        int sender = stoi(reply.substr(0, sp));
        if (sender <= 0 || sender >= NUM_AGENTS) continue;
        if (got_chunks[sender] >= expected_chunks[sender]) continue;

        received[sender] += reply.substr(sp + 1);
        ++got_chunks[sender];
        ++got_messages;
    }

    for (int id = 1; id < NUM_AGENTS; ++id) {
        vector<unsigned char> bits = decode_bits(received[id], count_for_agent(total_edges, id));
        fill_agent_edges(id, bits, edge_open);
    }

    string answer = build_answer(edge_open, m);
    finish_no_reply("! " + answer);
}
