Problem:
Parallel/Orthogonal

For given two lines s1 and s2, print "2" if they are parallel, "1" if they are orthogonal, or "0" otherwise.

s1 crosses points p0 and p1, and
s2 crosses points p2 and p3.

Input

The entire input looks like:

q (the number of queries)
1st query
2nd query
...
qth query

Each query consists of integer coordinates of the points p0, p1, p2, p3 in the following format:

xp0 yp0 xp1 yp1 xp2 yp2 xp3 yp3

Output

For each query, print "2", "1" or "0".

Constraints

1 ≤ q ≤ 1000

-10000 ≤ xpi, ypi ≤ 10000

p0 ≠ p1 and
p2 ≠ p3.

Sample Input 1

3
0 0 3 0 0 2 3 2
0 0 3 0 1 1 1 4
0 0 3 0 1 1 2 2

Sample Output 1

2
1
0

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;

namespace geometry
{
	public class Point{
		public double x, y;
		public Point(){
			this.x = this.y = 0;
		}

		public Point(double x, double y){
			this.x = x;
			this.y = y;
		}

		public static Point operator+(Point p1, Point p2){
			return new Point (p1.x + p2.x, p1.y + p2.y);
		}

		public static Point operator-(Point p1, Point p2){
			return new Point (p1.x - p2.x, p1.y - p2.y);
		}

		public static Point operator*(Point p1, double a){
			return new Point (p1.x * a, p1.y * a);
		}

		public static Point operator/(Point p1, double a){
			return new Point (p1.x / a, p1.y / a);
		}

		public double norm(){
			return this.x * this.x + this.y * this.y;
		}

		public double abs(){
			return Math.Sqrt(norm()); 
		}

		public Point Clone(){
			Point clone = new Point (this.x, this.y);
			return clone;
		}
	}

	public class Line{
		public Point p1, p2;
		public Line(){
			this.p1 = new Point ();
			this.p2 = new Point ();
		}

		public Line(double p1x, double p1y, double p2x, double p2y){
			this.p1 = new Point(p1x, p1y);
			this.p2 = new Point(p2x, p2y);
		}

		public Line(Point p1, Point p2){
			this.p1 = p1.Clone();
			this.p2 = p2.Clone();
		}

		public Line Clone(){
			Line clone = new Line (this.p1, this.p2);
			return clone;
		}
	}

	public class Circle{
		public Point c;
		public double r;
		public Circle(){
			this.c = new Point ();
			this.r = 0.0;
		}

		public Circle(double cx, double cy, double r){
			this.c.x = cx;
			this.c.y = cy;
			this.r = r;
		}

		public Circle(Point c, double r){
			this.c = c.Clone();
			this.r = r;
		}

		public Circle Clone(){
			Circle clone = new Circle (this.c, this.r);
			return clone;
		}
	}

	class MainClass{
		static bool is_equal(double a, double b){
			if (Math.Abs (a - b) < 0.000001) {
				return true;
			} else {
				return false;
			}
		}

		static double dot(Point v1, Point v2){
			return v1.x * v2.x + v1.y * v2.y;
		}

		static double cross(Point v1, Point v2){
			return v1.x * v2.y - v1.y * v2.x;
		}

		// ??´?????????
		static bool is_orthogonal(Line s1, Line s2){
			return is_equal(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
		}

		// ????????????
		static bool is_parallel(Line s1, Line s2){
			return is_equal(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
		}

		/*
		static bool is_intersect_sl(Line s, Line sl){
			return true;
		}
		*/

		// ?°???±??¢??°
		static Point project(Line s, Point p){
			Point base_v = s.p2 - s.p1;
			double r = dot (p - s.p1, base_v) / base_v.norm ();
			return s.p1 + base_v * r;
		}

		// ????°???¢??°
		static Point reflect(Line s, Point p){
			return p + (project(s, p) - p) * 2;
		}

		static double get_distance_p2p(Point p1, Point p2){
			return (p2 - p1).abs();
		}

		static double get_distance_l2p(Line l, Point p){
			return Math.Abs (cross (l.p2 - l.p1, p - l.p1)) / (l.p2 - l.p1).abs ();
		}

		static double get_distance_s2p(Line s, Point p){
			if (dot (s.p2 - s.p1, p - s.p1) < 0.0) {
				return (p - s.p1).abs ();
			} else if (dot (s.p1 - s.p2, p - s.p2) < 0.0) {
				return (p - s.p2).abs ();
			}
			return get_distance_l2p (s, p);
		}

		/*
		static double get_distance_s2s(Line s, Line s){
			if (
		}
		*/

		static double[] input_line(){
			string[] s = Console.ReadLine().Split(' ');
			double[] d = s.Select(i => double.Parse(i)).ToArray();
			return d;
		}

		// ?°???±
		static void CGL_1_A(){
			double[] d = input_line ();
			Line l = new Line(d[0], d[1], d[2], d[3]);

			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] p_pos = input_line ();
				Point p1 = new Point (p_pos[0], p_pos[1]);
				Point p2 = project (l, p1);
				Console.WriteLine ("{0} {1}", p2.x, p2.y);
			}
		}

		// ????°?
		static void CGL_1_B(){
			double[] d = input_line ();
			Line l = new Line(d[0], d[1], d[2], d[3]);

			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] p_pos = input_line ();
				Point p1 = new Point (p_pos [0], p_pos [1]);
				Point p2 = reflect (l, p1);
				Console.WriteLine ("{0} {1}", p2.x, p2.y);
			}
		}

		// ??´????????´???/????????????
		static void CGL_2_A(){
			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] s_pos = input_line ();
				Line s1 = new Line(s_pos[0], s_pos[1], s_pos[2], s_pos[3]);
				Line s2 = new Line(s_pos[4], s_pos[5], s_pos[6], s_pos[7]);
				if (is_parallel (s1, s2)) {
					Console.Write ("2\n");
				} else if (is_orthogonal (s1, s2)) {
					Console.Write ("1\n");
				} else {
					Console.Write ("0\n");
				}
			}
		}

		/*
		static void CGL_2_D(){
			int q = int.Parse(Console.ReadLine());
			for (int i = 0; i < q; i++) {
				double[] s_pos = input_line ();
				Line s1 = new Line(s_pos[0], s_pos[1], s_pos[2], s_pos[3]);
				Line s2 = new Line(s_pos[4], s_pos[5], s_pos[6], s_pos[7]);
			}
		}
		*/

		public static void Main (string[] args){
			// ?°???±
			//CGL_1_A ();
			// ????°?
			//CGL_1_B ();
			// ??´????????´???/????????????
			CGL_2_A ();
		}
	}
}