#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (int)n; i++)

const double eps = 1e-10;

struct Point {
  double x, y;
  Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}  
  double norm() {return sqrt(x*x + y*y);}
};

Point operator + (const Point &p, const Point &q) {return Point(p.x + q.x, p.y + q.y);}
Point operator - (const Point &p, const Point &q) {return Point(p.x - q.x, p.y - q.y);}
double operator * (const Point &p, const Point q) {return p.x * q.x + p.y * q.y;}
bool operator == (const Point &p, const Point &q) {return (abs(p.x - q.x) < eps && abs(p.y - q.y) < eps);}
bool operator != (const Point &p, const Point &q) {return !(p == q);}
double cross(const Point &p, const Point &q) {return p.x*q.y - p.y*q.x;}

struct Line_Segment {
  Point p , q;
  Line_Segment(Point p = Point(0.0,0.0), Point q = Point(0.0,0.0)) : p(p), q(q) {}
};

struct Line {
  double a, b, c;
  Line(double a, double b, double c) : a(a), b(b), c(c) {}
  Line(Point p, Point q) {
    a = q.y - p.y;
    b = p.x - q.x;
    c = q.x * p.y - p.x * q.y;
  }
};

struct Circle {
  double r;
  Point p;
  Circle(Point p = Point(0.0, 0.0), double r = 0.0) : p(p), r(r) {}
};

// 点と直線の距離
double point_line_dist(Point p, Line l) {
  return abs(l.a*p.x + l.b*p.y + l.c) / sqrt(l.a*l.a + l.b*l.b);
}

// 点の直線への射影
Point projection (Point p, Line l) {
  double x = p.x - l.a * (l.a*p.x + l.b*p.y + l.c) / (l.a*l.a + l.b*l.b);
  double y = p.y - l.b * (l.a*p.x + l.b*p.y + l.c) / (l.a*l.a + l.b*l.b);
  return Point(x,y);
}

// 線対称な点
Point reflection(Point p, Line l) {
  double x = p.x - 2.0 * l.a * (l.a*p.x + l.b*p.y + l.c) / (l.a*l.a + l.b*l.b);
  double y = p.y - 2.0 * l.b * (l.a*p.x + l.b*p.y + l.c) / (l.a*l.a + l.b*l.b);
  return Point(x,y);
}

// 点の線分からの回転方向
int ccw(Point p, Point p1, Point p2) {
  p1 = p1 - p; p2 = p2 - p;
  if(cross(p1,p2) > eps) return 1; 
  if(cross(p1,p2) < -eps) return -1; 
  if(p1 * p2 < 0) return 2; 
  if(p1.norm() < p2.norm()) return -2; 
  return 0; 
}

// 線分の交差判定
bool line_segment_cross(const Line_Segment l, const Line_Segment s) {
  return ccw(l.p,l.q,s.p) * ccw(l.p,l.q,s.q) <= 0 && ccw(s.p,s.q,l.p) * ccw(s.p,s.q,l.q) <= 0;
}

// 直線の平行・直交判定 (平行:2 直交:1 その他:0)
int line_parallel_orthogonal(Line l, Line s) {
  if(abs(l.a*s.a + l.b*s.b) < eps) return 1;
  else if(abs(l.a*s.b - l.b*s.a) < eps) return 2;
  else return 0;
}

// 円と直線の交点
vector<Point> circle_line_cross(Line l, Circle c) {
  vector<Point> vp;
  Point h;
  h.x = c.p.x - l.a * (l.a*c.p.x + l.b*c.p.y + l.c) / (l.a*l.a + l.b*l.b);
  h.y = c.p.y - l.b * (l.a*c.p.x + l.b*c.p.y + l.c) / (l.a*l.a + l.b*l.b);

  double d = l.a*c.p.x + l.b*c.p.y + l.c;
  double q = c.r*c.r - d*d / (l.a*l.a + l.b*l.b);
  if(q >= eps) {
    Point p1, p2;
    p1.x = h.x + sqrt(q) * l.b / sqrt(l.a*l.a + l.b*l.b);
    p1.y = h.y - sqrt(q) * l.a / sqrt(l.a*l.a + l.b*l.b);
    p2.x = h.x - sqrt(q) * l.b / sqrt(l.a*l.a + l.b*l.b);
    p2.y = h.y + sqrt(q) * l.a / sqrt(l.a*l.a + l.b*l.b);
    vp.push_back(p1);
    vp.push_back(p2);
  } else if(abs(q) < eps) {
    vp.push_back(h);
  }
  return vp;
} 

int main() {
  int q;
  cin >> q;
  rep(i,q) {
    Point p0, p1, p2, p3;
    cin >> p0.x >> p0.y >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y;
    Line l(p0,p1), s(p2,p3);
    cout << line_parallel_orthogonal(l,s) << endl;
  }
}


Measured memory_bytes: 3232