#include <stdlib.h>   // malloc / free
#include <string.h>   // strlen

// 演算法 / Algorithm:
// 1) 正向掃一遍 s，只記錄每步「操作後的長度」(不存內容)。
//    Forward pass: record only the length after each operation.
// 2) 反向走查，把目標位置 pos 一路翻譯回去，直到落在某個字母步驟。
//    Backward walk: map target position pos back until it lands on a letter step.

char processStr(char* s, long long k) {
    int n = (int)strlen(s);                 // s 的長度 / length of s
    // 配置長度陣列：len[i] = 處理完 s[i] 之後的長度
    // allocate array: len[i] = length after processing s[i]
    long long* len = (long long*)malloc(sizeof(long long) * n);

    const long long CAP = 2000000000000000LL; // 2e15 上限，防止翻倍時溢位 / cap to avoid overflow on doubling
    long long cur = 0;                        // 目前長度 / current length

    // ---- 正向：計算每一步的長度 / forward: compute each length ----
    for (int i = 0; i < n; i++) {
        char c = s[i];
        if (c >= 'a' && c <= 'z') {           // 字母 → 長度 +1 / letter → length +1
            cur += 1;
        } else if (c == '*') {                // '*' → 非空時 -1 / remove one if non-empty
            if (cur > 0) cur -= 1;
        } else if (c == '#') {                // '#' → 長度翻倍 / duplicate doubles length
            cur *= 2;
            if (cur > CAP) cur = CAP;          // 夾住上限，合法輸入碰不到 / clamp; valid inputs never reach it
        }
        // c == '%' → 反轉不改變長度，cur 不動 / reverse keeps length, do nothing
        len[i] = cur;                         // 記下這一步後的長度 / store length after this step
    }

    long long finalLen = (n > 0) ? len[n - 1] : 0; // 最終長度 / final length
    if (k >= finalLen) {                       // k 超出範圍 / k out of bounds
        free(len);                             // 釋放記憶體 / release memory
        return '.';
    }

    long long pos = k;                         // 目前要找的位置 / position we are tracking
    char ans = '.';                            // 預設答案 / default answer

    // ---- 反向：把 pos 翻譯回更早的位置 / backward: translate pos to earlier positions ----
    for (int i = n - 1; i >= 0; i--) {
        // prevLen = 執行 s[i] 之前的長度 / length BEFORE op i
        long long prevLen = (i > 0) ? len[i - 1] : 0;
        char c = s[i];

        if (c >= 'a' && c <= 'z') {            // 字母步驟 / letter step
            // 這個字母被放在第 prevLen 格 / this letter sits at slot prevLen
            if (pos == prevLen) { ans = c; break; } // 命中即為答案 / a hit is the answer
            // 否則 pos < prevLen，字母非目標，pos 不變 / otherwise unaffected
        } else if (c == '*') {
            // 刪除只動最尾，pos 在更前面，不受影響 / remove touches only the end
        } else if (c == '#') {
            // 複製後的後半是前半翻版，用模運算折回 / fold back-half into front via modulo
            if (prevLen > 0) pos = pos % prevLen;
        } else if (c == '%') {
            // 反轉 → 位置鏡射 / reverse mirrors the position
            pos = prevLen - 1 - pos;
        }
    }

    free(len);                                 // 用完歸還記憶體 / free heap memory
    return ans;
}
