#include <bits/stdc++.h>
using namespace std;

#define Fi first
#define Se second
#define pb push_back
#define mp make_pair
#define rep(x, a, b) for(int x = (a); x <= (b); ++ x)
#define per(x, a, b) for(int x = (a); x >= (b); -- x)
#define rop(x, a, b) for(int x = (a); x < (b); ++ x)
#define por(x, a, b) for(int x = (a); x > (b); -- x) 

typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned int unt;
typedef double db;
typedef pair <int, int> pii;
typedef vector <int> vi;

const db eps  = 1e-8;
const db _PI  = 3.1415926535897932384;
const db _E   = 2.7182818284590452354;
const int inf = 0x3f3f3f3f;
const LL INF  = 0x3f3f3f3f3f3f3f3fll;

int dcmp(db x) {
	if(x > eps) return 1;
	if(x < -eps) return -1;
	return 0;
}

int dcmp(db x, db y) {
	return dcmp(x - y);
}

struct Point {
	db x, y;
	Point(db _x = 0, db _y = 0) : x(_x), y(_y) {}
	void print() { printf("%.10f %.10f", x, y); }
};
struct Line {
	Point p1, p2;
	Line() {};
	Line(Point _p1, Point _p2) : p1(_p1), p2(_p2) {};
};

typedef Point Vector;
typedef Line Segment;

// CCW

const int CCW_COUNTER_CLOCKWISE = 1;
const int CCW_CLOCKWISE = -1;
const int CCW_ONLINE_FRONT = 2;
const int CCW_ONLINE_BACK = -2;
const int CCW_ON_SEGMENT = 0;

Vector operator + (const Vector &a, const Vector &b) {
	return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (const Vector &a, const Vector &b) {
	return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (const Vector &a, const db &b) {
	return Vector(a.x * b, a.y * b);
}
Vector operator / (const Vector &a, const db &b) {
	return Vector(a.x / b, a.y / b);
}
db operator * (const Vector &a, const Vector &b) {
	return a.x * b.x + a.y * b.y;
}
db operator ^ (const Vector &a, const Vector &b) {
	return a.x * b.y - a.y * b.x;
}
db dis(const Point &a, const Point &b) {
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
db dis2(const Point &a, const Point &b) {
	return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
db dis(const Vector &a) {
	return sqrt(a.x * a.x + a.y * a.y);
}
db dis2(const Vector &a) {
	return a.x * a.x + a.y * a.y;
}
Point Projection(const Line &L, const Point &p) {
	Vector Base = L.p2 - L.p1;
	db len = Base * (p - L.p1);
	return L.p1 + Base * (len / dis2(L.p1, L.p2));
}
Point Reflection(const Line &L, const Point &p) {
	return p + (Projection(L, p) - p) * 2.0;
}

int ccw(const Point &p0, const Point &p1, const Point &p2) {
	Vector p01 = p1 - p0, p02 = p2 - p0;
	if(dcmp(p01 ^ p02) == 1) return CCW_COUNTER_CLOCKWISE; // 顺时针 
	if(dcmp(p01 ^ p02) == -1) return CCW_CLOCKWISE;        // 逆时针 
	if(dcmp(p01 * p02) == -1) return CCW_ONLINE_BACK;
	if(dcmp(dis2(p01), dis2(p02)) == -1) return CCW_ONLINE_FRONT;
	return CCW_ON_SEGMENT;
}

bool isOrthogonal(const Vector &a, const Vector &b) {
	return dcmp(a * b) == 0;
}
bool isOrthogonal(const Point &a1, const Point &a2, const Point &b1, const Point &b2) {
	return isOrthogonal(a2 - a1, b2 - b1);
}
bool isOrthogonal(const Line &a, const Line &b) {
	return isOrthogonal(a.p2 - a.p1, b.p2 - b.p1);
}
bool isParallel(const Vector &a, const Vector &b) {
	return dcmp(a ^ b) == 0;
}
bool isParallel(const Point &a1, const Point &a2, const Point &b1, const Point &b2) {
	return isParallel(a2 - a1, b2 - b1);
}
bool isParallel(const Line &a, const Line &b) {
	return isParallel(a.p2 - a.p1, b.p2 - b.p1);
}

int main() {
	int q; scanf("%d", &q);
	rep(i, 1, q) {
		Line a, b;
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &a.p1.x, &a.p1.y, &a.p2.x, &a.p2.y, &b.p1.x, &b.p1.y, &b.p2.x, &b.p2.y);
		if(isOrthogonal(a, b)) puts("1");
		else if(isParallel(a, b)) puts("2");
		else puts("0");
	}
	return 0;
}


Measured memory_bytes: 3252