//6333
//
//ID: taoxiaa1
//PROG: concom
//LANG: C++
//
//URAL ID:248353QC
//#include<iostream>
//#include<algorithm>
//#include<string>
//#include<cstring>
//#include<map>
//#include<queue>
//#include<cmath>
//#include<stack>
//#include<set>
//#include<vector>
//#include<cstdio>
#include<bits/stdc++.h>
using namespace std;
//FILE *fin, *out;
//fin = fopen("money.fin", "r");
//out = fopen("money.out", "w");
//ofstream fout("money.out");
//ifstream fin("money.in");
#define N 100005
#define M 1000000007
#define ll long long
ll fac[N] = {1, 1}, inv[N] = {1, 1}, f[N] = {1, 1};
ll C(ll a, ll b) {
if (b > a)return 0;
return fac[a] * inv[b] % M * inv[a - b] % M;
}
void init() { //快速计算阶乘的逆元
for (int i = 2; i < N; i++) {
fac[i] = fac[i - 1] * i % M;
f[i] = (M - M / i) * f[M % i] % M;
inv[i] = inv[i - 1] * f[i] % M;
}
}
struct node {
long long n, m;
int id;
bool operator<(const node &x)const {
return n < x.n;
}
} s[N];
vector<node>lis[N];
ll ans[N];
int main() {
init();
int t;
scanf("%d", &t);
ll mx = sqrt(100000);
for (int i = 1; i <= t; i++) {
scanf("%lld%lld", &s[i].n, &s[i].m);
long long l = s[i].m / mx;
//cout<<l<<endl;
s[i].id = i;
lis[l].push_back(s[i]);
}
for (int i = 0; i <= mx; i++) {
if (!lis[i].size())continue;
sort(lis[i].begin(), lis[i].end());
int k = lis[i].size();
int val = 0, in = lis[i][0].n, ik = -1;
for (int j = 0; j < k; j++) {
while (in < lis[i][j].n) val = (0ll + val + val + M - C(in ++, ik)) % M;
while (ik < lis[i][j].m) val = (val + C(in, ++ ik)) % M;
while (ik > lis[i][j].m) val = (val + M - C(in, ik --)) % M;
ans[lis[i][j].id] = val;
}
}
for (int i = 1; i <= t; ++ i) printf("%d\n", ans[i]);
return 0;
}
//6336
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int A[10], M[400][400];
int L;
LL calc (int n, int m) {
if (n < 0 || m < 0) return 0;
return 1LL * M[L - 1][L - 1] * (n / L) * (m / L) +
1LL * M[n % L][L - 1] * (m / L) +
1LL * M[L - 1][m % L] * (n / L) +
1LL * M[n % L][m % L];
}
void solve () {
cin >> L;
for (int i = 0; i < L; ++i) cin >> A[i];
int k = 0;
for (int i = 0; i < 4 * L; ++i) {
for (int j = 0; j <= i; ++j) {
if (j < 2 * L && i - j < 2 * L) M[j][i - j] = A[k];
k = (k + 1) % L;
}
}
L *= 2;
for (int i = 0; i < L; ++i) for (int j = 0; j < L; ++j) {
if (i) M[i][j] += M[i - 1][j];
if (j) M[i][j] += M[i][j - 1];
if (i && j) M[i][j] -= M[i - 1][j - 1];
}
int Q;
cin >> Q;
while (Q--) {
int xL, yL, xR, yR;
cin >> xL >> yL >> xR >> yR;
cout << calc(xR, yR) - calc(xL - 1, yR) - calc(xR, yL - 1) + calc(xL - 1, yL - 1) << endl;
}
}
int main () {
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--) solve();
return 0;
}
//6341
#include <bits/stdc++.h>
using namespace std;
int ord(char c) {
if (isdigit(c)) return c - '0';
return c - 'A' + 10;
}
char str(int c) {
if (c < 10) return c + '0';
return c + 'A' - 10;
}
int r[16][16], c[16][16];
int a[16][16];
int b[4][4];
char s[16];
int ret;
void add(int ip, int jp, int v) {
for (int i = ip * 4; i < (ip + 1) * 4; ++i) {
for (int j = jp * 4; j < (jp + 1) * 4; ++j) {
r[i][a[i][j]] += v;
c[j][a[i][j]] += v;
}
}
}
bool rot(int ip, int jp) {
for (int i = ip * 4; i < (ip + 1) * 4; ++i) {
for (int j = jp * 4; j < (jp + 1) * 4; ++j) {
--r[i][a[i][j]];
--c[j][a[i][j]];
b[j - jp * 4][(ip + 1) * 4 - i - 1] = a[i][j];
}
}
bool succ = true;
for (int i = ip * 4; i < (ip + 1) * 4; ++i) {
for (int j = jp * 4; j < (jp + 1) * 4; ++j) {
a[i][j] = b[i - ip * 4][j - jp * 4];
if ((++r[i][a[i][j]] > 1) || (++c[j][a[i][j]] > 1)) succ = false;
}
}
return succ;
}
void dfs(int ip, int jp, int now) {
if (ip == 4 && jp == 0) {
ret = min(ret, now);
return;
}
add(ip, jp, 1);
if (now >= ret) return;
for (int i = 1; i <= 4; ++i) {
if (rot(ip, jp)) dfs(jp == 3 ? ip + 1 : ip, jp == 3 ? 0 : jp + 1, now + (i & 3));
}
add(ip, jp, -1);
}
void solve () {
for (int i = 0; i < 16; ++i) {
scanf("%s", s);
for (int j = 0; j < 16; ++j) a[i][j] = ord(s[j]);
}
memset(r, 0, sizeof(r));
memset(c, 0, sizeof(c));
ret = 16 * 4;
dfs(0, 0, 0);
printf("%d\n", ret);
}
int main() {
int T;
scanf("%d", &T);
while (T--) solve();
return 0;
}