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: Wrong Answer)

#include<bits/stdc++.h>
using namespace std;

#define int long long
int T , A , B , C , D , now;

void add(int numa , int numb , int cnt = 1){
	if((!numa && !numb) || now > D) return;
	int len = numa + numb , tms = min(cnt , max(0ll , (C - now - 1) / len));
	cnt -= tms; now += len * tms;
	while(now <= D && cnt--){
		int len = numa , lft = max(C - now - 1 , 0ll);
		now += min(len , lft); len -= min(len , lft);
		while(len-- && ++now<= D) putchar('A');
		len = numb; lft = max(C - now - 1 , 0ll);
		now += min(len , lft); len -= min(len , lft);
		while(len-- && ++now <= D) putchar('B');
	}
}

signed main(){
	for(cin >> T ; T ; --T){
		cin >> A >> B >> C >> D; now = 0;
		int t = (A + B) / min(A + 1 , B + 1) , l = 0 , r = A / t;
		while(l < r){int mid = (l + r + 1) >> 1; t * (A - t * mid) >= B - mid ? l = mid : r = mid - 1;}
		add(t , 1 , l); A -= l * t; B -= l;
		if(!B){add(A , 0); continue;}
		int numa = ((A + 1) * t - B) / t; A -= numa; add(numa , B - t * A); add(1 , t , A);
		putchar('\n');
	}
	return 0;
}