#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <list>
#include <climits>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <iomanip>

#define ALL(v) v.begin(), v.end()
#define REP(i, a, b) for(int i = a; i < b; i++)
#define REPD(i, a, b) for(int i = a; i > b; i--)
#define REPLL(i, a, b) for(ll i = a; i < b; i++)
#define FOR(i, a, b) for(int i = a; i <= b; i++)
#define FORD(i, a, b) for(int i = a; i >= b; i--)
#define FORLL(i, a, b) for(ll i = a; i <= b; i++)
#define INF 100001

#define vit vector<int>::iterator
#define sit set<int>::iterator
#define vi vector<int>
#define vpii vector<pii >

#define ll long long
#define ld long double

#define PB push_back
#define MP make_pair
#define pii pair<int, int>
#define pld pair<ld, ld>
#define st first
#define nd second

#define EPS 1e-9
#define PI acos(-1.0)
#define MAXN 1000

using namespace std;

int z, n, a, b;

struct point {
    ld x, y;
    point() { x = y = 0.0; }
    point(ld _x, ld _y) : x(_x), y(_y) {}
};

struct vec {
    ld x, y;
    vec(ld _x, ld _y) : x(_x), y(_y) {}
};

ld cross(vec a, vec b) {
    return a.x * b.y - a.y * b.x;
}

vec make_vec(point a, point b) {       // convert 2 points to vector a->b
    return vec(b.x - a.x, b.y - a.y);
}

vec scale(vec v, ld s) {        // nonnegative s = [<1 .. 1 .. >1]
    return vec(v.x * s, v.y * s);
}

point translate(point p, vec v) {        // translate p according to v
    return point(p.x + v.x , p.y + v.y);
}

ld dot(vec a, vec b) {
    return (a.x * b.x + a.y * b.y);
}

ld norm_sq(vec v) {
    return v.x * v.x + v.y * v.y;
}


ld ccw(point p, point q, point r) {
    return cross(make_vec(p, q), make_vec(p, r)); // >=0 for collinear
}

ld dist(point p1, point p2) {
    return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);
}

struct line {
    point a, b;
    line() {}
    line(point _a, point _b) : a(_a), b(_b) {
        if(a.x > b.x) swap(a, b);
    }

    line get_perpendicular() const {
        return line(point((-1.0)*a.y,a.x),point((-1.0)*b.y,b.x));
    }

    point get_point() const {
        vec v = make_vec(a, point(0, 0));
        return translate(b, v);
    }

    bool operator<(const line& l) const {
        return ccw(point(0, 0), get_point(), l.get_point()) > EPS;
    }

    bool operator==(const line& l) const {
        return fabs(ccw(point(0, 0), get_point(), l.get_point())) < EPS ;
    }
};

ld cross(line a, line b)  {
    return cross(make_vec(a.a, a.b), make_vec(b.a, b.b));
}


map<pair<line, ld>, ll> m;
vector<line> lines;

ld dist_to_line(point p, point a, point b, point &c) {
  // formula: c = a + u * ab
    vec ap = make_vec(a, p), ab = make_vec(a, b);
    ld u = dot(ap, ab) / norm_sq(ab);
    c = translate(a, scale(ab, u));                  // translate a to c
    return dist(p, c);
}

ld get_dist(int i, int j) {
    point c;
    return dist_to_line(lines[i].a, lines[j].a, lines[j].b, c);
}


int main()
{
    ios_base::sync_with_stdio(0);
    cin >> z;

    while(z--) {
        m.clear();
        cin >> n;
        lines.clear();
        REP(i, 0, n) {
            cin >> a >> b;
            point p1(a, b);

            cin >> a >> b;
            point p2(a, b);

            line l = line(p1, p2);
            lines.PB(l);
        }
        REP(i, 0, lines.size()) REP(j, i+1, lines.size()) {
            if(lines[i] == lines[j]) {
                m[make_pair(lines[i], get_dist(i, j))]++;
            }
        }
        ll result = 0;
        for(map<pair<line, ld>, ll>::iterator it = m.begin(); it != m.end() ; it++) {
            result += it->nd * m[MP(it->st.st.get_perpendicular(), it->st.nd)];
        }
        cout << result/2 << endl;
    }
    return 0;
}