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

namespace Geo2D{
	typedef long long int ll;
	const double eps = 1e-8;
	const double pi = acos(-1);
	const double inf = 1e100;

	/* Be careful for the criteria for == two doubles */
	/* Relative or Absolute? */
	struct Double{
		double x;
		Double(double x=0):x(x){}
		Double(const Double& rhs){x=rhs.x;}
		Double operator+(const Double& rhs)const{return Double(x+rhs.x);}
		Double& operator+=(const Double& rhs){return x+=rhs.x,*this;}
		Double operator-(const Double& rhs)const{return Double(x-rhs.x);}
		Double& operator-=(const Double& rhs){return x-=rhs.x,*this;}
		Double operator*(const Double& rhs)const{return Double(x*rhs.x);}
		Double& operator*=(const Double& rhs){return x*=rhs.x,*this;}
		Double operator/(const Double& rhs)const{return Double(x/rhs.x);}
		Double& operator/=(const Double& rhs){return x/=rhs.x,*this;}
		Double operator-()const{return Double(-x);}
		Double operator^(const Double& rhs)const{return pow(x,rhs.x);}
		Double operator^(const int& rhs)const{
			double res = 1, base = x;
			int b = rhs;
			while(b){
				if(b&1)	res = res * base;
				b >>= 1;
				base *= base;
			}
			return res;
		}
		Double& operator++(){return ++x,*this;}
		Double& operator--(){return --x,*this;}
		Double operator++(int){Double res(x);return x++,res;}
		Double operator--(int){Double res(x);return x--,res;}
		bool operator==(const Double& rhs)const{return x+eps>=rhs.x&&x<=rhs.x+eps;}
		bool operator!=(const Double& rhs)const{return !(*this==rhs);}
		bool operator<(const Double& rhs)const{return (*this==rhs)?false:x<rhs.x;}
		bool operator>(const Double& rhs)const{return (*this==rhs)?false:x>rhs.x;}
		bool operator<=(const Double& rhs)const{return (*this==rhs)?true:x<rhs.x;}
		bool operator>=(const Double& rhs)const{return (*this==rhs)?true:x>rhs.x;}
		friend ostream & operator << (ostream& os, const Double& rhs){
			os << rhs.x;
			return os;
		}
		friend istream & operator >> (istream& is, Double& rhs){
			is >> rhs.x;
			return is;
		}
		friend double abs(const Double& rhs){return abs(rhs.x);}
		friend double sin(const Double& rhs){return sin(rhs.x);}
		friend double cos(const Double& rhs){return cos(rhs.x);}
		friend double tan(const Double& rhs){return tan(rhs.x);}
		friend double asin(const Double& rhs){return asin(rhs.x);}
		friend double acos(const Double& rhs){return acos(rhs.x);}
		friend double atan(const Double& rhs){return atan(rhs.x);}
		friend double atan2(const Double& lhs,const Double& rhs){return atan2(lhs.x,rhs.x);}
		friend double sqrt(const Double& rhs){return sqrt(rhs.x);}
		friend ll ceil(const Double& rhs){return ceil(rhs.x);}
		friend ll round(const Double& rhs){return round(rhs.x);}
		friend ll floor(const Double& rhs){return floor(rhs.x);}
	};

	typedef Double T;
	/* To change a point, do P = P.member_function() */
	struct Point{
		T x,y;
		Point(T x=0,T y=0):x(x),y(y){}
		bool operator<(const Point& rhs)const{return x==rhs.x?y<rhs.y:x<rhs.x;}
		bool operator==(const Point& rhs)const{return x==rhs.x&&y==rhs.y;}
		Point operator-()const{return Point(-x,-y);}
		Point operator+(const Point& rhs)const{return Point(x+rhs.x,y+rhs.y);}
		Point operator-(const Point& rhs)const{return Point(x-rhs.x,y-rhs.y);}
		T operator*(const Point& rhs)const{return x*rhs.x+y*rhs.y;}
		Point operator*(const T& rhs)const{return Point(x*rhs,y*rhs);}
		Point operator/(const T& rhs)const{return Point(x/rhs,y/rhs);}
		T operator^(const Point& rhs)const{return x*rhs.y-y*rhs.x;}
		double len()const{return sqrt(x*x+y*y);}
		T len2()const{return x*x+y*y;}
		Point norm()const{double l = len();return *this/l;}
		Point resize(double l)const{return norm()*l;}
		Point rotpos()const{return Point(-y,x);}
		Point rotneg()const{return Point(y,-x);}
		Point rot(const double& ang)const{return Point(x*cos(ang)-y*sin(ang),y*cos(ang)+x*sin(ang));}

		/* friend function */
		friend double dist(const Point& lhs,const Point& rhs){Point delta = lhs - rhs;return delta.len();}
		friend T dist2(const Point& lhs,const Point& rhs){Point delta = lhs - rhs;return delta.len2();}
		/* the angle of ABC <= 180 */
		friend double angle(const Point& A,const Point& B,const Point& C){
			return abs(atan2(abs((A-B)^(C-B)),(A-B)*(C-B)));
		}
		friend ostream & operator << (ostream& os, const Point& rhs){
			os << rhs.x << ' ' << rhs.y;
			return os;
		}
		friend istream & operator >> (istream& is, Point& rhs){
			is >> rhs.x >> rhs.y;
			return is;
		}
	};
	/* P should contain at least two "different" points */
	vector<Point> hull(vector<Point> &P){
		if(P.size()<=1)	return {};
		vector<Point> res;
		sort(P.begin(),P.end());
		res={P[0],P[1]};
		for(int i=2;i<P.size();i++){
			while(res.size()>=2&&((res.back()-res[res.size()-2])^(P[i]-res[res.size()-2]))<=0)
				res.pop_back();
			res.emplace_back(P[i]);
		}
		for(int i=P.size()-2,t=res.size();i>=0;i--){
			while(res.size()>t&&((res.back()-res[res.size()-2])^(P[i]-res[res.size()-2]))<=0)
				res.pop_back();
			res.emplace_back(P[i]);
		}
		res.pop_back();
		if(res.size()<=1||(res.size()==2&&res[0]==res[1]))	return {};
		return res;
	}
	/* ccw, call hull for Pp,Pq beforehand */
	vector<Point> Minkowski(vector<Point>& Pp,vector<Point>& Pq){
		int n=Pp.size(),m=Pq.size();
		vector<Point> Pr;
		Pr.emplace_back(Pp[0]+Pq[0]);
		Pp.emplace_back(Pp[0]);Pq.emplace_back(Pq[0]);
		for(int i=0,j=0;i!=n||j!=m;){
			Point nxt;
			if((j==m)||(i!=n&&((Pp[i+1]-Pp[i])^(Pq[j+1]-Pq[j]))>=0)){
				nxt=Pr.back()+Pp[i+1]-Pp[i];
				i++;
			}
			else{
				nxt=Pr.back()+Pq[j+1]-Pq[j];
				j++;
			}
			while(Pr.size()>=2&&((Pr.back()-nxt)^(Pr[Pr.size()-2]-nxt))==0)
				Pr.pop_back();
			Pr.emplace_back(nxt);
		}
		Pp.pop_back();Pq.pop_back();Pr.pop_back();
		return Pr;
	}
	bool inConvex(vector<Point>& c,const Point& p){
		int L=1,R=c.size()-1;
		if(((p-c[0])^(c[L]-c[0]))>0)	return false;
		if(((p-c[0])^(c[R]-c[0]))<0)	return false;
		while(L<R){
			int mid=(L+R+1)>>1;
			if(((p-c[0])^(c[mid]-c[0]))<=0)	L=mid;
			else	R=mid-1;
		}
		if(L==c.size()-1)	L--;
		return ((p-c[L])^(c[L+1]-c[L]))<=0;
	}
	/* (-pi,pi] */
	Double norm(Double ang){
		ang = ang-round(ang/pi/2)*pi*2;
		if(ang<=-pi)	ang+=2*pi;
		if(ang>pi)	ang-=2*pi;
		return ang;
	}
	struct Line{
		Point s,e;
		Line(Point s=Point(),Point e=Point()):s(s),e(e){}
		Line(Point p,Double ang):s(p){
			ang=norm(ang);
			if(ang==pi/2)	e=s+Point(0,1);
			else if(ang==-pi/2)	e=s-Point(0,1);
			else	e=s+Point(1,tan(ang));
		}
		/* ax+by+c==0 */
		Line(Double a,Double b,Double c){
			if(a==0){
				s=Point(0,-c/b);
				e=Point(1,-c/b);
			}
			else if(b==0){
				s=Point(-c/a,0);
				e=Point(-c/a,1);
			}
			else{
				s=Point(0,-c/b);
				e=Point(-c/a,0);
			}
		}
		bool operator==(const Line& rhs)const{return s==rhs.s&&e==rhs.e;}
		double len()const{return dist(s,e);}
		T len2()const{return dist2(s,e);}
		double angle()const{return atan2(e.y-s.y,e.x-s.x);}
		Point projection(const Point& p)const{
			return s+((e-s)*((e-s)*(p-s)))/(e-s).len2();
		}
		Point symmetry(const Point& p)const{
			return projection(p)*2-p;
		}
		/* -1: at left, 0: on line, 1: at right */
		int where(const Point& p)const{
			auto x = (p-s)^(e-s);
			if(x==0)	return 0;
			else if(x>0)	return 1;
			else return -1;
		}
		/* 0: parallel, 1: same, 2: orthogonal, 3: intersect */
		int relation(const Line& l)const{
			if(parallel(l))	return where(l.s)==0;
			else if(orthogonal(l))	return 2;
			else return 3;
		}
		bool onseg(const Point& p)const{return ((p-s)^(e-s))==0&&((p-s)*(e-s))<=0;}
		bool parallel(const Line& l)const{return ((e-s)^(l.e-l.s))==0;}
		bool orthogonal(const Line& l)const{return ((e-s)*(l.e-l.s))==0;}
		friend ostream & operator << (ostream& os, const Line& rhs){
			os << rhs.s << ' ' << rhs.e;
			return os;
		}
		friend istream & operator >> (istream& is, Line& rhs){
			is >> rhs.s >> rhs.e;
			return is;
		}
		friend Point intersect(const Line& l,const Line& r){
			return Point();	
		}
	};
}
/* End of Geo2D */

using namespace Geo2D;

/* LightOJ 1203: angle
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int T;
	cin>>T;
	for(int t=1;t<=T;t++){
		double ans = inf;
		int n;
		cin>>n;
		vector<Point> res(n);
		for(int i=0;i<n;i++)
			cin>>res[i].x>>res[i].y;
		res = hull(res);
		if(res.empty())	ans = 0;
		else{
			for(int i=0;i<res.size();i++){
				int j =(i+1)%res.size(),k=(j+1)%res.size();
				ans = min(ans,angle(res[i],res[j],res[k]));
			}
		}
		cout<<fixed<<setprecision(10);
		cout<<"Case "<<t<<": "<<ans/pi*180<<endl;
	}
}
*/

/* LibreOJ 2459
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, q;
    cin >> n >> m >> q;
    vector<Point> Pp(n), Pq(m);
    for (int i = 0; i < n; i++) cin >> Pp[i].x >> Pp[i].y;
    for (int i = 0; i < m; i++) {
        cin >> Pq[i].x >> Pq[i].y;
        Pq[i].x = -Pq[i].x;
        Pq[i].y = -Pq[i].y;
    }
    Pp = hull(Pp), Pq = hull(Pq);
    vector<Point> Pr = Minkowski(Pp, Pq);
    while (q--) {
        Point P;
        cin >> P.x >> P.y;
        cout << inConvex(Pr, P) << '\n';
    }
}
*/



/* Aizu CGL 1 A */
/* Aizu CGL 1 B */
/*
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	Point s,e;
	cin>>s.x>>s.y>>e.x>>e.y;
	Line L(s,e);
	int q;
	cin>>q;
	while(q--){
		Point p;
		cin>>p.x>>p.y;
		// p = L.projection(p);
		p = L.symmetry(p);
		cout<<fixed<<setprecision(15)<<p.x<<' '<<p.y<<'\n';
	}
}
*/

/* Aizu CGL 2 A */
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int q;
	cin>>q;
	while(q--){
		Line L1,L2;
		cin>>L1>>L2;
		int r = L1.relation(L2);
		if(r==3)
			cout<<0<<'\n';
		else if(r==2)
			cout<<1<<'\n';
		else
			cout<<2<<'\n';
	}
}

/*
int main(){}
*/



Measured memory_bytes: 3308