#include <iostream>
#include <algorithm>
#include <iterator>
#include <iomanip>
#include <cmath>
#include <vector>
#include <numeric>
#include <cstdio>
#include <bitset>
#include <map>
#include <string>
#include <valarray>
#include <queue>
#include <utility>
#include <functional>
#include <list>


using namespace std;

const double ESP = 1E-8;

struct Point
{
    //friends
    friend Point operator*(double c, const Point & p);
    friend ostream & operator<<(ostream & os, const Point & p);
    friend istream & operator>>(istream & is, Point & p);
    friend double cross(const Point & p1, const Point & p2);

  
    //members
    double x, y;

    Point() {};
    Point(double x, double y): x(x), y(y) {};

    Point operator-(const Point & p) const
    {
        // Point difference = {x - p.x, y - p.y};
        // return difference;
        return Point(x - p.x, y - p.y);
    }

    double operator*(const Point & p) const
    {
        return x*p.x + y*p.y;
    }

    Point operator*(double c) const
    {
        // Point p = {c*x, c*y};
        // return p;
        return Point(c*x, c*y);
    }

    Point operator+(const Point & p) const
    {
        // Point sum = {x+p.x, y+p.y};
        // return sum;
        return Point(x+p.x, y+p.y);
    }

    Point projection(const Point & p1, const Point & p2) const
    {
        Point a(*this-p1), b(p2-p1);
        return (a*b)/(b*b)*b+p1;
    }

    Point reflection(const Point & p1, const Point & p2) const
    {
        return this->projection(p1, p2)*2 - *this;
    }

};


struct Line
{
    Line() = default;
    Line(const Point & p1, const Point & p2): directional(p1-p2), point_online(p1) {}; 
    Point directional, point_online;
};


//function related with point
double norm(const Point & p);
bool check_clockwise(const Point & p0, const Point & p1, const Point & p2);
bool check_counter_clockwise(const Point & p0, const Point & p1, const Point & p2);
bool check_online_back(const Point & p0, const Point & p1, const Point & p2);
bool check_online_front(const Point & p0, const Point & p1, const Point & p2);
bool check_on_segment(const Point & p0, const Point & p1, const Point & p2);
// bool check_parallel(const Point & p0, const Point & p1, const Point & p2, const Point & p3);


//functions related with lines
bool check_parallel(const Line & l1, const Line & l2);
bool check_orthogonal(const Line & l1, const Line & l2);

int main()
{
    Point p0, p1, p2, p3;

    int q;
    cin >> q;

    int result;

    for (int i = 0; i < q; i++)
    {
        cin >> p0 >> p1 >> p2 >> p3;
        if (check_parallel(Line(p0, p1), Line(p2, p3)))
            result = 2;
        else if (check_orthogonal(Line(p0, p1), Line(p2, p3)))
            result = 1;
        else
            result = 0;

        cout << result << endl;
    }


    // vector<string> results(q);
    // for (int i = 0; i < q; i++)
    // {
    //     cin >> p2;
    //     if (check_counter_clockwise(p0, p1, p2))
    //         results[i] = "COUNTER_CLOCKWISE";
    //     else if (check_clockwise(p0, p1, p2))
    //         results[i] = "CLOCKWISE";
    //     else if (check_online_back(p0, p1, p2))
    //         results[i] = "ONLINE_BACK";
    //     else if (check_online_front(p0, p1, p2))
    //         results[i] = "ONLINE_FRONT";
    //     else if (check_on_segment(p0, p1, p2))
    //         results[i] = "ON_SEGMENT";
    // }

    // for (auto x: results)
    //     cout << x << endl;

}


//friends
Point operator*(double c, const Point & p)
{
    return p*c;
}

ostream & operator<<(ostream & os, const Point & p) 
{
    os << setprecision(8) << fixed << p.x << ' ' << p.y << endl;
    return os;
}

istream & operator>>(istream & is, Point & p)
{
    is >> p.x >> p.y;
    return is;
}

double cross(const Point & p1, const Point & p2)
{
    return p1.x*p2.y-p1.y*p2.x;
}

bool check_counter_clockwise(const Point & p0, const Point & p1, const Point & p2)
{
    return cross(p1-p0,p2-p0) > 0;
}

bool check_clockwise(const Point & p0, const Point & p1, const Point & p2)
{
    return cross(p1-p0,p2-p0) < 0;
}

double norm(const Point & p)
{
    return sqrt(p*p);
}

bool check_online_back(const Point & p0, const Point & p1, const Point & p2)
{
    Point a(p2-p0), b(p1-p0);
    double norm_a = norm(a), norm_b = norm(b);
    return fabs(a*b+norm_a*norm_b)<ESP && fabs(norm_a)>ESP;
}


bool check_online_front(const Point & p0, const Point & p1, const Point & p2)
{
    Point a(p2-p0), b(p1-p0);
    double norm_a = norm(a), norm_b = norm(b);
    return fabs(a*b-norm_a*norm_b)<ESP && norm_a>norm_b && fabs(norm_a-norm_b)>ESP;
}


bool check_on_segment(const Point & p0, const Point & p1, const Point & p2)
{
    Point a(p2-p0), b(p1-p0);
    double norm_a = norm(a), norm_b = norm(b);
    return fabs(a*b-norm_a*norm_b)<ESP && ((norm_a<norm_b && fabs(norm_a-norm_b)>ESP) || fabs(norm_a-norm_b)<ESP);
    // double d1=a*b, d2=norm_a*norm_b, d3=fabs(d1-d2);
    // bool t1 = d3<=ESP, t2=norm_a<norm_b && fabs(norm_a-norm_b)>=ESP, t3=fabs(norm_a-norm_b)<=ESP;
    // return t1 &&(t2||t3);
}


bool check_parallel(const Line & l1, const Line & l2)
{
    return cross(l1.directional, l2.directional)==0;
}


bool check_orthogonal(const Line & l1, const Line & l2)
{
    return l1.directional*l2.directional==0;
}


Measured memory_bytes: 3228