;之后是二分查找,先sort再二分,复杂度o(logn);然后是哈希查找,复杂度o(1),注意哈希表的哈希函数
//Uva1152 用哈希查找的时候处理负数下标不知道怎么处理,算了,wa加TLe
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=4000+5;
const int mx=1000000;
int head[mx],next1[mx];
int shz1[maxn],shz2[maxn],shz3[maxn],shz4[maxn],a,b;
//三重遍历加set.count()查找 插入很耗时
//三重遍历加一重遍历查找 复杂度O(n^4)
void a1(){
int t=0;
for(int i=0;i<b;i++){
for(int j=0;j<b;j++){
for(int k=0;k<b;k++){
for(int x=0;x<b;x++){
if(-shz1[i]-shz2[j]-shz3[k]+shz4[x]==0)t++;
}
}
}
}
cout<<t<<endl;
}
//三重遍历加二分查找 复杂度n^3*logn
int ts(int i){
sort(shz4,shz4+b);
int x=0,y=b;
while(x<y){
int m=x+(y-x)/2;
if(shz4[m]==i)return 1;
else if(shz4[m]>i)y=m;
else if(shz4[m]<i)x=m+1;
}
return 0;
}
void a2(){
int t=0;
for(int i=0;i<b;i++){
for(int j=0;j<b;j++){
for(int k=0;k<b;k++){
if(ts(-shz1[i]-shz2[j]-shz3[k])){
t++;
}
}
}
}
cout<<t<<endl;
}
//三重遍历加哈希查找 复杂度n^3
int hs(int i){
return abs(i*2%1000000);
}
int ts1(int i){
int v=hs(i);
int u=head[v];
while(u){
if(u==i)return 1;
u=next1[u];
}
return 0;
}
void a3(){
cin>>b;
memset(head,0,sizeof(head));//初始化链头
for(int i=0;i<b;i++){
cin>>shz1[i]>>shz2[i]>>shz3[i]>>shz4[i];
//shz4[i] 插入到哈希表
int jud=0;
int v=hs(shz4[i]);
int u=head[v];
while(u){
if(u==shz4[i]){
jud=1;
break;
}
u=next1[u];
}
if(!jud){
next1[shz4[i]]=head[v];
head[v]=shz4[i];
}
}
int t=0;
for(int i=0;i<b;i++){
for(int j=0;j<b;j++){
for(int k=0;k<b;k++){
if(ts1(-shz1[i]-shz2[j]-shz3[k]))t++;
}
}
}
cout<<t<<endl;
}
//优化,二重遍历加哈希查找 复杂度n^2
void a4(){
int t=0;
memset(head,0,sizeof(head));
for(int i=0;i<b;i++){
for(int j=0;j<b;j++){
int x=shz1[i]+shz2[j];
int v=hs(x);
int u=head[v];
int jud=0;
while(u){
if(u==x){
jud=1;
break;
}
u=next1[u];
}
if(!jud){
next1[x]=head[v];
head[v]=x;
}
}
}
for(int i=0;i<b;i++){
for(int j=0;j<b;j++){
int x=shz3[i]+shz4[j];
int v=hs(x);
int u=head[v];
while(u){
if(u==x){
t++;
break;
}
u=next1[u];
}
}
}
cout<<t<<endl;
}
int main(){
cin>>a;
while(a--){
cin>>b;
for(int i=0;i<b;i++){
cin>>shz1[i]>>shz2[i]>>shz3[i]>>shz4[i];
}
a4();
if(a)cout<<endl;
}
return 0;
}