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# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		for(;Q>0;Q--){
			var d = ria();
			int A = d[0], B = d[1], C = d[2], D = d[3];
			if( A > 1020 || B > 1020 ){
				Console.WriteLine("XXXXX");
				continue;
			}
			
			if(A >= B){
				int n = 1;
				while(true){
					if(((A + n -1) / n) <= B + 1){
						break;
					}
					n++;
				}
//Console.WriteLine(n);				
				List<int> aa = new List<int>();
				int ta = A;
				for(int i=0;i<(A + n - 1) / n;i++){
					aa.Add(1);
					ta -= 1;
				}
				for(int i=0;i<aa.Count;i++){
					int inc = Math.Min(ta, n - aa[i]);
					aa[i] += inc;
					ta -= inc;
				}
				//Array.Sort(aa);
				
				List<int> bb = new List<int>();
				int tb = B;
				for(int i=0;i<aa.Count - 1;i++){
					bb.Add(1);
					tb -= 1;
				}
				for(int i=0;i<bb.Count;i++){
					int inc = Math.Max(tb, n - bb[i]);
					bb[i] += inc;
					tb -= inc;
				}
				bb.Sort();
				
				List<char> L = new List<char>();
				for(int i=0;i<aa.Count;i++){
					for(int j=0;j<aa[i];j++) L.Add('A');
					if(i<bb.Count){
						for(int j=0;j<bb[i];j++) L.Add('B');
					}
				}
				
				var LL = new List<char>();
				for(int i=C-1;i<=D-1;i++){
					LL.Add(L[i]);
				}
				Console.WriteLine(new String(LL.ToArray()));
			} else {
				int n = 1;
				while(true){
					if(((B + n -1) / n) <= A + 1){
						break;
					}
					n++;
				}
				List<int> bb = new List<int>();
				int tb = B;
				for(int i=0;i<(B + n - 1) / n;i++){
					bb.Add(1);
					tb -= 1;
				}
				for(int i=0;i<bb.Count;i++){
					int inc = Math.Min(tb, n - bb[i]);
					bb[i] += inc;
					tb -= inc;
				}
				bb.Sort();
				
				List<int> aa = new List<int>();
				int ta = A;
				for(int i=0;i<bb.Count - 1;i++){
					aa.Add(1);
					ta -= 1;
				}
				for(int i=0;i<aa.Count;i++){
					int inc = Math.Max(ta, n - aa[i]);
					aa[i] += inc;
					ta -= inc;
				}
				//Array.Sort(bb);
				
				List<char> L = new List<char>();
				for(int i=0;i<bb.Count;i++){
					for(int j=0;j<bb[i];j++) L.Add('B');
					if(i<aa.Count){
						for(int j=0;j<aa[i];j++) L.Add('A');
					}
				}
				var LL = new List<char>();
				for(int i=C-1;i<=D-1;i++){
					LL.Add(L[i]);
				}
				Console.WriteLine(new String(LL.ToArray()));
			}
		}
	}
	int Q;
	public Sol(){
		Q = ri();
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}