Problem:
Score : 1100 points

Problem Statement

Let f(A, B), where A and B are positive integers, be the string satisfying the following conditions:

f(A, B) has length A + B;

f(A, B) contains exactly A letters A and exactly B letters B;

The length of the longest substring of f(A, B) consisting of equal letters (ex., AAAAA or BBBB) is as small as possible under the conditions above;

f(A, B) is the lexicographically smallest string satisfying the conditions above.

For example, f(2, 3) = BABAB, and f(6, 4) = AABAABAABB.

Answer Q queries: find the substring of f(A_i, B_i) from position C_i to position D_i (1-based).

Constraints

1 \leq Q \leq 10^3

1 \leq A_i, B_i \leq 5 \times 10^8

1 \leq C_i \leq D_i \leq A_i + B_i

D_i - C_i + 1 \leq 100

All input values are integers.

Partial Score

500 points will be awarded for passing the testset satisfying 1 \leq A_i, B_i \leq 10^3.

Input

Input is given from Standard Input in the following format:

Q
A_1 B_1 C_1 D_1
A_2 B_2 C_2 D_2
:
A_Q B_Q C_Q D_Q

Output

For each query i in order of input, print a line containing the substring of f(A_i, B_i) from position C_i to position D_i (1-based).

Sample Input 1

5
2 3 1 5
6 4 1 10
2 3 4 4
6 4 3 7
8 10 5 8

Sample Output 1

BABAB
AABAABAABB
A
BAABA
ABAB

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

//MIPT Cryptozoology 17.2
#pragma comment(linker, "/STACK:512000000")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

#define all(a) a.begin(), a.end()
typedef long long li;
typedef long double ld;
void solve(bool);
void precalc();
clock_t start;
#define FILENAME ""

int main() {
#ifdef AIM
    string s = FILENAME;
    //assert(!s.empty());
    freopen("/home/alexandero/ClionProjects/cryptozoology/input.txt", "r", stdin);
#else
    //freopen(FILENAME ".in", "r", stdin);
    //freopen(FILENAME ".out", "w", stdout);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    start = clock();
    int t = 1;
    cout.sync_with_stdio(0);
    cin.tie(0);
    precalc();
    cout.precision(10);
    cout << fixed;
    cin >> t;
    int testNum = 1;
    while (t--) {
        //cout << "Case #" << testNum++ << ": ";
        //cerr << testNum << endl;
        solve(true);
        //cerr << testNum - 1 << endl;
    }
    cout.flush();
#ifdef AIM1
    while (true) {
      solve(false);
  }
#endif

#ifdef AIM
    cout.flush();
    cerr << "\n\n time: " << (clock() - start) / 1.0 / CLOCKS_PER_SEC << "\n\n";
#endif

    return 0;
}

void precalc() {
}

template<typename T>
inline T nxt() {
    T cur;
    cin >> cur;
    return cur;
}

//#define int li
//const int mod = 1000000007;

int get_res(int a, int b) {
    int L = 0, R = a + b;
    while (L + 1 < R) {
        int d = (L + R) / 2;
        if ((a - 1) / d <= b) {
            R = d;
        } else {
            L = d;
        }
    }
    return R;
}

void solve(bool read) {
    int a, b, C, D;
    cin >> a >> b >> C >> D;
    int A = a, B = b;

    if (a >= b) {
        int d = get_res(a, b);

        int first_steps = min(a / d, b);
        a -= first_steps * d;
        b -= first_steps;

        //cout << a << " " << b << " " << d << " " << first_steps << " " << a << " " << b << endl;

        auto get_symbol = [&](int pos) {
          if (pos < first_steps * (d + 1)) {
              if (pos % (d + 1) == d) {
                  return 'B';
              } else {
                  return 'A';
              }
          } else {
              pos -= first_steps * (d + 1);
              if (pos < a) {
                  return 'A';
              }
              return 'B';
          }
        };

        string ans;
        for (int pos = C - 1; pos < D; ++pos) {
            ans += get_symbol(pos);
        }
        cout << ans << endl;

    } else {
        int d = get_res(b, a);
        if (d == 1) {
            for (int i = C - 1; i < D; ++i) {
                if ((A + B - 1 - i) % 2 == 0) {
                    cout << 'B';
                } else {
                    cout << 'A';
                }
            }
            cout << "\n";
            return;
        }

        /*int diff = a * d - b;
        int pref_b = 0;
        int full_steps = 0;
        if (diff < 0) {
            full_steps = 0;
            pref_b = b - a * d;
            b -= pref_b;
        } else {
            full_steps = diff / (d * d - 1);
            a -= full_steps * d;
            b -= full_steps;
            while ((a - d) * d > b - 1) {
                ++full_steps;
                a -= d;
                --b;
            }
        }*/

        vector<int> as, bs;
        do {
            if (b == 0) {
                assert(a == 0);
                break;
            }
            int need_a = (b + d - 1) / d;
            assert(need_a <= a);
            int take = min(a - need_a + 1, d);
            as.push_back(take);
            a -= take;
            int min_b = min(max(b - a * d, 1), d);
            //assert(min_b > 0 && min_b <= d);
            bs.push_back(min_b);
            b -= min_b;
        } while (true); //as.back() != 1 || bs.back() != d);

        int trivial_steps = b / d;
        a -= trivial_steps;
        b -= trivial_steps * d;

        //cout << A << " " << B << " " << d << " " << pref_b << " " << full_steps << " " << between << " " << trivial_steps << " " << a << " " << b << endl;

        auto get_symbol = [&](int pos) {
            /*if (pos < pref_b) {
                return 'B';
            }
            pos -= pref_b;
            if (pos < full_steps * (d + 1)) {
                int rem = pos % (d + 1);
                return rem < d ? 'A' : 'B';
            }
            pos -= full_steps * (d + 1);*/

            for (int i = 0; i < as.size(); ++i) {
                if (pos < as[i]) return 'A';
                pos -= as[i];
                if (pos < bs[i]) return 'B';
                pos -= bs[i];
            };
            if (pos < trivial_steps * (d + 1)) {
                return (pos % (d + 1) == 0) ? 'A' : 'B';
            }
            pos -= trivial_steps * (d + 1);
            if (pos < a) {
                return 'A';
            }
            return 'B';
        };

        string ans;
        for (int pos = C - 1; pos < D; ++pos) {
            ans += get_symbol(pos);
        }
        cout << ans << endl;
    }

}