#include <iostream>
#include <map>
#include <random>
#include <initializer_list>
using namespace std;
// --- 全局配置与类型 ---
const int MAXN = 1000000 + 5; // 由于会不断拆分区间,建议空间开大
using ll = long long;
// --- 随机权值生成 ---
random_device rd;
mt19937 rng(rd());
// --- Treap 结构体 ---
struct Node {
ll L, R; // 区间左、右端点
int lc, rc, fa; // 左右孩子、父节点
ll tsz; // 子树覆盖的总长度
uint32_t pir; // 优先级
} nd[MAXN];
int root, cnt;
map<ll, int> leftmap;
// --- 核心辅助函数 ---
inline void pull(int u) {
if (!u) return;
nd[u].tsz = (nd[u].R - nd[u].L + 1);
if (nd[u].lc) {
nd[u].tsz += nd[nd[u].lc].tsz;
nd[nd[u].lc].fa = u;
}
if (nd[u].rc) {
nd[u].tsz += nd[nd[u].rc].tsz;
nd[nd[u].rc].fa = u;
}
}
// 基础 merge (2个节点)
int merge_tree(int a, int b) {
if (!a || !b) {
int res = a | b;
if (res) nd[res].fa = 0;
return res;
}
if (nd[a].pir < nd[b].pir) {
nd[a].rc = merge_tree(nd[a].rc, b);
pull(a); nd[a].fa = 0;
return a;
} else {
nd[b].lc = merge_tree(a, nd[b].lc);
pull(b); nd[b].fa = 0;
return b;
}
}
// 列表重载
int merge_tree(std::initializer_list<int> nodes) {
int res = 0;
for (int node : nodes) {
res = merge_tree(res, node);
}
return res;
}
// 严格按照逻辑:分离出包含第k个位置的整个区间块u
void split_tree(int u, ll k, int &a, int &b) {
if (!u) { a = b = 0; return; }
ll lsz = nd[nd[u].lc].tsz;
ll own = nd[u].R - nd[u].L + 1;
if (k <= lsz) {
split_tree(nd[u].lc, k, a, nd[u].lc);
if (nd[u].lc) nd[nd[u].lc].fa = u;
pull(u); b = u; nd[b].fa = 0;
} else if (k > lsz + own) {
split_tree(nd[u].rc, k - lsz - own, nd[u].rc, b);
if (nd[u].rc) nd[nd[u].rc].fa = u;
pull(u); a = u; nd[a].fa = 0;
} else {
a = nd[u].lc; b = nd[u].rc;
if (a) nd[a].fa = 0;
if (b) nd[b].fa = 0;
nd[u].lc = nd[u].rc = 0;
pull(u); nd[u].fa = 0;
}
}
// --- 查询函数 ---
int get_node(ll lable) {
auto it = leftmap.upper_bound(lable);
return (--it)->second;
}
ll block_index(int u) {
ll res = (nd[u].lc ? nd[nd[u].lc].tsz : 0);
int curr = u;
while (nd[curr].fa) {
int p = nd[curr].fa;
if (nd[p].rc == curr) {
res += nd[p].tsz - nd[curr].tsz;
}
curr = p;
}
return res + 1;
}
ll kth(ll k) {
int u = root;
while (u) {
ll lsz = (nd[u].lc ? nd[nd[u].lc].tsz : 0);
ll own = nd[u].R - nd[u].L + 1;
if (k <= lsz) u = nd[u].lc;
else if (k <= lsz + own) return nd[u].L + (k - lsz - 1);
else { k -= (lsz + own); u = nd[u].rc; }
}
return -1;
}
// --- 主程序 ---
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
nd[++cnt] = {1, 1000000000, 0, 0, 0, 1000000000, (uint32_t)rng()};
root = cnt;
leftmap[1] = root;
int n, q;
if (!(cin >> n)) return 0;
for (int i = 1; i <= n; ++i) {
ll A, B; cin >> A >> B;
if (A == B) continue;
// --- 第一阶段:提取 A 所在的节点 ---
int targetBlockA = get_node(A);
ll posA = block_index(targetBlockA);
int treeLeftA = 0, treeRightA = 0;
split_tree(root, posA, treeLeftA, treeRightA); // 分离大树
ll oldL = nd[targetBlockA].L, oldR = nd[targetBlockA].R;
leftmap.erase(oldL);
int blockLeftA = 0, blockRightA = 0, nodeA = targetBlockA;
if (oldL < A) {
blockLeftA = ++cnt;
nd[blockLeftA] = {oldL, A - 1, 0, 0, 0, 0, (uint32_t)rng()};
pull(blockLeftA);
leftmap[oldL] = blockLeftA;
}
if (oldR > A) {
blockRightA = ++cnt;
nd[blockRightA] = {A + 1, oldR, 0, 0, 0, 0, (uint32_t)rng()};
pull(blockRightA);
leftmap[A + 1] = blockRightA;
}
nd[nodeA].L = nd[nodeA].R = A;
nd[nodeA].lc = nd[nodeA].rc = 0;
pull(nodeA);
// 重新合并除去 A 以外的树
root = merge_tree({treeLeftA, blockLeftA, blockRightA, treeRightA});
// --- 第二阶段:寻找 B 并在其前方插入 A ---
int targetBlockB = get_node(B);
ll posB = block_index(targetBlockB);
int treeLeftB = 0, treeRightB = 0;
split_tree(root, posB, treeLeftB, treeRightB); // 再次分离大树
ll bL = nd[targetBlockB].L;
leftmap.erase(bL);
int blockLeftB = 0, blockB_Start = targetBlockB;
if (bL < B) {
blockLeftB = ++cnt;
nd[blockLeftB] = {bL, B - 1, 0, 0, 0, 0, (uint32_t)rng()};
pull(blockLeftB);
leftmap[bL] = blockLeftB;
}
nd[blockB_Start].L = B; // 修改原节点左端点为 B
pull(blockB_Start);
leftmap[A] = nodeA;
leftmap[B] = blockB_Start;
// 最终合并:LeftTree + B前的碎片 + 孤立的A + 以B开头的剩余部分 + RightTree
root = merge_tree({treeLeftB, blockLeftB, nodeA, blockB_Start, treeRightB});
}
if (!(cin >> q)) return 0;
while (q--) {
char type; ll x;
cin >> type >> x;
if (type == 'P') {
int u = get_node(x);
cout << block_index(u) + (x - nd[u].L) << "\n";
} else if (type == 'L') {
cout << kth(x) << "\n";
}
}
return 0;
}