using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3");
WillReturn.Add("3 1 2");
WillReturn.Add("4 2 2");
WillReturn.Add("331895368 154715807 13941326");
//20
//32
//409369707
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
const long Hou = 1000000007;
static long mN;
static long mA;
static long mB;
static long UB;
// Aだけを配置するとして、配置可能な最大添字
static long mMaxIndA;
// Bだけを配置するとして、配置可能な最大添字
static long mMaxIndB;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
mN = wkArr[0];
mA = wkArr[1];
mB = wkArr[2];
long Result = Solve();
Console.WriteLine(Result);
}
}
static long Solve()
{
// 配置不能な場合
if (mA + mB > mN) return 0;
UB = mN;
// 簡単のため、すり替え
var ABList = new List<long>();
ABList.Add(mA);
ABList.Add(mB);
mA = ABList.Max();
mB = ABList.Min();
mMaxIndA = UB - mA;
mMaxIndB = UB - mB;
// 場合1 Aの左端 <= Bの左端 の場合
//for (long I = 0; I <= mMaxIndA; I++) {
// Console.WriteLine("AのIndが{0}の場合、Bは{1}通り", I, DerivePlaceCnt1(I));
//}
long MinPattern1 = DerivePlaceCnt1(mMaxIndA);
long MaxPattern1 = DerivePlaceCnt1(0);
long Result1 = ExecNibunhou1(MaxPattern1);
//Console.WriteLine("MinPattern1={0}", MinPattern1);
//Console.WriteLine("MaxPattern1={0}", MaxPattern1);
//Console.WriteLine("可能なBの配置数が最大なのは{0}まで", Result1);
long MaxCnt1 = Result1 + 1;
long Pattern1 = MaxCnt1 * MaxPattern1;
long Syokou1 = MaxPattern1 - 1;
Pattern1 += DeriveTousaSuuretuSum(Syokou1, MinPattern1, -1, Hou);
Pattern1 %= Hou;
//Console.WriteLine("Pattern1={0}", Pattern1);
// 場合2 Aの左端 > Bの左端 の場合
//for (long I = 0; I <= mMaxIndA; I++) {
// Console.WriteLine("AのIndが{0}の場合、Bは{1}通り", I, DerivePlaceCnt2(I));
//}
long MinPattern2 = DerivePlaceCnt2(0);
long MaxPattern2 = DerivePlaceCnt2(mMaxIndA);
long Result2 = ExecNibunhou2(MaxPattern2);
//Console.WriteLine("MinPattern2={0}", MinPattern2);
//Console.WriteLine("MaxPattern2={0}", MaxPattern2);
//Console.WriteLine("可能なBの配置数が最大なのは{0}から", Result2);
long MaxCnt2 = mMaxIndA - Result2 + 1;
long Pattern2 = MaxCnt2 * MaxPattern2;
long Syokou2 = MaxPattern2 - 1;
Pattern2 += DeriveTousaSuuretuSum(Syokou2, MinPattern2, -1, Hou);
Pattern2 %= Hou;
//Console.WriteLine("Pattern2={0}", Pattern2);
long Answer = 1;
long Prod1 = (mMaxIndA + 1) * (mMaxIndA + 1);
Prod1 %= Hou;
Answer *= Prod1;
Answer %= Hou;
long Prod2 = (mMaxIndB + 1) * (mMaxIndB + 1);
Prod2 %= Hou;
Answer *= Prod2;
Answer %= Hou;
long PatternSum = Pattern1 + Pattern2;
PatternSum %= Hou;
Answer -= PatternSum * PatternSum;
Answer %= Hou;
if (Answer < 0) Answer += Hou;
return Answer;
}
// Aの左端を引数として、可能なBの配置数を求める
// (Aの左端 <= Bの左端 の場合)
static long DerivePlaceCnt1(long pAInd)
{
long pBInd = pAInd + mA - 1;
pBInd = Math.Min(pBInd, mMaxIndB);
if (pAInd <= pBInd) {
return pBInd - pAInd + 1;
}
return 0;
}
// 二分法で、Bの配置数が最大なIndの最大値を求める
// (Aの左端 <= Bの左端 の場合)
static long ExecNibunhou1(long pMaxVal)
{
long L = 0;
long R = UB;
while (L + 1 < R) {
long Mid = (L + R) / 2;
long MidVal = DerivePlaceCnt1(Mid);
if (MidVal == pMaxVal) {
L = Mid;
}
else {
R = Mid;
}
}
return L;
}
// Aの左端を引数として、可能なBの配置数を求める
// (Aの左端 > Bの左端 の場合)
static long DerivePlaceCnt2(long pAInd)
{
// Bの長さが1なら不可
if (mB == 1) return 0;
long MaxLeft = pAInd - 1;
if (MaxLeft < 0) return 0;
long MinLeft = pAInd + 1 - mB;
MinLeft = Math.Max(0, MinLeft);
return MaxLeft - MinLeft + 1;
}
// 二分法で、Bの配置数が最大なIndの最大値を求める
// (Aの左端 > Bの左端 の場合)
static long ExecNibunhou2(long pMaxVal)
{
long L = 0;
long R = UB;
while (L + 1 < R) {
long Mid = (L + R) / 2;
long MidVal = DerivePlaceCnt2(Mid);
if (MidVal == pMaxVal) {
R = Mid;
}
else {
L = Mid;
}
}
return R;
}
// 初項と末項と公差と法を引数として、等差数列の和を返す
static long DeriveTousaSuuretuSum(long pSyokou, long pMakkou, long pKousa, long pHou)
{
long KouCnt = (pMakkou - pSyokou) / pKousa + 1;
long wkSum = (pSyokou + pMakkou) % Hou;
wkSum %= Hou;
long Result = wkSum * KouCnt;
Result %= Hou;
Result *= DeriveGyakugen(2);
Result %= Hou;
return Result;
}
// 引数の逆元を求める
static long DeriveGyakugen(long pLong)
{
return DeriveBekijyou(pLong, Hou - 2, Hou);
}
// 繰り返し2乗法で、(NのP乗) Mod Mを求める
static long DeriveBekijyou(long pN, long pP, long pM)
{
long CurrJyousuu = pN % pM;
long CurrShisuu = 1;
long WillReturn = 1;
while (true) {
// 対象ビットが立っている場合
if ((pP & CurrShisuu) > 0) {
WillReturn = (WillReturn * CurrJyousuu) % pM;
}
CurrShisuu *= 2;
if (CurrShisuu > pP) return WillReturn;
CurrJyousuu = (CurrJyousuu * CurrJyousuu) % pM;
}
}
}