#include<bits/stdc++.h>
#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
#define pii pair<int,int>
#define pdd pair<double,double>
#define pll pair<long long,long long>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define rush() int T;scanf("%d",&T);while(T--)
#define debug(x) cout<<#x<<": "<<x<<endl
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pf(x) printf("%d\n",x)
#define pf2(x,y) printf("%d %d\n",x,y)
#define pf3(x,y,z) printf("%d %d %d\n",x,y,z)
#define all(x) (x).begin(),(x).end()
#define PI acos(-1.0)
#define E exp(1.0)
#define db double
#define ll long long
#define ld long double
#define ull unsigned long long
//#define io
using namespace std;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
//#define gc getchar
//char buf[1<<21],*p1=buf,*p2=buf;
//inline int gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
//inline int read()
//{
//    int ret=0,f=0;char c=gc();
//    while(!isdigit(c)){if(c=='-')f=1;c=gc();}
//    while(isdigit(c)){ret=ret*10+c-48;c=gc();}
//    if(f)return -ret;return ret;
//}
const db EPS=1e-10;
inline int sign(db a){return a<-EPS?-1:a>EPS;}
inline int cmp(db a,db b){return sign(a-b);}
inline db sqr(db x){return x*x;}
struct Point{
    db x,y;
    Point(){}
    Point(db _x,db _y):x(_x),y(_y){}
    void input(){scanf("%lf%lf",&x,&y);}
    void output(){printf("%.10f %.10f\n",x,y);}
    bool operator == (Point b)const{
        return sign(x-b.x)==0&&sign(y-b.y)==0;
    }
    bool operator < (Point b)const{
        return sign(x-b.x)==0?sign(y-b.y)<0:x<b.x;
    }
    Point operator + (const Point &b)const{
        return Point(x+b.x,y+b.y);
    }
    Point operator - (const Point &b)const{
        return Point(x-b.x,y-b.y);
    }
    db operator ^ (const Point &b)const{
        return x*b.y-y*b.x;
    }
    db operator * (const Point &b)const{
        return x*b.x+y*b.y;
    }
    db len(){return hypot(x,y);}
    db len2(){return x*x+y*y;}
    db distance(Point p){return hypot(x-p.x,y-p.y);}
    Point operator * (const db &k)const{
        return Point(x*k,y*k);
    }
    Point operator / (const db &k)const{
        return Point(x/k,y/k);
    }
    db rad(Point a,Point b){
        Point p=*this;
        return fabs(atan2(fabs((a-p)^(b-p)),(a-p)*(b-p)));
    }
    Point unit(){return *this/len();}
    Point trunc(db r){
        db l=len();
        if(!sign(l))return *this;
        r/=l;
        return Point(x*r,y*r);
    }
    Point rotleft(){return Point(-y,x);}
    Point rotright(){return Point(y,-x);}
    Point rotate(Point p,db angle){
        Point v=(*this)-p;
        db c=cos(angle),s=sin(angle);
        return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    }
};
struct Line{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e):s(_s),e(_e){}
    bool operator == (Line v){
        return (s==v.s)&&(e==v.e);
    }
    Line(Point p,db angle){
        s=p;
        if(sign(angle-PI/2)==0)e=(s+Point(0,1));
        else e=(s+Point(1,tan(angle)));
    }
    Line(db a,db b,db c){
        if(sign(a)==0){
            s=Point(0,-c/b);e=Point(1,-c/b);
        }else if(sign(b)==0){
            s=Point(-c/a,0);e=Point(-c/a,1);
        }else{
            s=Point(0,-c/b);e=Point(1,(-c-a)/b);
        }
    }
    void input(){s.input();e.input();}
    void adjust(){if(e<s)swap(s,e);}
    db length(){return s.distance(e);}
    //[0,PI)
    db angle(){
        db k=atan2(e.y-s.y,e.x-s.x);
        if(sign(k)<0)k+=PI;
        if(sign(k-PI)==0)k-=PI;
        return k;
    }
    //line|1 on the left|2 on the right|3 on line|
    int relation(Point p){
        int c=sign((p-s)^(e-s));
        if(c<0)return 1;
        else if(c>0)return 2;
        else return 3;
    }
    bool pointonseg(Point p){
        return sign((p-s)^(e-s))==0&&sign((p-s)*(p-e))<=0;
    }
    bool parallel(Line v){
        return sign((e-s)^(v.e-v.s))==0;
    }
    //|0 not intersect|1 non-standard|2 intersect|
    int segcrossseg(Line v){
        int d1=sign((e-s)^(v.s-s));
        int d2=sign((e-s)^(v.e-s));
        int d3=sign((v.e-v.s)^(s-v.s));
        int d4=sign((v.e-v.s)^(e-v.s));
        if((d1^d2)==-2&&(d3^d4)==-2)return 2;
        return (d1==0&&sign((v.s-s)*(v.s-e))<=0)||
            (d2==0&&sign((v.e-s)*(v.e-e))<=0)||
            (d3==0&&sign((s-v.s)*(s-v.e))<=0)||
            (d4==0&&sign((e-v.s)*(e-v.e))<=0);
    }
    //|0 not intersect|1 non-standard|2 intersect|
    int linecrossseg(Line v){
        int d1=sign((e-s)^(v.s-s));
        int d2=sign((e-s)^(v.e-s));
        if((d1^d2)==-2)return 2;
        return (d1==0||d2==0);
    }
    //|0 parallel|1 coincides|2 intersect|
    int linecrossline(Line v){
        if((*this).parallel(v))return v.relation(s)==3;
        return 2;
    }
    //要保证两直线不平行或重合
    Point crossPoint(Line v){
        db a1=(v.e-v.s)^(s-v.s);
        db a2=(v.e-v.s)^(e-v.s);
        return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
    }

};

//	//点到直线的距离
//	double dispointtoline(Point p){
//		return fabs((p-s)^(e-s))/length();
//	}
//	//点到线段的距离
//	double dispointtoseg(Point p){
//		if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)
//			return min(p.distance(s),p.distance(e));
//		return dispointtoline(p);
//	}
//	//`返回线段到线段的距离`
//	//`前提是两线段不相交，相交距离就是0了`
//	double dissegtoseg(Line v){
//		return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),min(v.dispointtoseg(s),v.dispointtoseg(e)));
//	}
//	//`返回点p在直线上的投影`
//	Point lineprog(Point p){
//		return s + ( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );
//	}
//	//`返回点p关于直线的对称点`
//	Point symmetrypoint(Point p){
//		Point q = lineprog(p);
//		return Point(2*q.x-p.x,2*q.y-p.y);
//	}
//};

Point proj(Point p1,Point p2,Point q)
{
    Point dir=p2-p1;
    return p1+dir*(dir*(q-p1)/dir.len2());
}
Point reflect(Point p1,Point p2,Point q)
{
    return proj(p1,p2,q)*2-q;
}
Line l1,l2;
int main()
{
    #ifdef io
    freopen("in.txt","r",stdin);
    #endif
    int q;
    sc(q);
    while(q--){
        l1.input();l2.input();
        int t=l1.linecrossline(l2);
        if(!t||t==1)puts("2");
        else{
            if((l2.e-l2.s)*(l1.e-l1.s)==0)puts("1");
            else puts("0");
        }
    }
    return 0;
}



Measured memory_bytes: 3244