#include <bits/stdc++.h>   struct Mock {     Mock(int n, const std::string &s) : n(n), s(s) {}     std::vector<std::string> ask(int l, int r) {       if (l > r) {         return {};       }       std::vector<std::string> substrings;       for (int i = l - 1; i < r; ++i) {         for (int j = 1; i + j <= r; ++j) {           auto ss = s.substr(i, j);           std::shuffle(ss.begin(), ss.end(), gen);           substrings.push_back(ss);         }       }       std::shuffle(substrings.begin(), substrings.end(), gen);       return substrings;     }     void out(const std::string &t) { assert(s == t); }     int n;       private:     std::string s;     std::mt19937 gen;   };   struct IO {     IO() { scanf( %d , &n); }     std::vector<std::string> ask(int l, int r) {       if (l > r) {         return {};       }       printf( ? %d %d n , l, r);       fflush(stdout);       std::vector<char> buf(r - l + 2);       std::vector<std::string> substrings;       int size = (r - l + 2) * (r - l + 1) / 2;       for (int i = 0; i < size; ++i) {         scanf( %s , buf.data());         substrings.push_back(buf.data());       }       return substrings;     }     void out(const std::string &t) {       printf( ! %s n , t.c_str());       fflush(stdout);     }     int n;   };   static const int C = 26;   using Count = std::array<int, C>;   Count toCount(const std::string &s) {     Count result;     memset(result.data(), 0, sizeof(result));     for (char c : s) {       result[c -  a ]++;     }     return result;   }   template <typename IO>   std::string solve(IO &io) {     int n = io.n;     if (n == 1) {       return io.ask(1, 1)[0];     }     int n2 = n >> 1;     std::vector<int> s(n, 0);     {       std::map<Count, int> halfs;       for (auto &&s : io.ask(1, n2)) {         halfs[toCount(s)]++;       }       for (auto &&s : io.ask(2, n2)) {         halfs[toCount(s)]--;       }       std::vector<std::pair<int, Count>> counts;       for (auto &&kv : halfs) {         if (kv.second) {           int size = 0;           for (int c : kv.first) {             size += c;           }           counts.emplace_back(size, kv.first);         }       }       std::sort(counts.begin(), counts.end());       assert(static_cast<int>(counts.size()) == n2);       for (int i = 0; i < n2; ++i) {         auto count = counts[i].second;         for (int j = 0; j < i; ++j) {           count[s[j]]--;         }         while (!count[s[i]]) {           s[i]++;         }       }     }     {       std::vector<Count> counts(n + 1);       for (auto &&s : io.ask(1, n)) {         auto count = toCount(s);         for (int j = 0; j < C; ++j) {           counts[s.length()][j] += count[j];         }       }       for (int i = n + 1 >> 1; i >= 1; --i) {         auto count = counts[i];         for (int j = 0; j < C; ++j) {           count[j] -= counts[i - 1][j];         }         int left = i - 1, right = n - i;         for (int j = left; j < right; ++j) {           count[s[j]]--;         }         while (!count[s[right]]) {           s[right]++;         }       }     }     std::string buf(n,    );     for (int i = 0; i < n; ++i) {       buf[i] =  a  + s[i];     }     return buf;   }   int main() {     IO io;     io.out(solve(io));   }