Language: C++

#include<iostream>
#include<iomanip>
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<sstream>
#include<queue>
#include<vector>
using namespace std;

#define MOD 1000000007
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL

#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b)) < EPS)

//0?¬?
class Point {
public:
	double x, y;

	Point(double x = 0, double y = 0) :x(x), y(y) {}

	Point operator+(Point &p) { return Point(x + p.x, y + p.y); }
	Point operator-(Point &p) { return Point(x - p.x, y - p.y); }
	Point operator*(double a) { return Point(a * x, a * y); }
	Point operator/(double a) { return Point(x / a, y / a); }
	bool operator<(const Point &p)const { return x != p.x ? x < p.x : y < p.y; }
	bool operator==(const Point &p)const { return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS; }

	double abs() { return sqrt(norm()); }
	double norm() { return x*x + y*y; }

};

//1?¬?
typedef Point Vector;

class Segment {
public:
	Point p1, p2;
	Segment(Point p1 = Point(), Point p2 = Point(1, 1)) :p1(p1), p2(p2) {}
};
typedef Segment Line;

//2?¬?
class Circle {
public:
	Point c; //center
	double r; //radius
	Circle(Point c = Point(), double r = 0.0) :c(c), r(r) {}
};
typedef vector<Point> Polygon;

//??????
double dot(Vector a, Vector b) { return a.x*b.x + a.y*b.y; }
//??????
double cross(Vector a, Vector b) { return a.x*b.y - a.y*b.x; }

//??´?????????
bool isOrthogonal(Vector a, Vector b) { return equals(dot(a, b), 0.0); }
bool isOrthogonal(Point a1, Point a2, Point b1, Point b2) { return isOrthogonal(a1 - a2, b1 - b2); }
bool isOrthogonal(Segment s1, Segment s2) { return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0); }

//????????????
bool isParallel(Vector a, Vector b) { return equals(cross(a, b), 0.0); }
bool isParallel(Point a1, Point a2, Point b1, Point b2) { return isParallel(a1 - a2, b1 - b2); }
bool isParallel(Segment s1, Segment s2) { return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0); }

//?°???±
Point project(Segment s, Point p) {
	Vector base = s.p2 - s.p1;
	double r = dot(p - s.p1, base) / base.norm();
	return s.p1 + base*r;
}
//????°?
Point reflect(Segment s, Point p) { return p + (project(s, p) - p)*2.0; }

//??????(p0,p1)????????????p2???????????¢???
enum { ONLINE_FRONT = -2, CLOCKWISE, ON_SEGMENT, COUNTER_CLOCKWISE, ONLINE_BACK };
int ccw(Point p0, Point p1, Point p2) {
	Vector a = p1 - p0, b = p2 - p0;
	if (cross(a, b) > EPS)return COUNTER_CLOCKWISE;
	if (cross(a, b) < -EPS)return CLOCKWISE;
	if (dot(a, b) < -EPS)return ONLINE_BACK;
	if (a.norm() < b.norm())return ONLINE_FRONT;
	return ON_SEGMENT;
}

//?????????????????????
bool intersect(Point p1, Point p2, Point p3, Point p4) {
	return (ccw(p1, p2, p3)*ccw(p1, p2, p4) <= 0 &&
		ccw(p3, p4, p1)*ccw(p3, p4, p2) <= 0);
}
bool intersect(Segment s1, Segment s2) { return intersect(s1.p1, s1.p2, s2.p1, s2.p2); }
//???????????????
Point getCrossPoint(Segment s1, Segment s2) {
	Vector base = s2.p2 - s2.p1;
	double a1 = abs(cross(base, s1.p1 - s2.p1)); //area1
	double a2 = abs(cross(base, s1.p2 - s2.p1)); //area2
	double t = a1 / (a1 + a2);
	return s1.p1 + (s1.p2 - s1.p1)*t;
}

//2??????????????¢
double getDistance(Point a, Point b) { return (a - b).abs(); }
//??´?????¨???????????¢
double getDistanceLP(Line l, Point p) { return abs(cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs()); }
//????????¨???????????¢
double getDistanceSP(Segment s, Point p) {
	if (dot(s.p2 - s.p1, p - s.p1) < 0.0)return (p - s.p1).abs();
	if (dot(s.p1 - s.p2, p - s.p2) < 0.0)return (p - s.p2).abs();
	return getDistanceLP(s, p);
}
//????????¨??????????????¢
double getDistance(Segment s1, Segment s2) {
	if (intersect(s1, s2))return 0.0;
	return	min(
		min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
		min(getDistanceSP(s1, s1.p1), getDistanceSP(s1, s1.p2))
	);
}

int main() {
	int q; cin >> q;
	for (int i = 0; i < q; i++) {
		Point p[4];
		for (int j = 0; j < 4; j++) {
			scanf("%lf%lf", &p[j].x, &p[j].y);
		}
		if (isParallel(p[0], p[1], p[2], p[3]))cout << 2 << endl;
		else if (isOrthogonal(p[0], p[1], p[2], p[3]))cout << 1 << endl;
		else cout << 0 << endl;
	}
	return 0;
}

Compiler output:
a.cc: In function 'Point project(Segment, Point)':
a.cc:85:21: error: no match for 'operator+' (operand types are 'Point' and 'Point')
   85 |         return s.p1 + base*r;
      |                ~~~~ ^ ~~~~~~
      |                  |        |
      |                  Point    Point
a.cc:35:15: note: candidate: 'Point Point::operator+(Point&)' (near match)
   35 |         Point operator+(Point &p) { return Point(x + p.x, y + p.y); }
      |               ^~~~~~~~
a.cc:35:15: note:   conversion of argument 1 would be ill-formed:
a.cc:85:27: error: cannot bind non-const lvalue reference of type 'Point&' to an rvalue of type 'Point'
   85 |         return s.p1 + base*r;
      |                       ~~~~^~
In file included from /usr/include/c++/14/string:48,
                 from /usr/include/c++/14/bits/locale_classes.h:40,
                 from /usr/include/c++/14/bits/ios_base.h:41,
                 from /usr/include/c++/14/ios:44,
                 from /usr/include/c++/14/ostream:40,
                 from /usr/include/c++/14/iostream:41,
                 from a.cc:1:
/usr/include/c++/14/bits/stl_iterator.h:627:5: note: candidate: 'template<class _Iterator> constexpr std::reverse_iterator<_Iterator> std::operator+(typename reverse_iterator<_Iterator>::difference_type, const reverse_iterator<_Iterator>&)'
  627 |     operator+(typename reverse_iterator<_Iterator>::difference_type __n,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:627:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::reverse_iterator<_Iterator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/stl_iterator.h:1798:5: note: candidate: 'template<class _Iterator> constexpr std::move_iterator<_IteratorL> std::operator+(typename move_iterator<_IteratorL>::difference_type, const move_iterator<_IteratorL>&)'
 1798 |     operator+(typename move_iterator<_Iterator>::difference_type __n,
      |     ^~~~~~~~
/usr/include/c++/14/bits/stl_iterator.h:1798:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::move_iterator<_IteratorL>'
   85 |         return s.p1 + base*r;
      |                            ^
In file included from /usr/include/c++/14/string:54:
/usr/include/c++/14/bits/basic_string.h:3598:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3598 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3598:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3616:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3616 |     operator+(const _CharT* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3616:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   mismatched types 'const _CharT*' and 'Point'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3635:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3635 |     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3635:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3652:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, const _CharT*)'
 3652 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3652:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3670:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, _CharT)'
 3670 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3670:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3682:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
 3682 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3682:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3689:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const __cxx11::basic_string<_CharT, _Traits, _Allocator>&, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3689 |     operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3689:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3696:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3696 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3696:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3719:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3719 |     operator+(const _CharT* __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3719:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   mismatched types 'const _CharT*' and 'Point'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3726:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
 3726 |     operator+(_CharT __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3726:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3733:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const _CharT*)'
 3733 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3733:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
/usr/include/c++/14/bits/basic_string.h:3740:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, _CharT)'
 3740 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
      |     ^~~~~~~~
/usr/include/c++/14/bits/basic_string.h:3740:5: note:   template argument deduction/substitution failed:
a.cc:85:28: note:   'Point' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
   85 |         return s.p1 + base*r;
      |                            ^
a.cc: In function 'Point reflect(Segment, Point)':
a.cc:88:46: error: no match for 'operator+' (operand types are 'Point' and 'Point')
   88 | Point reflect(Segment s, Point p) { return