Problem:
Railroad Conflict
Nate U. Smith は大都市圏の鉄道会社を経営している．この大都市圏には，彼の鉄道会社以外にライバルの鉄道会社がある．2 社は互いに競合関係にある．
この大都市圏では，列車の運行を容易にするため，全ての路線は両端の駅を結んだ線分を経路としている．また，踏切等の設置をさけるため，全ての路線は高架または地下に敷設されている．既存路線は，全線にわたって高架を走るか，または全線にわたって地下を走るかのいずれかである．
ところで，最近，この大都市圏にある 2 つの街区 A，B がさかんに開発されていることから，Nate の会社ではこれらの街区の間に新しい路線を設けることを決断した．この新路線は，従来の路線と同様に A，B を両端とする線分を経路としたいが，経路の途中には別の路線があることから，高架あるいは地下のいずれかに全線を敷設することは不可能である．そこで，路線の一部を高架に，残りの部分を地下に敷設することにした．このとき，新路線が自社の既存路線と交わるところでは，新路線と既存路線との間の乗り継ぎを便利にするため，既存路線が高架ならば新路線も高架に，既存路線が地下ならば新路線も地下を走るようにする．また，新路線が他社の既存路線と交わるところでは，他社による妨害をさけるため，既存路線が高架ならば新路線は地下に，既存路線が地下ならば新路線は高架を走るようにする．A 駅および B 駅をそれぞれ高架あるいは地下のいずれに設けるかは特に問わない．
当然のことながら，新路線が高架から地下に，あるいは地下から高架に移るところには出入口を設けなければならない．ところが，出入口を設けるためには費用がかかるため，新路線に設ける出入口の個数は最小限に抑えたい．それには，プログラマであるあなたの助けを要すると考えた Nate は，あなたを彼の会社に呼び出した．
あなたの仕事は，A 駅，B 駅の位置，そして既存路線に関する情報が与えられたときに，新路線において最低限設けなければならない出入口の個数を求めるプログラムを作成することである．
以下の図は，サンプルとして与えた入力および出力の内容を示したものである．
Input
入力の先頭行には単一の正の整数が含まれ，これはデータセットの個数を表す．それぞれのデータセットは次の形式で与えられる．
xa
ya
xb
yb
n
xs
1
ys
1
xt
1
yt
1
o
1
l
1
xs
2
ys
2
xt
2
yt
2
o
2
l
2
...
xs
n
ys
n
xt
n
yt
n
o
n
l
n
ただし，(
xa
,
ya
) および (
xb
,
yb
) はそれぞれ A 駅，B 駅の座標を表す．
N
は既存路線の数を表す 100 以下の正の整数である．(
xs
i
,
ys
i
) および (
ys
i
,
yt
i
) は
i
番目の既存路線における始点および終点の座標を表す．
o
i
は
i
番目の既存路線の所有者を表す整数である．これは 1 または 0 のいずれかであり，1 はその路線が自社所有であることを，0 は他社所有であることをそれぞれ表す．
l
i
は
i
番目の既存路線が高架または地下のいずれにあるかを表す整数である．これも 1 または 0 のいずれかであり，1 はその路線が高架にあることを，0 は地下にあることをそれぞれ表す．
入力中に現れる x 座標および y 座標の値は -10000 から 10000 の範囲にある（両端も範囲に含まれる）．また，それぞれのデータセットにおいて，新路線を含めた全ての路線に対して，以下の条件を満たすと仮定してよい．ここで 2 点が非常に近いとは，その 2 点間の距離が 10
-9
以下であることを表す．
ある交点の非常に近くに別の交点があることはない．
ある路線の端点の非常に近くを別の路線が通ることはない．
2 つの路線の一部または全部が重なることはない．
Output
それぞれのデータセットに対して，最低限設けなければならない出入口の個数を 1 行に出力しなさい．
Sample Input
2
-10 1 10 1
4
-6 2 -2 -2 0 1
-6 -2 -2 2 1 0
6 2 2 -2 0 0
6 -2 2 2 1 1
8 12 -7 -3
8
4 -5 4 -2 1 1
4 -2 4 9 1 0
6 9 6 14 1 1
-7 6 7 6 0 0
1 0 1 10 0 0
-5 0 -5 10 0 1
-7 0 7 0 0 1
-1 0 -1 -5 0 1
Output for the Sample Input
1
3

Submitted solutions:

code_snippet: #define _USE_MATH_DEFIMES
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

const int MOD = 1'000'000'007;
const int MOD2 = 998'244'353;
const int INF = 1'000'000'000; //1e9
const int NIL = -1;
const long long LINF = 1'000'000'000'000'000'000; // 1e18
const long double EPS = 1E-10;

template<class T, class S> inline bool chmax(T &a, const S &b){
    if(a < b){
        a = b; return true;
    }
    return false;
}
template<class T, class S> inline bool chmin(T &a, const S &b){
    if(b < a){
        a = b; return true;
    }
    return false;
}






class Point2D{
    long double x, y;
public:
    Point2D(long double X=0, long double Y=0): x(X), y(Y){}
    Point2D(const Point2D& v): x(v.x), y(v.y){}
    template<class T>
    Point2D(const std::vector<T> &v){
        assert(v.size() == 2);
        x = v[0]; y = v[1];
    }
    template<class T, class T2>
    Point2D(const std::pair<T, T2> &p){
        x = p.first; y = p.second;
    }

    void setX(long double X){x = X;}
    long double getX(){return x;}
    void setY(long double Y){y = Y;}
    long double getY(){return y;}

    Point2D operator+() const{return *this;}
    Point2D operator-() const{return Point2D(-x, -y);}

    Point2D& operator=(const Point2D& v){
        x = v.x; y = v.y;
        return *this;
    }

    Point2D& operator+=(const Point2D& v){
        x += v.x; y += v.y;
        return *this;
    }

    Point2D& operator-=(const Point2D& v){
        x -= v.x; y -= v.y;
        return *this;
    }

    Point2D& operator*=(const long double a){
        x *= a; y *= a;
        return *this;
    }

    Point2D& operator/=(const long double a){
        x /= a; y /= a;
        return *this;
    }

    Point2D operator+(const Point2D& v) const{
        Point2D tmp(*this);
        return tmp += v;
    }

    Point2D operator-(const Point2D& v) const{
        Point2D tmp(*this);
        return tmp -= v;
    }

    Point2D operator*(const long double a) const{
        Point2D tmp(*this);
        return tmp *= a;
    }

    friend Point2D operator*(long double a, const Point2D v){
        return v * a;
    }

    Point2D operator/(const long double a) const{
        Point2D tmp(*this);
        return tmp /= a;
    }

    long double norm(){return x*x + y*y;}
    friend long double norm(Point2D v){return v.norm();}
    long double abs(){return sqrt(norm());}
    friend long double abs(Point2D v){return v.abs();}

    bool operator<(const Point2D &v) const{
        return x != v.x ? x < v.x : y < v.y;
    }

    bool operator>(const Point2D &v) const{
        return x != v.x ? x > v.x : y > v.y;
    }

    bool operator==(const Point2D &v) const{
        return std::abs(x - v.x) < EPS
            && std::abs(y - v.y) < EPS;
    }

    bool operator<=(const Point2D &v) const{
        return (*this < v) || (*this == v);
    }

    bool operator>=(const Point2D &v) const{
        return (*this > v) || (*this == v);
    }

    long double dot(Point2D b){
        return x*b.y + y*b.y;
    }

    friend long double dot(Point2D a, Point2D b){
        return a.dot(b);
    }

    long double cross(Point2D b){
        return x*b.y - y*b.x;
    }

    friend long double cross(Point2D a, Point2D b){
        return a.cross(b);
    }

    friend long double distance(Point2D a, Point2D b){
        return (a - b).abs();
    }

    friend bool isParallel(Point2D a, Point2D b){
        return std::abs(a.cross(b)) < EPS;
    }

    friend bool isOrthogonal(Point2D a, Point2D b){
        return std::abs(a.dot(b)) < EPS;
    }

    int ccw(Point2D b){
        if(cross(b) > EPS) return 1;//反時計
        if(cross(b) < -EPS) return -1;//時計
        if(dot(b) < -EPS) return 2;//逆向き
        if(norm() < b.norm()) return -2;//同じ向きbが大きい
        return 0;//同じ向きaが大きい
    }

    friend int ccw(Point2D a, Point2D b){
        return a.ccw(b);//同じ向きaが大きい
    }

    int ccw(Point2D p1, Point2D p2){
        return (p1 - *this).ccw(p2 - *this);
    }

    friend int ccw(Point2D p0, Point2D p1, Point2D p2){
        return p0.ccw(p1, p2);
    }

    friend bool intersect(Point2D p1, Point2D p2, Point2D p3, Point2D p4){
        return(p1.ccw(p2, p3) * p1.ccw(p2, p4) <= 0 &&
               p3.ccw(p4, p1) * p3.ccw(p4, p2) <= 0);
    }
    
    std::vector<Point2D> convex_hll(std::vector<Point2D> &v){
        int n(v.size()), k(0);
        auto comp = [](Point2D a, Point2D b){
            if(a.x != b.x) return a.x < b.x;
            else return a.y < b.y;
        };
        std::sort(std::begin(v), std::end(v), comp);
        std::vector<Point2D> ret(2*n);
        //下側
        for(int i(0); i < n; ret[k++] = v[i++]){
            while(k >= 2 && ret[k-2].ccw(ret[k-2], v[i]) <= 0) --k;
        }
        //上側
        for(int i(n-2), t = k + 1; i >= 0;ret[k++] = v[i--]){
            while(k >= t && ret[k-2].ccw(ret[k-2], v[i]) <= 0) --k;
        }
        ret.resize(k-1);
        return ret;
    }
};
using Vector2D = Point2D;

class Line2D{
    Point2D p1, p2;
public:
    Line2D(){}
    Line2D(Point2D a, Point2D b): p1(a), p2(b){}

    void setP1(const Point2D p){p1 = p;}
    Point2D getP1(){return p1;}
    void setP2(const Point2D p){p2 = p;}
    Point2D getP2(){return p2;}

    Point2D project(Point2D p){
        Point2D base(p2 - p1);
        long double r(dot(p - p1, base) / norm(base));
        return p1 + base * r;
    }

    friend Point2D project(Line2D l, Point2D p){
        return l.project(p);
    }

    friend Point2D reflect(Line2D l, Point2D p){
        return p + 2.0 * (l.project(p) - p);
    }

    friend bool isParallel(Line2D s1, Line2D s2){
        return isParallel(s1.p2 - s1.p1, s2.p2- s2.p1);
    }

    friend bool isOrthogonal(Line2D s1, Line2D s2){
        return isOrthogonal(s1.p2 - s1.p1, s2.p2- s2.p1);
    }

    friend bool intersect(Line2D s1, Line2D s2){
        return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
    }

    friend Point2D getCrossPoint(Line2D s1, Line2D s2){
        Vector2D base(s2.p2 - s2.p1);
        long double d1(std::abs(cross(base, s1.p1 - s2.p1)));
        long double d2(std::abs(cross(base, s1.p2 - s2.p1)));
        long double t(d1 / (d1 + d2));
        return s1.p1 + (s1.p2 - s1.p1) * t;
    }
};
using Segment2D = Line2D;

int main(){
    int Q; std::cin >> Q;
    while(Q--){
        long double xa, ya, xb, yb;
        std::cin >> xa >> ya >> xb >> yb;
        Point2D A(xa, ya), B(xb, yb);
        Segment2D AB(A, B);
        std::vector<std::pair<long double, int>> cross;
        int n; std::cin >> n;
        {
            long double xs, ys, xt, yt;
            int o, l;
            while(n--){
                std::cin >> xs >> ys >> xt >> yt >> o >> l;
                Point2D S(xs, ys), T(xt, yt);
                Segment2D ln(S, T);
                if(intersect(AB, ln)){
                    auto t(getCrossPoint(AB, ln));
                    cross.emplace_back(abs(t - A), o ^ l);
                }
            }
        }
        std::sort(std::begin(cross), std::end(cross));
        if(cross.empty()){
            std::cout << 0 << "\n";
            continue;
        }
        int cur(cross[0].second), ans(0);
        for(int i(1), i_len(cross.size()); i < i_len; ++i){
            if(cur != cross[i].second){
                cur = cross[i].second; ++ans;
            }
        }
        std::cout << ans << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3368
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

// 書きかけの幾何ライブラリ
// バグがあるかも

namespace geometry {

using Real = long double;
constexpr Real eps = 1e-12;
constexpr Real PI = acosl(-1);
constexpr Real INF_REAL = numeric_limits<Real>::max();

bool equal_eps(Real a, Real b) {
    return abs(a - b) < eps;
}

int sgn(Real a) {
    return equal_eps(a, 0) ? 0 : a > 0 ? 1 : -1;
}

struct Point {
    Real x, y;
    constexpr Point() : Point(0, 0) {}
    constexpr Point(Real _x, Real _y) : x(_x), y(_y) {}
    constexpr Point(const pair<Real, Real> &p) : x(p.first), y(p.second) {}
    Point &operator+=(const Point &p) {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator-=(const Point &p) {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    Point &operator*=(const Real &r) {
        x *= r;
        y *= r;
        return *this;
    }
    Point &operator/=(const Real &r) {
        assert(!equal_eps(r, 0));
        x /= r;
        y /= r;
        return *this;
    }
    Point operator+(const Point &p) const { return Point(*this) += p; }
    Point operator-(const Point &p) const { return Point(*this) -= p; }
    Point operator*(const Real &r) const { return Point(*this) *= r; }
    Point operator/(const Real &r) const { return Point(*this) /= r; }
    Point operator-() const { return Point() - *this; }
    bool operator==(const Point &p) const {
        return equal_eps(x, p.x) && equal_eps(y, p.y);
    }
    bool operator!=(const Point &p) const {
        return !equal_eps(x, p.x) || !equal_eps(y, p.y);
    }
    Point rotate(Real rad) const {
        Real c = cosl(rad), s = sinl(rad);
        Real tx = x * c - y * s;
        Real ty = x * s + y * c;
        return Point(tx, ty);
    }
    Point unit() const {
        return (*this) / metric();
    }
    Real Re() const { return x; }
    Real Im() const { return y; }
    Real norm() const { return x * x + y * y; }
    Real metric() const { return sqrtl(norm()); }
    Real arg() const { return atan2l(y, x); }
    Real arg(Point q1, Point q2) const {
        q1 -= *this, q2 -= *this;
        return abs(q1.arg() - q2.arg());
    }
    friend Point operator*(Real r, const Point &p) {
        return p * r;
    }
    friend Point operator/(Real r, const Point &p) {
        return p / r;
    }
};

Real Re(const Point &p) { return p.Re(); }
Real Im(const Point &p) { return p.Im(); }
Real dot(const Point &p, const Point &q) {
    return p.x * q.x + p.y * q.y;
}
Real cross(const Point &p, const Point &q) {
    return p.x * q.y - p.y * q.x;
}
Real norm(const Point &p) {
    return p.norm();
}
Real metric(const Point &p) {
    return p.metric();
}
Real metric(const Point &p, const Point &q) {
    return metric(p - q);
}
Real arg(const Point &p) {
    return p.arg();
}

bool equal_point(const Point &p, const Point &q) {
    return equal_eps(p.x, q.x) && equal_eps(p.y, q.y);
}

constexpr Point INF_POINT = Point(INF_REAL, INF_REAL);

// a を基準にした b と c の位置関係
int ccw(const Point &a, const Point &b, const Point &c) {
    Point p = b - a, q = c - a;
    if (cross(p, q) > eps) return 1; // a, b, c の順で反時計回り
    if (cross(p, q) < -eps) return -1; // a, b, c の順で時計回り
    if (min(norm(p), norm(q)) < eps * eps) return 0; // a = c or b = c
    if (dot(p, q) < eps) return 2; // c, a, b の順で一直線
    if (norm(p) < norm(q)) return -2; // a, b, c の順で一直線
    return 0; // a, c, b の順で一直線
}

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

} // namespace geometry

namespace geometry {

struct Line {
    // Line : ax + by = c
    Real a, b, c;
    constexpr Line() = default;
    constexpr Line(Real _a, Real _b, Real _c) : a(_a), b(_b), c(_c) {}
    constexpr Line(const Point &p, const Point &q) : a(q.y - p.y), b(p.x - q.x), c(p.x * q.y - p.y * q.x) {}
    constexpr Line(Real _a, const Point &p) : a(_a), b(-1), c(_a * p.x - p.y) {}
    bool online(const Point &p) const {
        return equal_eps(a * p.x + b * p.y, c);
    }
    Real get_x(Real y) const {
        if (equal_eps(a, 0)) return INF_REAL;
        return (c - b * y) / a;
    }
    Real get_y(Real x) const {
        if (equal_eps(b, 0)) return INF_REAL;
        return (c - a * x) / b;
    }
    Line perpendicular(const Point &p) const {
        if (equal_eps(a, 0)) return Line(1, 0, p.x);
        if (equal_eps(0, b)) return Line(0, 1, p.y);
        return Line(b / a, p);
    }
    Point crossppoint(const Line &l) const {
        if (equal_eps(a * l.b, l.a * b)) return INF_POINT;
        Real d = a * l.b - l.a * b;
        return Point(l.b * c - b * l.c, l.c * a - c * l.a) / d;
    }
    Point projection(const Point &p) const {
        return crossppoint(perpendicular(p));
    }
    Point reflection(const Point &p) const {
        Point q = projection(p);
        return 2 * q - p;
    }
    Point unit() const {
        if (equal_eps(b, 0)) {
            return Point(0, 1);
        }
        Point p(0, get_y(0)), q(1, get_y(1));
        return (p - q) / metric(p - q);
    }
    bool is_orthogonal(const Line &l) const {
        return equal_eps(a * l.a + b * l.b, 0);
    }
    bool is_parallel(const Line &l) const {
        return equal_eps(a * l.b, l.a * b);
    }
    Real dist(const Point &p) const {
        Point q = projection(p);
        return metric(p - q);
    }
};

bool is_orthogonal(const Line &l1, const Line &l2) {
    return l1.is_orthogonal(l2);
}
bool is_parallel(const Line &l1, const Line &l2) {
    return l1.is_parallel(l2);
}
Point crosspoint(const Line &l1, const Line &l2) {
    return l1.crossppoint(l2);
}

} // namespace geometry

namespace geometry {

struct Segment {
    Line l;
    Point p, q;
    Segment() = default;
    Segment(const Point &_p, const Point &_q) : l(_p, _q), p(_p), q(_q) {}
    bool cross(const Segment &s) const {
        bool f1 = ccw(p, q, s.p) * ccw(p, q, s.q) <= 0;
        bool f2 = ccw(s.p, s.q, p) * ccw(s.p, s.q, q) <= 0;
        return f1 && f2;
    }
    Point crosspoint(const Segment &s) const {
        if (cross(s)) return l.crossppoint(s.l);
        return INF_POINT;
    }
    Real dist(const Point &r) const {
        if (dot(q - p, r - p) < eps) return (r - p).metric();
        if (dot(p - q, r - q) < eps) return (r - q).metric();
        return l.dist(r);
    }
    Real dist(const Segment &s) const {
        if (cross(s)) return 0;
        Real res = INF_REAL;
        res = min(res, dist(s.p));
        res = min(res, dist(s.q));
        res = min(res, s.dist(p));
        res = min(res, s.dist(q));
        return res;
    }
};

bool cross(const Segment &s, const Segment &t) {
    return s.cross(t);
}

Point crosspoint(const Segment &s, const Segment &t) {
    return s.crosspoint(t);
}

Real dist(const Segment &s, const Segment &t) {
    return s.dist(t);
}

} // nemespace geometry
using namespace geometry;

void solve() {
    Point a, b;
    cin >> a >> b;
    Segment S(a, b);
    auto get = [&] (Real t) -> Point {
        return a + t * (b - a);
    };
    auto time = [&] (const Point p) -> Real {
        Real l = 0, r = 1;
        for (int t = 0; t < 100; t++) {
            Real m = (l + r) / 2;
            auto q = get(m);
            (metric(a, q) <= metric(a, p) ? l : r) = m;
        }
        return r;
    };
    int N;
    cin >> N;
    vector<pair<Real, bool>> Ts;
    while (N--) {
        Point s, t;
        int o, l;
        cin >> s >> t >> o >> l;
        Segment T(s, t);
        auto p = S.crosspoint(T);
        if (!equal_point(p, INF_POINT)) {
            Ts.emplace_back(time(p), o ^ l);
        }
    }
    sort(Ts.begin(), Ts.end());
    int ans = 0, k = -1;
    for (auto [_, f] : Ts) {
        if (k != -1 && k != f) ans++;
        k = f;
    }
    cout << ans << '\n';
}

int main() {
    int T;
    cin >> T;
    while (T--) solve();
}
accuracy: 1
time_ms: 50
memory_kb: 3584
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;


//参考 https://github.com/saphmitchy/deliair-lib
// 型名
// R:Real, P:Point, L:Line, S:Segment, C:Circle, VP:vector<Point>

#define X(p) real(p)
#define Y(p) imag(p)

using R = ld;
using P = complex<R>;
using VP = vector<P>;

//const R EPS = 1e-9; // ここは適宜調節する,いつものやつから消す
const R pi = acos(-1.0);

int sgn(R a) {
    return (a < -EPS) ? -1 : (a > EPS) ? 1 : 0;
} // 符号関数

bool eq(R a, R b) {//実数の一致判定
    return sgn(b - a) == 0;
}

P operator*(P p, R d) {//ベクトルのd倍
    return P(X(p) * d, Y(p) * d);
}

P operator/(P p, R d) {//ベクトルの1/d倍
    return p * (1 / d);
}

istream &operator>>(istream &is, P &p) {
    // R a, b; // 入力が小数
    int a, b; // 入力が整数
    is >> a >> b;
    p = P(a, b);
    return is;
}

ostream &operator<<(ostream &os, P p) {
    return os << X(p) << ' ' << Y(p);
}

R getarg(P b,P a){//ベクトルbはベクトルaを何radian回転させる必要があるか
  assert(sgn(abs(a)) != 0);//長さが0はだめ
  return arg(b/a);
}

bool cp_x(P p, P q) {//ベクトルの比較x軸で比較->y軸で比較
    if (!eq(X(p), X(q)))
        return X(p) < X(q);
    return Y(p) < Y(q);
}

bool cp_y(P p, P q) {//ベクトルの比較y軸で比較->x軸で比較
    if (!eq(Y(p), Y(q)))
        return Y(p) < Y(q);
    return X(p) < X(q);
}

struct L {//直線ab
    P a, b;
    L() {}
    L(P a, P b) : a(a), b(b) {}

    // 入出力（必要なら）
    friend ostream &operator<<(ostream &os, L &l) {
        return os << l.a << ' ' << l.b;
    }
    friend istream &operator>>(istream &is, L &l) {
        return is >> l.a >> l.b;
    }
};

struct S : L {//線分ab
    S() {}
    S(P a, P b) : L(a, b) {}
};

struct C {//中心p 半径rの円
    P p;
    R r;
    C() {}
    C(P p, R r) : p(p), r(r) {}
};

P rot(P p, R t) {//ベクトルの回転
    return p * P(cos(t), sin(t));
}

//2つのベクトルの内積
R dot(P p, P q) {
    return X(p) * X(q) + Y(p) * Y(q);
}

//2つのベクトルの外積
R det(P p, P q) {
    return X(p) * Y(q) - Y(p) * X(q);
}

// https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=jp
int ccw(P a, P b, P c) { // 線分 ab に対する c の位置関係 
    b -= a, c -= a;//ベクトルab,ベクトルacにした
    if (sgn(det(b, c)) == 1)//外積右ねじ正
        return +1; // COUNTER_CLOCKWISE a,b,cが反時計回り
    if (sgn(det(b, c)) == -1)
        return -1; // CLOCKWISE
    if (dot(b, c) < 0.0)
        return +2; // ONLINE_BACK
    if (norm(b) < norm(c))
        return -2; // ONLINE_FRONT
    return 0;      // ON_SEGMENT
}

bool para(L a, L b) { // 平行判定
    return eq(det(a.b - a.a, b.b - b.a), 0.0);
}

bool orth(L a, L b) { // 垂直判定
    return eq(dot(a.b - a.a, b.b - b.a), 0.0);
}

P proj(L l, P p) { // 垂線の足
    R t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}

// これいる？
// P proj(S s, P p) {
//     R t = dot(p - s.a, s.b - s.a) / norm(s.b - s.a);
//     return s.a + (s.b - s.a) * t;
// }

P refl(L l, P p) { // 線対称の位置にある点
    return p + (proj(l, p) - p) * 2.0;
}

bool inter(L l, P p) { // 交点を持つか判定
    return abs(ccw(l.a, l.b, p)) != 1;
}

bool inter(S s, P p) {
    return ccw(s.a, s.b, p) == 0;
}

bool inter(L l, L m) {
    if (!eq(det(l.b - l.a, m.b - m.a), 0.0))
        return true;
    return eq(det(l.b - l.a, m.b - l.a), 0.0);
}

bool inter(L l, S s) {
    return sgn(det(l.b - l.a, s.a - l.a) * det(l.b - l.a, s.b - l.a)) <= 0;
}

bool inter(S s, L l) {
    return inter(l, s);
}

bool inter(S s, S t) {
    if (ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) > 0)
        return false;
    return ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

R dist(P p, P q) {
    return abs(q - p);
}

R dist(L l, P p) {
    return abs(p - P(proj(l, p)));
}

//R dist(S s, P p) {
//    P h = proj(s, p);
//    if (inter(s, h))
//        return abs(h - p);
//    return min(abs(s.a - p), abs(s.b - p));
//}

R dist(S s, P p) {
    P h = proj(s, p);
    if(dot(p-s.a,s.b-s.a) <= 0) return abs(s.a-p);
    if(dot(p-s.b,s.a-s.b) <= 0) return abs(s.b-p);
    return abs(p - h);
}

R dist(L l, L m) {
    return inter(l, m) ? 0.0 : dist(l, m.a);
}

R dist(S s, S t) {
    if (inter(s, t))
        return 0.0;
    return min({dist(s, t.a), dist(s, t.b), dist(t, s.a), dist(t, s.b)});
}

R dist(L l, S s) {
    if (inter(l, s))
        return 0.0;
    return min(dist(l, s.a), dist(l, s.b));
}

R dist(S s, L l) {
    return dist(l, s);
}

bool inter(C c, L l) {
    return sgn(c.r - dist(l, c.p)) >= 0;
}

bool inter(C c, P p) {
    return eq(abs(p - c.p), c.r);
}

// 共通接線の本数
// 交点なし:4
// 外接:3
// 2点で交わる:2
// 内接:1
// 一方がもう一方を内包:0
int inter(C c1, C c2) {
    if (c1.r < c2.r)
        swap(c1, c2);
    R d = abs(c1.p - c2.p);
    int a = sgn(d - c1.r - c2.r);
    if (a >= 0)
        return 3 + a;
    return 1 + sgn(d - c1.r + c2.r);
}

VP crosspoint(L l, L m) {
    VP ret;
    if (!inter(l, m))
        return ret;
    R A = det(l.b - l.a, m.b - m.a);
    R B = det(l.b - l.a, l.b - m.a);
    if (eq(A, 0.0) && eq(B, 0.0)) {
        ret.emplace_back(m.a);
    } else {
        ret.emplace_back(m.a + (m.b - m.a) * B / A);
    }
    return ret;
}

VP crosspoint(S s, S t) {
    return inter(s, t) ? crosspoint(L(s), L(t)) : VP();
}

VP crosspoint(C c, L l) {//円と直線の交点
    P h = proj(l, c.p);
    P e = (l.b - l.a) / abs(l.b - l.a);
    VP ret;
    if (!inter(c, l))
        return ret;
    if (eq(dist(l, c.p), c.r)) {
        ret.emplace_back(h);
    } else {
        R b = sqrt(c.r * c.r - norm(h - c.p));
        ret.push_back(h + e * b), ret.push_back(h - e * b);
    }
    return ret;
}

VP crosspoint(C c, S s) {//円と線分の交点
    P h = proj(s, c.p);
    P e = (s.b - s.a) / abs(s.b - s.a);
    VP ret;
    if (!inter(c, s))
        return ret;
    if (eq(dist(s, c.p), c.r)) {
        ret.emplace_back(h);
    } else {
        R b = sqrt(c.r * c.r - norm(h - c.p));
        if(ccw(s.a,s.b,h - e * b) == 0){//s.aに近い方から線分上なら追加する
          ret.push_back(h - e * b);
        }
        if(ccw(s.a,s.b,h + e * b)==0){
          ret.push_back(h + e * b);
        }
    }
    return ret;
}

VP crosspoint(C c1, C c2) {//2つの円の交わる点
    R d = abs(c1.p - c2.p);
    R a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    R t = atan2(Y(c2.p) - Y(c1.p), X(c2.p) - X(c1.p));
    VP ret;
    if (inter(c1, c2) % 4 == 0) // 交わらないとき
        return ret;
    if (eq(a, 0.0)) {
        ret.emplace_back(P(c1.p + rot(P(c1.r, 0.0), t)));
    } else {
        P p1 = c1.p + rot(P(c1.r, 0.0), t + a);
        P p2 = c1.p + rot(P(c1.r, 0.0), t - a);
        ret.emplace_back(p1), ret.emplace_back(p2);
    }
    return ret;
}

VP cut(VP p, L l, bool border = true) { // 直線が多角形に切り取られる区間
    int n = sz(p);
    p.emplace_back(p[0]), p.emplace_back(p[1]);
    VP ret;
    rep(i, n) {
        if (!eq(dist(l, p[i]), 0) && !eq(dist(l, p[i + 1]), 0)) {
            S s(p[i], p[i + 1]);
            if (eq(dist(l, s), 0)) {
                auto res = crosspoint(l, s);
                ret.emplace_back(res[0]);
            }
        }
        if (eq(dist(l, p[i + 1]), 0)) {
            if ((eq(dist(l, p[i]), 0) || eq(dist(l, p[i + 2]), 0)) && !border)
                continue;
            S s(p[i], p[i + 2]);
            if (eq(dist(l, s), 0))
                ret.emplace_back(p[i + 1]);
        }
    }
    return ret;
}

VP rectangle(S s, R r) { // sを軸とした幅rの長方形
    P d = (s.a - s.b) * P(0, 1);
    d *= r / sqrt(norm(d));
    return VP{s.a + d, s.a - d, s.b - d, s.b + d};
}

L vertical_bisector(P p, P q) { // 垂直二等分線
    L l;
    l.a = (p + q) * 0.5;
    l.b = l.a + rot(q - p, pi * 0.5);
    return l;
}

L angle_bisector(P a,P b,P c){//角abcの二等分線(角bの２等分線)
  L l;
  l.a = b;
  R ang = atan2(Y(c-b),X(c-b)) - atan2(Y(a-b),X(a-b));//なす角
  ang/=2.0;
  l.b = l.a + rot(a-b,ang);
  return l;
}

C Apollonius(P p, P q, R a, R b) { // アポロニウスの円
    P p1 = (p * b + q * a) / (a + b), p2 = (-p * b + q * a) / (a - b);
    C c;
    c.p = (p1 + p2) * 0.5;
    c.r = abs(p1 - p2) * 0.5;
    return c;
}

R area(VP p) { // 多角形の面積
    R ret = 0.0;
    int n = sz(p);
    rep(i, n) ret += det(p[i], p[(i + 1) % n]);
    return abs(ret * 0.5);
}

int in_polygon(VP p, P q) { // IN:2, ON:1, OUT:0
    int n = sz(p);
    int ret = 0;
    rep(i, n) {
        P a = p[i] - q, b = p[(i + 1) % n] - q;
        if (eq(det(a, b), 0.0) && sgn(dot(a, b)) <= 0)
            return 1;
        if (Y(a) > Y(b))
            swap(a, b);
        if (sgn(Y(a)) <= 0 && sgn(Y(b)) == 1 && sgn(det(a, b)) == 1)
            ret ^= 2;
    }
    return ret;
}

VP tangent(C c, P p) { // 点 p を通る円 c の接線と c の接点
    return crosspoint(c, C(p, sqrt(norm(p - c.p) - c.r * c.r)));
}

vector<L> tangent(C c1, C c2) { // 共通接線
    vector<L> ret;
    if (c1.r < c2.r)
        swap(c1, c2);
    R r = abs(c2.p - c1.p);
    if (eq(r, 0.0))
        return ret;
    P u = (c2.p - c1.p) / r;
    P v = rot(u, pi * 0.5);
    for (R s : {1.0, -1.0}) {
        R h = (c1.r + c2.r * s) / r;
        if (eq(abs(h), 1.0)) {
            ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
        } else if (abs(h) < 1.0) {
            P uu = u * h, vv = v * sqrt(1.0 - h * h);
            ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
            ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
        }
    }
    return ret;
}

VP convex_hull(VP p) { // 凸包
    sort(all(p), cp_x);
    p.erase(unique(all(p)), end(p));
    int n = sz(p), k = 0;
    if (n == 1)
        return p;
    VP ch(2 * n);
    for (int i = 0; i < n; ch[k++] = p[i++]) {
        while (k >= 2 && sgn(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= 0)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while (k >= t && sgn(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= 0)
            k--;
    }
    ch.resize(k - 1);
    return ch;
}

R closest_pair(VP p) { // 最近点対の距離
    if (sz(p) <= 1)
        return 1e18;
    sort(all(p), cp_x);
    VP memo(sz(p));

    function<R(int, int)> rec = [&](int l, int r) {
        if (r - l <= 1)
            return R(1e18);
        int m = (l + r) >> 1;
        R x = X(p[m]);
        R ret = min(rec(l, m), rec(m, r));
        inplace_merge(p.begin() + l, p.begin() + m, p.begin() + r, cp_y);
        int cnt = 0;
        reps(i, l, r) {
            if (abs(X(p[i]) - x) >= ret)
                continue;
            rep(j, cnt) {
                P d = p[i] - memo[cnt - j - 1];
                if (Y(d) >= ret)
                    break;
                chmin(ret, abs(d));
            }
            memo[cnt++] = p[i];
        }
        return ret;
    };

    return rec(0, sz(p));
}

R farthest_pair(VP p) {//最遠点対の距離
  VP ps = convex_hull(p);
  ll n = ps.size();
  if(n == 2){//凸包が潰れてる
    return dist(ps[0],ps[1]);
  }
  ll i = 0,j = 0;
  rep(k,n){//x軸方向に最も遠い点対を求める
    if(cp_x(ps[k],ps[i]))i = k;
    if(cp_x(ps[j],ps[k]))j = k;
  }
  R ret = 0;
  ll si = i,sj = j;
  while(i != sj || j != si){//180度反転しきるまで
    ret = max(ret,dist(ps[i],ps[j]));
    if(det(ps[(i+1)%n] - ps[i],ps[(j+1)%n]-ps[j]) < 0){
      i = (i + 1) % n;
    }else{
      j = (j + 1) % n;
    }
  }
  return ret;
}

// 原点, 点 a, 点 b とで囲まれる領域の面積 (三角形 ver と扇型 ver)
R calc_element(P a, P b, R cr,bool triangle){
  if(triangle)return det(a,b)/2;
  else{
    P tmp = b * (P(X(a),-Y(a)));
    R ang = atan2(Y(tmp),X(tmp));
    return cr * cr * ang/2;
  }
}

// 円 C と、三角形 ((0, 0), ia, ib) との共通部分の面積
R common_area(C c, P ia,P ib){
  P a = ia - c.p , b = ib - c.p;
  if(eq(abs(a-b),0))return 0;
  bool isin_a = (sgn(c.r - abs(a))>= 0);
  bool isin_b = (sgn(c.r - abs(b))>= 0);
  if(isin_a && isin_b)return calc_element(a,b,c.r,true);//aもbも円の中

  C oc(P(0,0),c.r);
  S seg(a,b);
  VP cr = crosspoint(oc,seg);
  if(cr.empty())return calc_element(a,b,c.r,false);
  P s = cr[0],t = cr.back();
  return calc_element(s,t,c.r,true) + calc_element(a,s,c.r,isin_a) + calc_element(t,b,c.r,isin_b);

}


R common_area(C c, VP vp){// 円cと多角形の共通部分の面積
  R ret = 0;
  ll n = vp.size();
  rep(i,n){
    ret += common_area(c,vp[i],vp[(i+1)%n]);
  }
  return ret;
}

R common_area(C p, C q) {// 円と円の共通部分の面積
    R d = abs(p.p - q.p);
    if (d >= p.r + q.r - EPS) return 0;
    else if (d <= abs(p.r - q.r) + EPS) return min(p.r, q.r) * min(p.r, q.r) * pi;
    R pcos = (p.r*p.r + d*d - q.r*q.r) / (p.r*d*2);
    R pang = acosl(pcos);
    R parea = p.r*p.r*pang - p.r*p.r*sin(pang*2)/2;
    R qcos = (q.r*q.r + d*d - p.r*p.r) / (q.r*d*2);
    R qang = acosl(qcos);
    R qarea = q.r*q.r*qang - q.r*q.r*sin(qang*2)/2;
    return parea + qarea;
}

vector<VP> divisions(vector<L> lf, R lim = 1e9) {
    vector<L> ls;
    each(l, lf) {
        bool ok = true;
        each(m, ls) {
            if (para(l, m) & inter(l, m.a)) {
                ok = false;
                break;
            }
        }
        if (ok)
            ls.emplace_back(l);
    }
    VP lc{P(-lim, -lim), P(lim, -lim), P(lim, lim), P(-lim, lim)};
    rep(i, 4) ls.emplace_back(lc[i], lc[(i + 1) % 4]);
    int m = sz(ls);
    VP ps;
    vector<vector<int>> lp(m);
    rep(i, m) {
        reps(j, i + 1, m) {
            each(p, crosspoint(ls[i], ls[j])) {
                if (max(abs(X(p)), abs(Y(p))) < lim + EPS) {
                    lp[i].emplace_back(sz(ps)), lp[j].emplace_back(sz(ps));
                    ps.emplace_back(p);
                }
            }
        }
    }
    int n = sz(ps);
    vector<int> id(n, -1), to;
    vector<R> rg;
    vector<vector<pair<R, int>>> li(n);
    rep(i, m) {
        sort(all(lp[i]), [&ps](int a, int b) { return cp_x(ps[a], ps[b]); });
        vector<int> q;
        rep(j, sz(lp[i])) {
            int me = id[lp[i][j]], st = j;
            auto np = ps[lp[i][j]];
            while (j + 1 < sz(lp[i])) {
                if (abs(ps[lp[i][j + 1]] - np) < EPS) {
                    j++;
                    if (id[lp[i][j]] != -1)
                        me = id[lp[i][j]];
                } else
                    break;
            }
            if (me == -1)
                me = lp[i][st];
            reps(k, st, j + 1) id[lp[i][k]] = me;
            q.emplace_back(me);
        }
        rep(i, sz(q) - 1) {
            P d = ps[q[i + 1]] - ps[q[i]];
            R s = atan2(Y(d), X(d)), t = atan2(-Y(d), -X(d));
            int x = q[i], y = q[i + 1];
            li[x].emplace_back(s, sz(to));
            li[x].emplace_back(s + pi * 2, sz(to));
            to.emplace_back(y), rg.emplace_back(t);
            li[y].emplace_back(t, sz(to));
            li[y].emplace_back(t + pi * 2, sz(to));
            to.emplace_back(x), rg.emplace_back(s);
        }
    }
    rep(i, n) sort(all(li[i]));
    vector<bool> u(sz(to), false);
    vector<VP> ret;
    rep(i, n) {
        each(l, li[i]) {
            int ns = l.second;
            if (u[ns])
                continue;
            VP nv;
            int no = ns;
            bool ok = true;
            while (1) {
                if (sz(nv) > 1) {
                    P x = nv[sz(nv) - 2], y = nv[sz(nv) - 1], z = ps[to[no]];
                    int c = ccw(x, y, z);
                    if (c == 1)
                        ok = false;
                    if (c != -1)
                        nv.pop_back();
                }
                nv.emplace_back(ps[to[no]]);
                u[no] = true;
                no = upper_bound(all(li[to[no]]), pair(rg[no] + EPS, -1))->second;
                if (no == ns)
                    break;
            }
            if (ok)
                ret.emplace_back(nv);
        }
    }
    return ret;
}

//ref https://github.com/drken1215/algorithm/blob/master/Geometry/arg_sort.cpp
//verify https://atcoder.jp/contests/abc139/submissions/me
//点列を偏角ソート
void arg_sort(VP &v){
  //原点=0,(pi,2pi] = -1  (0pi,pi] = 1
  auto sign = [&](const P &p){
    if(sgn(X(p)) == 0 && sgn(Y(p)) == 0){
      return 0;
    }else if(sgn(Y(p)) == -1 || (sgn(Y(p)) == 0 && sgn(X(p)) == 1)){
      return -1;
    }else{
      return 1;
    }
  };
  auto cp = [&](const P &p,const P &q){
    if(sign(p) != sign(q)){
      return sign(p) < sign(q);
    }else{//外積>0で判定
      //同じ向きにあるときは未定義、それぞれ決める
      return X(p) * Y(q) - Y(p) * X(q) > 0;
    }
  };
  sort(v.begin(),v.end(),cp);
}


void solve(){
  S ab;
  {
    LL(xa,ya,xb,yb);
    ab = S(P(xa,ya),P(xb,yb));
  }
  LL(n);
  vector<pair<ld,ll>> crospt;
  rep(i,n){
    LL(xs,ys,xt,yt,o,l);
    S st =S(P(xs,ys),P(xt,yt));
    VP ret = crosspoint(ab,st);
    each(p,ret){
      ld d = dist(p,ab.a);
      if(o == 1){
        //自分
        crospt.emplace_back(d,l);
      }else {
        crospt.emplace_back(d,l^1);
      }
    }
  }
  sort(all(crospt));
  ll siz  = sz(crospt);

  vvll dp(siz+1,vll(2,INF));
  dp[0][0] =0;
  dp[0][1] =0;
  rep(i,siz){
    rep(j,2)if(crospt[i].second == j){
      rep(k,2){
        if(j == k){
          chmin(dp[i+1][j],dp[i][k]);
        }else{
          chmin(dp[i+1][j],dp[i][k] + 1);
        }
      }
    }
  }
  cout << min(dp[siz][0],dp[siz][1]) << endl;

}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  LL(t);
  while(t--){
    solve();
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3712
final_rank: 3

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    using P=pair<ll,ll>;
    using T=tuple<int,int,int>;
    const int INF=1001001001;
    const ll INFL=1e18;
    const int mod=998244353;

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

	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);}

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

		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;
		}
	};
	typedef Point Vector;
	struct Segment{
		Point p1,p2;
		Segment(Point p1,Point p2):p1(p1),p2(p2){}
	};
	typedef Segment Line;
	class Circle{
	public:
		Point c;
		double r;
		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;
	}
	Point rot90(const Point& p){return Point(-p.y,p.x);}
	Point getCrossPoint(Line s1,Line s2){//２線分の交点
		Vector base=s2.p2-s2.p1;
		double d1=abs(cross(base,s1.p1-s2.p1));
		double d2=abs(cross(base,s1.p2-s2.p1));
		double t=d1/(d1+d2);
		return s1.p1+(s1.p2-s1.p1)*t;
	}
	Point intersection(Line s1,Line s2){//２直線の交点 http://www.deqnotes.net/acmicpc/2d_geometry/lines
		Vector a=s1.p2-s1.p1,b=s2.p2-s2.p1;
		return s1.p1+a*cross(b,s2.p1-s1.p1)/cross(b,a);
	}
	Point circumcenter(Point a,Point b,Point c){
		Line ab((a+b)/2,(a+b)/2+rot90(a-b));
		Line bc((b+c)/2,(b+c)/2+rot90(b-c));
		return getCrossPoint(ab,bc);
	}
	int ccw(Point p0,Point p1,Point p2){
		Vector a=p1-p0;
		Vector b=p2-p0;
		if(cross(a,b)>EPS){return 1;}
		if(cross(a,b)<-EPS){return -1;}
		if(dot(a,b)<-EPS){return 2;}
		if(a.norm()<b.norm()){return -2;}
		return 0;
	}
	double getarea(vector<Point>p){ //https://imagingsolution.net/math/calc_n_point_area/
		int n=p.size();
		double s=0;
		rep(i,n){
			s+=cross(p[i],p[(i+1)%n]);
		}
		s=abs(s);
		s/=2;
		return s;
	}
	vector<Point> ConvexCut(vector<Point>& s,Segment t){
		vector<Point>ans;
		int n=s.size();
		rep(j,n){
			Point p=s[j],q=s[(j+1)%n];
			double p_c=cross(t.p2-t.p1,p-t.p1);
			double q_c=cross(t.p2-t.p1,q-t.p1);
			Segment now=Segment(p,q);

			if(p_c+EPS>0){
				ans.push_back(p);
			}
			if(ccw(t.p1,t.p2,now.p1)*ccw(t.p1,t.p2,now.p2)==-1){
				auto e=intersection(t,now);
				ans.push_back(e);
			}
		}
		return ans;
	}

	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);
	}

    void solve(){
		Point xa,xb;
		cin>>xa.x>>xa.y>>xb.x>>xb.y;
		Segment nw(xa,xb);
		int n;
		cin>>n;
		vector<tuple<Point,int,int>>cs;
		rep(i,n){
			Point s,t;
			int o,l;
			cin>>s.x>>s.y>>t.x>>t.y>>o>>l;
			Segment v(s,t);
			if(intersect(nw,v)){
				auto cv=intersection(nw,v);
				cs.push_back(make_tuple(cv,o,l));
			}
		}
		sort(cs.begin(),cs.end());
		int ans=INF;
		rep(z,2){
			int pre=z,cnt=0;
			for(auto[v,o,l]:cs){
				if(!o){
					if(l!=pre){
						cnt++;
						pre^=1;
					}
				}else{
					if(l==pre){
						cnt++;
						pre^=1;
					}
				}
			}
			chmin(ans,cnt);
		}
		cout<<ans<<endl;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
		
		int t;
		cin>>t;
		rep(z,t){
			solve();
		}
		
        return 0;
    }
accuracy: 1
time_ms: 20
memory_kb: 3712
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;
const double EPS = 1e-9;


//определяет расположение точки (xp, yp) относительно отрезка ((x1, y1), (x2, y2))
int func(double x1, double y1, double x2, double y2, double xp, double yp) {
    double vec_pow = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1);
    double scal_pow = (x2 - x1) * (xp - x1) + (y2 - y1) * (yp - y1);
    double mod1 = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
    double mod2 = sqrt((xp - x1) * (xp - x1) + (yp - y1) * (yp - y1));

    //(xp, yp) справа от вектора {(x1, y1), (x2, y2)}
    if (vec_pow > EPS) {
        return 1;
    }

    //(xp, yp) слева от вектора {(x1, y1), (x2, y2)}
    if (vec_pow < -EPS) {
        return -1;
    }

    //тогда (xp, yp) и вектор {(x1, y1), (x2, y2)} лежат на одной прямой

    //(xp, yp) расположенна сзади точки (x1, y1)
    if (scal_pow < -EPS) {
        return 2;
    }

    //(xp, yp) расположена дальше (x2, y2)
    if (mod1 < mod2) {
        return -2;
    }

    //(xp, yp) лежит на отрезке ((x1, y1), (x2, y2))
    return 0;
}

//проверка пересекаются ли отрезки ((x1, y1), (x2, y2)) и ((x3, y3), (x4, y4))
bool is_crossed(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
    bool res = func(x1, y1, x2, y2, x3, y3) * func(x1, y1, x2, y2, x4, y4) <= 0 &&
           func(x3, y3, x4, y4, x1, y1) * func(x3, y3, x4, y4, x2, y2) <= 0;

    return res;
}

//находит точку пересечения прямых заданых двумя точками
pair<double, double> find_point(
    double x1, double y1,
    double x2, double y2,
    double x3, double y3,
    double x4, double y4) {
    pair<double, double> point;
    point.first = ((x2 - x1) * (y3 * (x4 - x3) + x3 * (y3 - y4)) - (x4 - x3) * (y1 * (x2 - x1) + x1 * (y1 - y2))) /
                  ((y2 - y1) * (x4 - x3) - (y4 - y3) * (x2 - x1));
    if (x1 == x2) {
        point.second = ((point.first - x3) * (y4 - y3) + y3 * (x4 - x3)) / (x4 - x3);
    } else {
        point.second = ((point.first - x1) * (y2 - y1) + y1 * (x2 - x1)) / (x2 - x1);
    }

    return point;
}

double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

signed main() {
    int q;
    cin >> q;
    while (q--) {
        double xa, ya, xb, yb;
        cin >> xa >> ya >> xb >> yb;
        int n;
        cin >> n;

        vector<pair<double, bool>> points;

        for (int i = 1; i <= n; i++) {
            double xs, ys, xf, yf;
            bool o, l;
            cin >> xs >> ys >> xf >> yf >> o >> l;
            if (is_crossed(xa, ya, xb, yb, xs, ys, xf, yf)) {
                pair<double, double> point = find_point(xa, ya, xb, yb, xs, ys, xf, yf);
                double distance = dist(point.first, point.second, xa, ya);
                // 1 1 -> 1
                // 1 0 -> 0
                // 0 1 -> 0
                // 0 0 -> 1
                // cout << i << " " << distance << " " << o << " " << l << " " << (o == l) << endl;
                points.push_back(make_pair(distance, o == l));
            }
        }

        if (points.size() == 0) {
            cout << 0 << endl;
            continue;
        }

        sort(points.begin(), points.end());

        int ans = 0;

        bool state = points[0].second;
        for (int i = 1; i < points.size(); i++) {
            if (state != points[i].second) {
                state = points[i].second;
                ans++;
            }
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3464
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;
const double EPS = 0.000001;


//определяет расположение точки (xp, yp) относительно отрезка ((x1, y1), (x2, y2))
int func(double x1, double y1, double x2, double y2, double xp, double yp) {
    double vec_pow = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1);
    double scal_pow = (x2 - x1) * (xp - x1) + (y2 - y1) * (yp - y1);
    double mod1 = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
    double mod2 = sqrt((xp - x1) * (xp - x1) + (yp - y1) * (yp - y1));

    //(xp, yp) справа от вектора {(x1, y1), (x2, y2)}
    if (vec_pow > EPS) {
        return 1;
    }

    //(xp, yp) слева от вектора {(x1, y1), (x2, y2)}
    if (vec_pow < -EPS) {
        return -1;
    }

    //тогда (xp, yp) и вектор {(x1, y1), (x2, y2)} лежат на одной прямой

    //(xp, yp) расположенна сзади точки (x1, y1)
    if (scal_pow < -EPS) {
        return 2;
    }

    //(xp, yp) расположена дальше (x2, y2)
    if (mod1 < mod2) {
        return -2;
    }

    //(xp, yp) лежит на отрезке ((x1, y1), (x2, y2))
    return 0;
}

//проверка пересекаются ли отрезки ((x1, y1), (x2, y2)) и ((x3, y3), (x4, y4))
bool is_crossed(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
    bool res = func(x1, y1, x2, y2, x3, y3) * func(x1, y1, x2, y2, x4, y4) <= 0 &&
           func(x3, y3, x4, y4, x1, y1) * func(x3, y3, x4, y4, x2, y2) <= 0;

    return res;
}

//находит точку пересечения прямых заданых двумя точками
pair<double, double> find_point(
    double x1, double y1,
    double x2, double y2,
    double x3, double y3,
    double x4, double y4) {
    pair<double, double> point;
    point.first = ((x2 - x1) * (y3 * (x4 - x3) + x3 * (y3 - y4)) - (x4 - x3) * (y1 * (x2 - x1) + x1 * (y1 - y2))) /
                  ((y2 - y1) * (x4 - x3) - (y4 - y3) * (x2 - x1));
    if (x1 == x2) {
        point.second = ((point.first - x3) * (y4 - y3) + y3 * (x4 - x3)) / (x4 - x3);
    } else {
        point.second = ((point.first - x1) * (y2 - y1) + y1 * (x2 - x1)) / (x2 - x1);
    }

    return point;
}

double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

signed main() {
    int q;
    cin >> q;
    while (q--) {
        double xa, ya, xb, yb;
        cin >> xa >> ya >> xb >> yb;
        int n;
        cin >> n;

        vector<pair<double, bool>> points;

        for (int i = 1; i <= n; i++) {
            double xs, ys, xf, yf;
            bool o, l;
            cin >> xs >> ys >> xf >> yf >> o >> l;
            if (is_crossed(xa, ya, xb, yb, xs, ys, xf, yf)) {
                pair<double, double> point = find_point(xa, ya, xb, yb, xs, ys, xf, yf);
                double distance = dist(point.first, point.second, xa, ya);
                // 1 1 -> 1
                // 1 0 -> 0
                // 0 1 -> 0
                // 0 0 -> 1
                // cout << i << " " << distance << " " << o << " " << l << " " << (o == l) << endl;
                points.push_back(make_pair(distance, o == l));
            }
        }

        if (points.size() == 0) {
            cout << 0 << endl;
            continue;
        }

        sort(points.begin(), points.end());
        // cout << points.size() << endl;
        // for (int i = 0; i < points.size(); i++) {
        //     cout << points[i].first << ' ' << points[i].second << endl;
        // }
        int ans = 0;

        bool state = points[0].second;
        for (int i = 1; i < points.size(); i++) {
            if (state != points[i].second) {
                state = points[i].second;
                ans++;
            }
        }
        cout << ans << endl;
    }
}

// 1
// 0 0 2 2
// 2
// 0 1 1 0 1 1
// 0 2 2 0 0 1
//
// 1
// -10 1 10 1
// 4
// -6 2 -2 -2 0 1
// -6 -2 -2 2 1 0
// 6 2 2 -2 0 0
// 6 -2 2 2 1 1
accuracy: 1
time_ms: 50
memory_kb: 3416
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;
const double EPS = 0.000001;

struct PointData {
    bool is_underground;
    double distance;

    PointData(double arg_distance, bool arg_is_underground) {
        distance = arg_distance;
        is_underground = arg_is_underground;
    }

    bool operator<(const PointData &other) const {
        return distance > other.distance;
    }
};

//определяет расположение точки (xp, yp) относительно отрезка ((x1, y1), (x2, y2))
int func(double x1, double y1, double x2, double y2, double xp, double yp) {
    double vec_pow = (x2 - x1) * (yp - y1) - (xp - x1) * (y2 - y1);
    double scal_pow = (x2 - x1) * (xp - x1) + (y2 - y1) * (yp - y1);
    double mod1 = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
    double mod2 = sqrt((xp - x1) * (xp - x1) + (yp - y1) * (yp - y1));

    //(xp, yp) справа от вектора {(x1, y1), (x2, y2)}
    if (vec_pow > EPS) {
        return 1;
    }

    //(xp, yp) слева от вектора {(x1, y1), (x2, y2)}
    if (vec_pow < -EPS) {
        return -1;
    }

    //тогда (xp, yp) и вектор {(x1, y1), (x2, y2)} лежат на одной прямой

    //(xp, yp) расположенна сзади точки (x1, y1)
    if (scal_pow < -EPS) {
        return 2;
    }

    //(xp, yp) расположена дальше (x2, y2)
    if (mod1 < mod2) {
        return -2;
    }

    //(xp, yp) лежит на отрезке ((x1, y1), (x2, y2))
    return 0;
}

//проверка пересекаются ли отрезки ((x1, y1), (x2, y2)) и ((x3, y3), (x4, y4))
bool is_crossed(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
    bool res = func(x1, y1, x2, y2, x3, y3) * func(x1, y1, x2, y2, x4, y4) <= 0 &&
           func(x3, y3, x4, y4, x1, y1) * func(x3, y3, x4, y4, x2, y2) <= 0;

    return res;
}

//находит точку пересечения прямых заданых двумя точками
pair<double, double> find_point(
    double x1, double y1,
    double x2, double y2,
    double x3, double y3,
    double x4, double y4) {
    pair<double, double> point;
    point.first = ((x2 - x1) * (y3 * (x4 - x3) + x3 * (y3 - y4)) - (x4 - x3) * (y1 * (x2 - x1) + x1 * (y1 - y2))) /
                  ((y2 - y1) * (x4 - x3) - (y4 - y3) * (x2 - x1));
    if (x1 == x2) {
        point.second = ((point.first - x3) * (y4 - y3) + y3 * (x4 - x3)) / (x4 - x3);
    } else {
        point.second = ((point.first - x1) * (y2 - y1) + y1 * (x2 - x1)) / (x2 - x1);
    }

    return point;
}

double dist(double x1, double y1, double x2, double y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

signed main() {
    int q;
    cin >> q;
    while (q--) {
        double xa, ya, xb, yb;
        cin >> xa >> ya >> xb >> yb;
        int n;
        cin >> n;

        priority_queue<PointData> points;

        for (int i = 1; i <= n; i++) {
            double xs, ys, xf, yf;
            bool o, l;
            cin >> xs >> ys >> xf >> yf >> o >> l;
            if (is_crossed(xa, ya, xb, yb, xs, ys, xf, yf)) {
                pair<double, double> point = find_point(xa, ya, xb, yb, xs, ys, xf, yf);
                double distance = dist(point.first, point.second, xa, ya);
                // 1 1 -> 1
                // 1 0 -> 0
                // 0 1 -> 0
                // 0 0 -> 1
                // cout << i << " " << distance << " " << o << " " << l << " " << (o == l) << endl;
                points.push(PointData(distance, !(o == l)));
            }
        }

        if (points.empty()) {
            cout << 0 << endl;
            continue;
        }

        int ans = 0;

        bool state = points.top().is_underground;
        while (!points.empty()) {
            if (state != points.top().is_underground) {
                state = points.top().is_underground;
                ans++;
            }
            points.pop();
        }
        cout << ans << endl;
    }
}

// 1
// 0 0 2 2
// 2
// 0 1 1 0 1 1
// 0 2 2 0 0 1
//
// 1
// -10 1 10 1
// 4
// -6 2 -2 -2 0 1
// -6 -2 -2 2 1 0
// 6 2 2 -2 0 0
// 6 -2 2 2 1 1
accuracy: 1
time_ms: 50
memory_kb: 3448
final_rank: 13

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

struct Info{
	double x,y;
};

struct Data{
	Data(double arg_distance,bool arg_is_under_ground){
		distance = arg_distance;
		is_under_ground = arg_is_under_ground;
	}
	bool operator<(const struct Data &arg) const{
		return distance > arg.distance;
	};

	double distance;
	bool is_under_ground;
};


int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}

Info calc(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){
	Info ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(x1 != x2){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

double calc_dist(double x1,double y1,double x2,double y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

void func(){

	double start_x,start_y,goal_x,goal_y;
	scanf("%lf %lf %lf %lf",&start_x,&start_y,&goal_x,&goal_y);

	int N;
	scanf("%d",&N);

	priority_queue<Data> Q;

	double x1,y1,x2,y2;
	int Owner,L;

	Info ret;
	double tmp_dist;

	for(int loop = 0; loop < N; loop++){
		scanf("%lf %lf %lf %lf %d %d",&x1,&y1,&x2,&y2,&Owner,&L);

		if(func(x1,y1,x2,y2,start_x,start_y)*func(x1,y1,x2,y2,goal_x,goal_y) <= 0 &&
				func(start_x,start_y,goal_x,goal_y,x1,y1) * func(start_x,start_y,goal_x,goal_y,x2,y2) <= 0){
			ret = calc(start_x,start_y,goal_x,goal_y,x1,y1,x2,y2);
			tmp_dist = calc_dist(start_x,start_y,ret.x,ret.y);
			if(Owner == 1){
				if(L == 1){
					Q.push(Data(tmp_dist,false));
				}else{
					Q.push(Data(tmp_dist,true));
				}
			}else{
				if(L == 1){
					Q.push(Data(tmp_dist,true));
				}else{
					Q.push(Data(tmp_dist,false));
				}
			}
		}
	}

	if(Q.empty()){
		printf("0\n");
		return;
	}

	bool under_ground = Q.top().is_under_ground;
	Q.pop();

	int ans = 0;

	while(!Q.empty()){
		if(under_ground == Q.top().is_under_ground){
			//Do nothing
		}else{
			ans++;
			under_ground = Q.top().is_under_ground;
		}
		Q.pop();
	}
	printf("%d\n",ans);
}

int main(){

	int num;
	scanf("%d",&num);

	for(int i = 0; i < num; i++)func();

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 2920
final_rank: 1

code_snippet: #include <iostream>
#include <complex>
#include <vector>
#include <algorithm>

using namespace std;

double det(const complex<double> &a, const complex<double> &b) {
    return (conj(b) * a).imag();
}

double ratio(complex<double> s1, complex<double> d1, complex<double> s2, complex<double> d2) {
    return det(s2 - s1, d2) / det(d1, d2);
}

int main() {
    int c;
    cin >> c;
    while (c--) {
        int xa, ya, xb, yb, m, o, l;
        cin >> xa >> ya >> xb >> yb >> m;
        complex<double> a(xa, ya), b(xb, yb);
        vector<pair<double, int>> cross;
        for (int i = 0; i < m; i++) {
            cin >> xa >> ya >> xb >> yb >> o >> l;
            complex<double> c(xa, ya), d(xb, yb);
            double s = ratio(a, b - a, c, d - c), t = ratio(c, d - c, a, b - a);
            if (0 < s && s < 1 && 0 < t && t < 1) cross.push_back(make_pair(s, o ^ l));
        }
        sort(cross.begin(), cross.end());
        int ans = 0;
        int n = cross.size();
        if (n > 1) {
            for (int i = 0; i < n - 1; i++)
                if (cross[i].second != cross[i + 1].second) ans++;
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3324
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

using T = double;
const T eps = 1e-12;
using Point = complex<T>;
using Poly = vector<Point>;
#define X real()
#define Y imag()
template <typename T> inline bool eq(const T &a, const T &b) {
    return fabs(a - b) < eps;
}
bool cmp(const Point &a, const Point &b) {
    auto sub = [&](Point a) {
        return (a.Y < 0 ? -1 : (a.Y == 0 && a.X >= 0 ? 0 : 1));
    };
    if (sub(a) != sub(b))
        return sub(a) < sub(b);
    return a.Y * b.X < a.X * b.Y;
}
struct Line {
    Point a, b, dir;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b), dir(b - a) {}
    Line(T A, T B, T C) {
        if (eq(A, .0)) {
            a = Point(0, C / B), b = Point(1 / C / B);
        } else if (eq(B, .0)) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
struct Circle {
    Point p;
    T r;
    Circle() {}
    Circle(Point _p, T _r) : p(_p), r(_r) {}
};

istream &operator>>(istream &is, Point &p) {
    T x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}
ostream &operator<<(ostream &os, Point &p) {
    os << fixed << setprecision(12) << p.X << ' ' << p.Y;
    return os;
}
Point unit(const Point &a) {
    return a / abs(a);
}
T dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
T cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
Point rot(const Point &a, const T &theta) {
    return Point(cos(theta) * a.X - sin(theta) * a.Y,
                 sin(theta) * a.X + cos(theta) * a.Y);
}
Point rot90(const Point &a) {
    return Point(-a.Y, a.X);
}
T arg(const Point &a, const Point &b, const Point &c) {
    double ret = acos(dot(a - b, c - b) / abs(a - b) / abs(c - b));
    if (cross(a - b, c - b) < 0)
        ret = -ret;
    return ret;
}

Point Projection(const Line &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Projection(const Segment &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Reflection(const Line &l, const Point &p) {
    return p + (Projection(l, p) - p) * 2.;
}
int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps)
        return 1; // ccw

    if (cross(b, c) < -eps)
        return -1; // cw

    if (dot(b, c) < 0)
        return 2; // c,a,b

    if (norm(b) < norm(c))
        return -2; // a,b,c

    return 0;      // a,c,b

}
bool isOrthogonal(const Line &a, const Line &b) {
    return eq(dot(a.b - a.a, b.b - b.a), .0);
}
bool isParallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), .0);
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
int isIntersect(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d > a.r + b.r + eps)
        return 4;
    if (eq(d, a.r + b.r))
        return 3;
    if (eq(d, abs(a.r - b.r)))
        return 1;
    if (d < abs(a.r - b.r) - eps)
        return 0;
    return 2;
}
T Dist(const Line &a, const Point &b) {
    Point c = Projection(a, b);
    return abs(c - b);
}
T Dist(const Segment &a, const Point &b) {
    if (dot(a.b - a.a, b - a.a) < eps)
        return abs(b - a.a);
    if (dot(a.a - a.b, b - a.b) < eps)
        return abs(b - a.b);
    return abs(cross(a.b - a.a, b - a.a)) / abs(a.b - a.a);
}
T Dist(const Segment &a, const Segment &b) {
    if (isIntersect(a, b))
        return .0;
    T res = min({Dist(a, b.a), Dist(a, b.b), Dist(b, a.a), Dist(b, a.b)});
    return res;
}
Point Intersection(const Line &a, const Line &b) {
    T d1 = cross(a.b - a.a, b.b - b.a);
    T d2 = cross(a.b - a.a, a.b - b.a);
    if (eq(d1, 0.) and eq(d2, 0.))
        return b.a;
    return b.a + (b.b - b.a) * (d2 / d1);
}
Poly Intersection(const Circle &a, const Line &b) {
    Poly res;
    T d = Dist(b, a.p);
    if (d > a.r + eps)
        return res;
    Point h = Projection(b, a.p);
    if (eq(d, a.r)) {
        res.push_back(h);
        return res;
    }
    Point e = unit(b.b - b.a);
    T ph = sqrt(a.r * a.r - d * d);
    res.push_back(h - e * ph);
    res.push_back(h + e * ph);
    return res;
}
Poly Intersection(const Circle &a, const Segment &b) {
    Line c(b.a, b.b);
    Poly sub = Intersection(a, c);
    double xmi = min(b.a.X, b.b.X), xma = max(b.a.X, b.b.X);
    double ymi = min(b.a.Y, b.b.Y), yma = max(b.a.Y, b.b.Y);
    Poly res;
    rep(i, 0, sub.size()) {
        if (xmi <= sub[i].X + eps and sub[i].X - eps <= xma and
            ymi <= sub[i].Y + eps and sub[i].Y - eps <= yma) {
            res.push_back(sub[i]);
        }
    }
    return res;
}
Poly Intersection(const Circle &a, const Circle &b) {
    Poly res;
    int mode = isIntersect(a, b);
    T d = abs(a.p - b.p);
    if (mode == 4 or mode == 0)
        return res;
    if (mode == 3) {
        T t = a.r / (a.r + b.r);
        res.push_back(a.p + (b.p - a.p) * t);
        return res;
    }
    if (mode == 1) {
        if (b.r < a.r - eps) {
            res.push_back(a.p + (b.p - a.p) * (a.r / d));
        } else {
            res.push_back(b.p + (a.p - b.p) * (b.r / d));
        }
        return res;
    }
    T rc = (a.r * a.r + d * d - b.r * b.r) / d / 2.;
    T rs = sqrt(a.r * a.r - rc * rc);
    if (a.r - abs(rc) < eps)
        rs = 0;
    Point e = unit(b.p - a.p);
    res.push_back(a.p + rc * e + rs * e * Point(0, 1));
    res.push_back(a.p + rc * e + rs * e * Point(0, -1));
    return res;
}
Poly HalfplaneIntersection(vector<Line> &H) {
    sort(ALL(H), [&](Line &l1, Line &l2) { return cmp(l1.dir, l2.dir); });
    auto outside = [&](Line &L, Point p) -> bool {
        return cross(L.dir, p - L.a) < -eps;
    };
    deque<Line> deq;
    int sz = 0;
    rep(i, 0, SZ(H)) {
        while (sz > 1 and
               outside(H[i], Intersection(deq[sz - 1], deq[sz - 2]))) {
            deq.pop_back();
            sz--;
        }
        while (sz > 1 and outside(H[i], Intersection(deq[0], deq[1]))) {
            deq.pop_front();
            sz--;
        }
        if (sz > 0 and fabs(cross(H[i].dir, deq[sz - 1].dir)) < eps) {
            if (dot(H[i].dir, deq[sz - 1].dir) < 0) {
                return {};
            }
            if (outside(H[i], deq[sz - 1].a)) {
                deq.pop_back();
                sz--;
            } else
                continue;
        }
        deq.push_back(H[i]);
        sz++;
    }

    while (sz > 2 and outside(deq[0], Intersection(deq[sz - 1], deq[sz - 2]))) {
        deq.pop_back();
        sz--;
    }
    while (sz > 2 and outside(deq[sz - 1], Intersection(deq[0], deq[1]))) {
        deq.pop_front();
        sz--;
    }
    if (sz < 3)
        return {};
    deq.push_back(deq.front());
    Poly ret;
    rep(i, 0, sz) ret.push_back(Intersection(deq[i], deq[i + 1]));
    return ret;
}

T Area(const Poly &a) {
    T res = 0;
    int n = a.size();
    rep(i, 0, n) res += cross(a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Poly &a, const Circle &b) {
    int n = a.size();
    if (n < 3)
        return .0;
    auto rec = [&](auto self, const Circle &c, const Point &p1,
                   const Point &p2) {
        Point va = c.p - p1, vb = c.p - p2;
        T f = cross(va, vb), res = .0;
        if (eq(f, .0))
            return res;
        if (max(abs(va), abs(vb)) < c.r + eps)
            return f;
        if (Dist(Segment(p1, p2), c.p) > c.r - eps)
            return c.r * c.r * arg(vb * conj(va));
        auto u = Intersection(c, Segment(p1, p2));
        Poly sub;
        sub.push_back(p1);
        for (auto &x : u)
            sub.push_back(x);
        sub.push_back(p2);
        rep(i, 0, sub.size() - 1) res += self(self, c, sub[i], sub[i + 1]);
        return res;
    };
    T res = .0;
    rep(i, 0, n) res += rec(rec, b, a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d >= a.r + b.r - eps)
        return .0;
    if (d <= abs(a.r - b.r) + eps) {
        T r = min(a.r, b.r);
        return M_PI * r * r;
    }
    T ath = acos((a.r * a.r + d * d - b.r * b.r) / d / a.r / 2.);
    T res = a.r * a.r * (ath - sin(ath * 2) / 2.);
    T bth = acos((b.r * b.r + d * d - a.r * a.r) / d / b.r / 2.);
    res += b.r * b.r * (bth - sin(bth * 2) / 2.);
    return fabs(res);
}
bool isConvex(const Poly &a) {
    int n = a.size();
    int cur, pre, nxt;
    rep(i, 0, n) {
        pre = (i - 1 + n) % n;
        nxt = (i + 1) % n;
        cur = i;
        if (ccw(a[pre], a[cur], a[nxt]) == -1)
            return 0;
    }
    return 1;
}
int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain

    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y < eps and eps < q.Y and cross(p, q) > eps)
            res ^= 1;
        if (eq(cross(p, q), .0) and dot(p, q) < eps)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (eq(p.Y, q.Y) ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    res.resize(k - 1);
    return res;
}
T Diam(const Poly &a) {
    int n = a.size();
    int x = 0, y = 0;
    rep(i, 1, n) {
        if (a[i].Y > a[x].Y)
            x = i;
        if (a[i].Y < a[y].Y)
            y = i;
    }
    T res = abs(a[x] - a[y]);
    int i = x, j = y;
    do {
        if (cross(a[(i + 1) % n] - a[i], a[(j + 1) % n] - a[j]) < 0)
            i = (i + 1) % n;
        else
            j = (j + 1) % n;
        chmax(res, abs(a[i] - a[j]));
    } while (i != x or j != y);
    return res;
}
Poly Cut(const Poly &a, const Line &l) {
    int n = a.size();
    Poly res;
    rep(i, 0, n) {
        Point p = a[i], q = a[(i + 1) % n];
        if (ccw(l.a, l.b, p) != -1)
            res.push_back(p);
        if (ccw(l.a, l.b, p) * ccw(l.a, l.b, q) < 0)
            res.push_back(Intersection(Line(p, q), l));
    }
    return res;
}

T Closest(Poly &a) {
    int n = a.size();
    if (n <= 1)
        return 0;
    sort(ALL(a), [&](Point a, Point b) {
        return (eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X);
    });
    Poly buf(n);
    auto rec = [&](auto self, int lb, int rb) -> T {
        if (rb - lb <= 1)
            return (T)INF;
        int mid = (lb + rb) >> 1;
        auto x = a[mid].X;
        T res = min(self(self, lb, mid), self(self, mid, rb));
        inplace_merge(a.begin() + lb, a.begin() + mid, a.begin() + rb,
                      [&](auto p, auto q) { return p.Y < q.Y; });
        int ptr = 0;
        rep(i, lb, rb) {
            if (abs(a[i].X - x) >= res)
                continue;
            rep(j, 0, ptr) {
                auto sub = a[i] - buf[ptr - 1 - j];
                if (sub.Y >= res)
                    break;
                chmin(res, abs(sub));
            }
            buf[ptr++] = a[i];
        }
        return res;
    };
    return rec(rec, 0, n);
}

Circle Incircle(const Point &a, const Point &b, const Point &c) {
    T A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point p(A * a.X + B * b.X + C * c.X, A * a.Y + B * b.Y + C * c.Y);
    p /= (A + B + C);
    T r = Dist(Line(a, b), p);
    return Circle(p, r);
}
Circle Circumcircle(const Point &a, const Point &b, const Point &c) {
    Line l1((a + b) / 2., (a + b) / 2. + (b - a) * Point(0, 1));
    Line l2((b + c) / 2., (b + c) / 2. + (c - b) * Point(0, 1));
    Point p = Intersection(l1, l2);
    return Circle(p, abs(p - a));
}
Poly tangent(const Point &a, const Circle &b) {
    return Intersection(b, Circle(a, sqrt(norm(b.p - a) - b.r * b.r)));
}
vector<Line> tangent(const Circle &a, const Circle &b) {
    vector<Line> res;
    T d = abs(a.p - b.p);
    if (eq(d, 0.))
        return res;
    Point u = unit(b.p - a.p);
    Point v = u * Point(0, 1);
    for (int t : {-1, 1}) {
        T h = (a.r + b.r * t) / d;
        if (eq(h * h, 1.)) {
            res.push_back(Line(a.p + (h > 0 ? u : -u) * a.r,
                               a.p + (h > 0 ? u : -u) * a.r + v));
        } else if (1 > h * h) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.push_back(Line(a.p + (U + V) * a.r, b.p - (U + V) * (b.r * t)));
            res.push_back(Line(a.p + (U - V) * a.r, b.p - (U - V) * (b.r * t)));
        }
    }
    return res;
}

/**
 * @brief Geometry
 */

int main() {
int _;
cin >> _;
while(_--) {
    double xa, ya, xb, yb;
    cin >> xa >> ya >> xb >> yb;
    Point pa(xa,ya), pb(xb,yb);
    Segment S(pa,pb);
    vector<pair<double,int>> V;
    int N;
    cin >> N;
    rep(i,0,N) {
        double x1, y1, x2, y2;
        int O, L;
        cin >> x1 >> y1 >> x2 >> y2 >> O >> L;
        int A = (O+L)%2;
        Point p1(x1,y1), p2(x2,y2);
        Segment T(p1,p2);
        if (isIntersect(S,T)) {
            Point P = Intersection(S,T);
            V.push_back(pair<double,int>{abs(pa-P), A});
        }
    }
    sort(ALL(V));
    int ANS = 0;
    for (int i = 0; i + 1 < (int)(V.size()); i++) {
        if (V[i].second != V[i+1].second) ANS++;
    }
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 50
memory_kb: 3484
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9 + 10;
const ll INFL = 4e18;

const long double EPS = 1e-9;

bool almostEqual(long double a, long double b) { return std::abs(a - b) < EPS; }

bool lessThan(long double a, long double b) {
    return a < b && !almostEqual(a, b);
}

bool greaterThan(long double a, long double b) {
    return a > b && !almostEqual(a, b);
}

bool lessThanOrEqual(long double a, long double b) {
    return a < b || almostEqual(a, b);
}

bool greaterThanOrEqual(long double a, long double b) {
    return a > b || almostEqual(a, b);
}

struct Point {
    long double x, y;

    Point() = default;
    Point(long double x, long double y) : x(x), y(y) {}

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

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

    Point operator*(long double k) const { return Point(x * k, y * k); }

    Point operator/(long double k) const { return Point(x / k, y / k); }

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

    long double cross(const Point &p) const { return x * p.y - y * p.x; }

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

    long double norm() const { return x * x + y * y; }

    long double abs() const { return std::sqrt(norm()); }

    long double arg() const { return atan2(y, x); }

    bool operator==(const Point &p) const {
        return almostEqual(x, p.x) && almostEqual(y, p.y);
    }

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

struct Line {
    Point a, b;

    Line() = default;
    Line(const Point &_a, const Point &_b) : a(_a), b(_b) {}
    Line(const long double &A, const long double &B, const long double &C) {
        if (almostEqual(A, 0)) {
            assert(!almostEqual(B, 0));
            a = Point(0, C / B);
            b = Point(1, C / B);
        } else if (almostEqual(B, 0)) {
            a = Point(C / A, 0);
            b = Point(C / A, 1);
        } else if (almostEqual(C, 0)) {
            a = Point(0, C / B);
            b = Point(1, (C - A) / B);
        } else {
            a = Point(0, C / B);
            b = Point(C / A, 0);
        }
    }

    bool operator==(const Line &l) const { return a == l.a && b == l.b; }

    friend istream &operator>>(istream &is, Line &l) {
        return is >> l.a >> l.b;
    }
};

struct Segment : Line {
    Segment() = default;
    using Line::Line;
};

struct Circle {
    Point center;
    long double r;
    Circle() = default;
    Circle(long double x, long double y, long double r) : center(x, y), r(r) {}
    Circle(Point _center, long double r) : center(_center), r(r) {}

    bool operator==(const Circle &C) const {
        return center == C.center && r == C.r;
    }

    friend istream &operator>>(istream &is, Circle &C) {
        return is >> C.center >> C.r;
    }
};

enum Orientation {
    COUNTER_CLOCKWISE,
    CLOCKWISE,
    ONLINE_BACK,
    ONLINE_FRONT,
    ON_SEGMENT
};

Orientation ccw(const Point &p0, const Point &p1, const Point &p2) {
    Point a = p1 - p0;
    Point b = p2 - p0;
    long double cross_product = a.cross(b);

    if (greaterThan(cross_product, 0))
        return COUNTER_CLOCKWISE;
    if (lessThan(cross_product, 0))
        return CLOCKWISE;
    if (lessThan(a.dot(b), 0))
        return ONLINE_BACK;
    if (lessThan(a.norm(), b.norm()))
        return ONLINE_FRONT;
    return ON_SEGMENT;
}

std::string orientationToString(Orientation o) {
    switch (o) {
        case COUNTER_CLOCKWISE:
            return "COUNTER_CLOCKWISE";
        case CLOCKWISE:
            return "CLOCKWISE";
        case ONLINE_BACK:
            return "ONLINE_BACK";
        case ONLINE_FRONT:
            return "ONLINE_FRONT";
        case ON_SEGMENT:
            return "ON_SEGMENT";
        default:
            return "UNKNOWN";
    }
}

Point projection(const Point &p1, const Point &p2, const Point &p) {
    Point base = p2 - p1;
    long double r = (p - p1).dot(base) / base.norm();
    return p1 + base * r;
}

Point projection(const Line &l, const Point &p) {
    Point base = l.b - l.a;
    long double r = (p - l.a).dot(base) / base.norm();
    return l.a + base * r;
}

Point reflection(const Point &p1, const Point &p2, const Point &p) {
    Point proj = projection(p1, p2, p);
    return proj * 2 - p;
}

Point reflection(const Line &l, const Point &p) {
    Point proj = projection(l, p);
    return proj * 2 - p;
}

bool isParallel(const Line &l1, const Line &l2) {
    return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0);
}

bool isOrthogonal(const Line &l1, const Line &l2) {
    return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0);
}

bool isParallel(const Segment &l1, const Segment &l2) {
    return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0);
}

bool isOrthogonal(const Segment &l1, const Segment &l2) {
    return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0);
}

bool isParallel(const Line &l1, const Segment &l2) {
    return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0);
}

bool isOrthogonal(const Line &l1, const Segment &l2) {
    return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0);
}

bool isParallel(const Segment &l1, const Line &l2) {
    return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0);
}

bool isOrthogonal(const Segment &l1, const Line &l2) {
    return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0);
}

bool isPointOnLine(const Point &p, const Line &l) {
    return almostEqual((l.b - l.a).cross(p - l.a), 0.0);
}

bool isPointOnSegment(const Point &p, const Segment &s) {
    return lessThanOrEqual(std::min(s.a.x, s.b.x), p.x) &&
           lessThanOrEqual(p.x, std::max(s.a.x, s.b.x)) &&
           lessThanOrEqual(std::min(s.a.y, s.b.y), p.y) &&
           lessThanOrEqual(p.y, std::max(s.a.y, s.b.y)) &&
           almostEqual((s.b - s.a).cross(p - s.a), 0.0);
}

bool isIntersecting(const Segment &s1, const Segment &s2) {
    Point p0p1 = s1.b - s1.a;
    Point p0p2 = s2.a - s1.a;
    Point p0p3 = s2.b - s1.a;
    Point p2p3 = s2.b - s2.a;
    Point p2p0 = s1.a - s2.a;
    Point p2p1 = s1.b - s2.a;

    long double d1 = p0p1.cross(p0p2);
    long double d2 = p0p1.cross(p0p3);
    long double d3 = p2p3.cross(p2p0);
    long double d4 = p2p3.cross(p2p1);

    if (lessThan(d1 * d2, 0) && lessThan(d3 * d4, 0)) {
        return true;
    }

    if (almostEqual(d1, 0.0) && isPointOnSegment(s2.a, s1))
        return true;
    if (almostEqual(d2, 0.0) && isPointOnSegment(s2.b, s1))
        return true;
    if (almostEqual(d3, 0.0) && isPointOnSegment(s1.a, s2))
        return true;
    if (almostEqual(d4, 0.0) && isPointOnSegment(s1.b, s2))
        return true;

    return false;
}

Point getIntersection(const Segment &s1, const Segment &s2) {
    assert(isIntersecting(s1, s2));
    auto cross = [](Point p, Point q) { return p.x * q.y - p.y * q.x; };

    Point base = s2.b - s2.a;
    long double d1 = std::abs(cross(base, s1.a - s2.a));
    long double d2 = std::abs(cross(base, s1.b - s2.a));
    long double t = d1 / (d1 + d2);

    return s1.a + (s1.b - s1.a) * t;
}

long double distancePointToSegment(const Point &p, const Segment &s) {
    Point proj = projection(s.a, s.b, p);
    if (isPointOnSegment(proj, s)) {
        return (p - proj).abs();
    } else {
        return std::min((p - s.a).abs(), (p - s.b).abs());
    }
}

long double distanceSegmentToSegment(const Segment &s1, const Segment &s2) {
    if (isIntersecting(s1, s2)) {
        return 0.0;
    }
    return std::min(
        {distancePointToSegment(s1.a, s2), distancePointToSegment(s1.b, s2),
         distancePointToSegment(s2.a, s1), distancePointToSegment(s2.b, s1)});
}

long double getPolygonArea(const vector<Point> &points) {
    int n = points.size();
    long double area = 0.0;
    for (int i = 0; i < n; ++i) {
        int j = (i + 1) % n;
        area += points[i].x * points[j].y;
        area -= points[i].y * points[j].x;
    }
    return std::abs(area) / 2.0;
}

bool isConvex(const vector<Point> &points) {
    int n = points.size();
    bool has_positive = false, has_negative = false;
    for (int i = 0; i < n; ++i) {
        int j = (i + 1) % n;
        int k = (i + 2) % n;
        Point a = points[j] - points[i];
        Point b = points[k] - points[j];
        long double cross_product = a.cross(b);
        if (greaterThan(cross_product, 0))
            has_positive = true;
        if (lessThan(cross_product, 0))
            has_negative = true;
    }
    return !(has_positive && has_negative);
}

bool isPointOnPolygon(const vector<Point> &polygon, const Point &p) {
    int n = polygon.size();
    for (int i = 0; i < n; ++i) {
        Point a = polygon[i];
        Point b = polygon[(i + 1) % n];
        Segment s(a, b);
        if (isPointOnSegment(p, s)) {
            return true;
        }
    }
    return false;
}

bool isPointInsidePolygon(const vector<Point> &polygon, const Point &p) {
    int n = polygon.size();
    bool inPolygon = false;
    for (int i = 0; i < n; ++i) {
        Point a = polygon[i];
        Point b = polygon[(i + 1) % n];
        if (greaterThan(a.y, b.y))
            swap(a, b);
        if (lessThanOrEqual(a.y, p.y) && lessThan(p.y, b.y) &&
            greaterThan((b - a).cross(p - a), 0)) {
            inPolygon = !inPolygon;
        }
    }
    return inPolygon;
}

vector<Point> convexHull(vector<Point> &points,
                         bool include_collinear = false) {
    int n = points.size();
    if (n <= 1)
        return points;

    sort(points.begin(), points.end(),
         [](const Point &l, const Point &r) -> bool {
             if (almostEqual(l.y, r.y)) {
                 return lessThan(l.x, r.x);
             }
             return lessThan(l.y, r.y);
         });
    if (n == 2)
        return points;

    vector<Point> upper = {points[0], points[1]},
                  lower = {points[0], points[1]};
    for (int i = 2; i < n; ++i) {
        while ((int)upper.size() >= 2 &&
               ccw(upper.end()[-2], upper.end()[-1], points[i]) != CLOCKWISE) {
            if (ccw(upper.end()[-2], upper.end()[-1], points[i]) ==
                    ONLINE_FRONT &&
                include_collinear)
                break;
            upper.pop_back();
        }
        upper.push_back(points[i]);
        while ((int)lower.size() >= 2 && ccw(lower.end()[-2], lower.end()[-1],
                                             points[i]) != COUNTER_CLOCKWISE) {
            if (ccw(lower.end()[-2], lower.end()[-1], points[i]) ==
                    ONLINE_FRONT &&
                include_collinear)
                break;
            lower.pop_back();
        }
        lower.push_back(points[i]);
    }
    reverse(upper.begin(), upper.end());
    upper.pop_back();
    lower.pop_back();
    lower.insert(lower.end(), upper.begin(), upper.end());
    return lower;
}

long double convexHullDiameter(const vector<Point> &hull) {
    int n = hull.size();
    if (n == 1)
        return 0;

    int k = 1;
    long double max_dist = 0;

    for (int i = 0; i < n; ++i) {
        while (true) {
            int j = (k + 1) % n;
            Point dist1 = hull[i] - hull[j], dist2 = hull[i] - hull[k];
            max_dist = max(max_dist, dist1.abs());
            max_dist = max(max_dist, dist2.abs());
            if (dist1.abs() > dist2.abs()) {
                k = j;
            } else {
                break;
            }
        }
        Point dist = hull[i] - hull[k];
        max_dist = max(max_dist, dist.abs());
    }

    return max_dist;
}

vector<Point> cutPolygon(const vector<Point> &g, const Line &l) {
    auto isLeft = [](const Point &p1, const Point &p2, const Point &p) -> bool {
        return (p2 - p1).cross(p - p1) > 0;
    };
    vector<Point> newPolygon;
    int n = g.size();
    for (int i = 0; i < n; ++i) {
        const Point &cur = g[i];
        const Point &next = g[(i + 1) % n];
        if (isLeft(l.a, l.b, cur)) {
            newPolygon.push_back(cur);
        }
        if ((isLeft(l.a, l.b, cur) && !isLeft(l.a, l.b, next)) ||
            (!isLeft(l.a, l.b, cur) && isLeft(l.a, l.b, next))) {
            long double A1 = (next - cur).cross(l.a - cur);
            long double A2 = (next - cur).cross(l.b - cur);
            Point intersection = l.a + (l.b - l.a) * (A1 / (A1 - A2));
            newPolygon.push_back(intersection);
        }
    }
    return newPolygon;
}

long double closestPair(vector<Point> &points, int l, int r) {
    if (r - l <= 1)
        return numeric_limits<long double>::max();
    int mid = (l + r) >> 1;
    long double x = points[mid].x;
    long double d =
        min(closestPair(points, l, mid), closestPair(points, mid, r));
    auto iti = points.begin(), itl = iti + l, itm = iti + mid, itr = iti + r;
    inplace_merge(itl, itm, itr,
                  [](const Point &lhs, const Point &rhs) -> bool {
                      return lessThan(lhs.y, rhs.y);
                  });

    vector<Point> nearLine;
    for (int i = l; i < r; ++i) {
        if (greaterThanOrEqual(fabs(points[i].x - x), d))
            continue;
        int sz = nearLine.size();
        for (int j = sz - 1; j >= 0; --j) {
            Point dv = points[i] - nearLine[j];
            if (dv.y >= d)
                break;
            d = min(d, dv.abs());
        }
        nearLine.push_back(points[i]);
    }
    return d;
}

int countIntersections(vector<Segment> segments) {
    struct Event {
        long double x;
        int type;  // 0: horizontal start, 1: vertical, 2: horizontal end
        long double y1, y2;

        Event(long double x, int type, long double y1, long double y2)
            : x(x), type(type), y1(y1), y2(y2) {}

        bool operator<(const Event &other) const {
            if (x == other.x)
                return type < other.type;
            return x < other.x;
        }
    };
    vector<Event> events;

    sort(segments.begin(), segments.end(),
         [](const Segment &lhs, const Segment &rhs) -> bool {
             return lessThan(min(lhs.a.x, lhs.b.x), min(rhs.a.x, rhs.b.x));
         });

    for (const auto &seg : segments) {
        if (seg.a.y == seg.b.y) {
            long double y = seg.a.y;
            long double x1 = min(seg.a.x, seg.b.x);
            long double x2 = max(seg.a.x, seg.b.x);
            events.emplace_back(x1, 0, y, y);
            events.emplace_back(x2, 2, y, y);
        } else {
            long double x = seg.a.x;
            long double y1 = min(seg.a.y, seg.b.y);
            long double y2 = max(seg.a.y, seg.b.y);
            events.emplace_back(x, 1, y1, y2);
        }
    }

    sort(events.begin(), events.end());

    set<long double> activeSegments;
    int intersectionCount = 0;

    for (const auto &event : events) {
        if (event.type == 0) {
            activeSegments.insert(event.y1);
        } else if (event.type == 2) {
            activeSegments.erase(event.y1);
        } else if (event.type == 1) {
            auto lower = activeSegments.lower_bound(event.y1);
            auto upper = activeSegments.upper_bound(event.y2);
            intersectionCount += distance(lower, upper);
        }
    }

    return intersectionCount;
}

int countCirclesIntersection(const Circle &c1, const Circle &c2) {
    long double d =
        sqrt((c1.center.x - c2.center.x) * (c1.center.x - c2.center.x) +
             (c1.center.y - c2.center.y) * (c1.center.y - c2.center.y));
    long double r1 = c1.r, r2 = c2.r;

    if (greaterThan(d, r1 + r2)) {
        return 4;
    } else if (almostEqual(d, r1 + r2)) {
        return 3;
    } else if (greaterThan(d, fabs(r1 - r2))) {
        return 2;
    } else if (almostEqual(d, fabs(r1 - r2))) {
        return 1;
    } else {
        return 0;
    }
}

Circle getInCircle(const Point &A, const Point &B,
                   const Point &C) {
    long double a = (B - C).abs();
    long double b = (A - C).abs();
    long double c = (A - B).abs();

    long double s = (a + b + c) / 2;
    long double area = sqrt(s * (s - a) * (s - b) * (s - c));
    long double r = area / s;

    long double cx = (a * A.x + b * B.x + c * C.x) / (a + b + c);
    long double cy = (a * A.y + b * B.y + c * C.y) / (a + b + c);

    return Circle{Point(cx, cy), r};
}

Circle getCircumCircle(const Point &A, const Point &B,
                       const Point &C) {
    long double D =
        2 * (A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y));
    long double Ux = ((A.x * A.x + A.y * A.y) * (B.y - C.y) +
                      (B.x * B.x + B.y * B.y) * (C.y - A.y) +
                      (C.x * C.x + C.y * C.y) * (A.y - B.y)) /
                     D;
    long double Uy = ((A.x * A.x + A.y * A.y) * (C.x - B.x) +
                      (B.x * B.x + B.y * B.y) * (A.x - C.x) +
                      (C.x * C.x + C.y * C.y) * (B.x - A.x)) /
                     D;

    Point center(Ux, Uy);
    long double radius = (center - A).abs();

    return Circle{center, radius};
}

vector<Point> getCircleLineIntersection(const Circle &c, Point p1, Point p2) {
    long double cx = c.center.x, cy = c.center.y, r = c.r;
    long double dx = p2.x - p1.x;
    long double dy = p2.y - p1.y;
    long double a = dx * dx + dy * dy;
    long double b = 2 * (dx * (p1.x - cx) + dy * (p1.y - cy));
    long double c_const =
        (p1.x - cx) * (p1.x - cx) + (p1.y - cy) * (p1.y - cy) - r * r;

    long double discriminant = b * b - 4 * a * c_const;
    vector<Point> intersections;

    if (almostEqual(discriminant, 0)) {
        long double t = -b / (2 * a);
        long double ix = p1.x + t * dx;
        long double iy = p1.y + t * dy;
        intersections.emplace_back(ix, iy);
        intersections.emplace_back(ix, iy);
    } else if (discriminant > 0) {
        long double sqrt_discriminant = sqrt(discriminant);
        long double t1 = (-b + sqrt_discriminant) / (2 * a);
        long double t2 = (-b - sqrt_discriminant) / (2 * a);

        long double ix1 = p1.x + t1 * dx;
        long double iy1 = p1.y + t1 * dy;
        long double ix2 = p1.x + t2 * dx;
        long double iy2 = p1.y + t2 * dy;

        intersections.emplace_back(ix1, iy1);
        intersections.emplace_back(ix2, iy2);
    }

    if (almostEqual(intersections[0].x, intersections[1].x)) {
        if (greaterThan(intersections[0].y, intersections[1].y)) {
            swap(intersections[0], intersections[1]);
        }
    } else if (greaterThan(intersections[0].x, intersections[1].x)) {
        swap(intersections[0], intersections[1]);
    }
    return intersections;
}

vector<Point> getCirclesIntersect(const Circle &c1, const Circle &c2) {
    long double x1 = c1.center.x, y1 = c1.center.y, r1 = c1.r;
    long double x2 = c2.center.x, y2 = c2.center.y, r2 = c2.r;

    long double d = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

    if (d > r1 + r2 || d < abs(r1 - r2)) {
        return {};  // No intersection
    }

    long double a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);
    long double h = sqrt(r1 * r1 - a * a);

    long double x0 = x1 + a * (x2 - x1) / d;
    long double y0 = y1 + a * (y2 - y1) / d;

    long double rx = -(y2 - y1) * (h / d);
    long double ry = (x2 - x1) * (h / d);

    Point p1(x0 + rx, y0 + ry);
    Point p2(x0 - rx, y0 - ry);

    vector<Point> intersections;
    intersections.push_back(p1);
    intersections.push_back(p2);

    if (almostEqual(intersections[0].x, intersections[1].x)) {
        if (greaterThan(intersections[0].y, intersections[1].y)) {
            swap(intersections[0], intersections[1]);
        }
    } else if (greaterThan(intersections[0].x, intersections[1].x)) {
        swap(intersections[0], intersections[1]);
    }
    return intersections;
}

vector<Point> getTangentLinesFromPoint(const Circle &c, const Point &p) {
    long double cx = c.center.x, cy = c.center.y, r = c.r;
    long double px = p.x, py = p.y;

    long double dx = px - cx;
    long double dy = py - cy;
    long double d = (p - c.center).abs();

    if (lessThan(d, r)) {
        return {};  // No tangents if the point is inside the circle
    } else if (almostEqual(d, r)) {
        return {p};
    }

    long double a = r * r / d;
    long double h = sqrt(r * r - a * a);

    long double cx1 = cx + a * dx / d;
    long double cy1 = cy + a * dy / d;

    vector<Point> tangents;

    tangents.emplace_back(cx1 + h * dy / d, cy1 - h * dx / d);
    tangents.emplace_back(cx1 - h * dy / d, cy1 + h * dx / d);

    if (almostEqual(tangents[0].x, tangents[1].x)) {
        if (greaterThan(tangents[0].y, tangents[1].y)) {
            swap(tangents[0], tangents[1]);
        }
    } else if (greaterThan(tangents[0].x, tangents[1].x)) {
        swap(tangents[0], tangents[1]);
    }

    return tangents;
}

vector<Segment> getCommonTangentsLine(const Circle &c1,
                                      const Circle &c2) {
    long double x1 = c1.center.x, y1 = c1.center.y, r1 = c1.r;
    long double x2 = c2.center.x, y2 = c2.center.y, r2 = c2.r;

    long double dx = x2 - x1;
    long double dy = y2 - y1;
    long double d = sqrt(dx * dx + dy * dy);

    vector<Segment> tangents;

    if (almostEqual(d, 0) && almostEqual(r1, r2)) {
        return tangents;
    }

    if (greaterThanOrEqual(d, r1 + r2)) {
        long double a = atan2(dy, dx);
        for (int sign : {-1, 1}) {
            long double theta = acos((r1 + r2) / d);
            long double cx1 = x1 + r1 * cos(a + sign * theta);
            long double cy1 = y1 + r1 * sin(a + sign * theta);
            long double cx2 = x2 + r2 * cos(a + sign * theta);
            long double cy2 = y2 + r2 * sin(a + sign * theta);
            tangents.emplace_back(Segment{Point(cx1, cy1), Point(cx2, cy2)});
            if (almostEqual(d, r1 + r2))
                break;
        }
    }

    if (greaterThanOrEqual(d, fabs(r1 - r2))) {
        long double a = atan2(dy, dx);
        for (int sign : {-1, 1}) {
            long double theta = acos((r1 - r2) / d);
            long double cx1 = x1 + r1 * cos(a + sign * theta);
            long double cy1 = y1 + r1 * sin(a + sign * theta);
            long double cx2 = x2 - r2 * cos(a + sign * theta);
            long double cy2 = y2 - r2 * sin(a + sign * theta);
            tangents.emplace_back(Segment{Point(cx1, cy1), Point(cx2, cy2)});
            if (almostEqual(d, fabs(r1 - r2)))
                break;
        }
    }

    sort(tangents.begin(), tangents.end(),
         [&](const Segment &s1, const Segment &s2) {
             if (almostEqual(s1.a.x, s2.a.x)) {
                 return lessThan(s1.a.y, s2.a.y);
             } else {
                 return lessThan(s1.a.x, s2.a.x);
             }
         });
    return tangents;
}

using ld = long double;

int main() {
    int T;
    cin >> T;

    while (T--) {
        Point A, B;
        cin >> A >> B;
        int N;
        cin >> N;
        Segment AB(A, B);
        vector<tuple<ld, ld, int, int>> T;
        for (int i = 0; i < N; i++) {
            Point C, D;
            cin >> C >> D;
            int o, l;
            cin >> o >> l;
            Segment CD(C, D);
            if (isIntersecting(AB, CD)) {
                Point P = getIntersection(AB, CD);
                auto [c, d] = P;
                T.push_back({c, d, o, l});
            }
        }
        sort(T.begin(), T.end());

        int ans = INF;
        for (int i = 0; i < 2; i++) {
            int now = i;
            int res = 0;
            for (auto [x, y, o, l] : T) {
                if (o) {
                    if (now != l) {
                        res++;
                        now = l;
                    }
                } else {
                    if (now == l) {
                        res++;
                        now = 1 - l;
                    }
                }
            }
            ans = min(ans, res);
        }

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3448
final_rank: 13

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

#include <bits/stdc++.h>
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }
typedef double D;
typedef complex<D> P;  // Point
typedef pair<P, P> L;  // Line
typedef vector<P> VP;
const D EPS = 1e-9;    // 許容誤差。問題によって変える
#define X real()
#define Y imag()
#define LE(n,m) ((n) < (m) + EPS)
#define GE(n,m) ((n) + EPS > (m))
#define EQ(n,m) (abs((n)-(m)) < EPS)

// 内積　dot(a,b) = |a||b|cosθ
D dot(P a, P b) {
  return (conj(a)*b).X;
}
// 外積　cross(a,b) = |a||b|sinθ
D cross(P a, P b) {
  return (conj(a)*b).Y;
}

// 点の進行方向
int ccw(P a, P b, P c) {
  b -= a;  c -= a;
  if (cross(b,c) >  EPS) return +1;  // counter clockwise
  if (cross(b,c) < -EPS) return -1;  // clockwise
  if (dot(b,c)   < -EPS) return +2;  // c--a--b on line
  if (norm(b) < norm(c)) return -2;  // a--b--c on line or a==b
  return 0;                          // a--c--b on line or a==c or b==c
}

/* 交差判定　直線・線分は縮退してはならない。接する場合は交差するとみなす。isecはintersectの略 */

// 直線と点
bool isecLP(P a1, P a2, P b) {
  return abs(ccw(a1, a2, b)) != 1;  // return EQ(cross(a2-a1, b-a1), 0); と等価
}

// 直線と直線
bool isecLL(P a1, P a2, P b1, P b2) {
  return !isecLP(a2-a1, b2-b1, 0) || isecLP(a1, b1, b2);
}

// 直線と線分
bool isecLS(P a1, P a2, P b1, P b2) {
  return cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS;
}

// 線分と線分
bool isecSS(P a1, P a2, P b1, P b2) {
  return ccw(a1, a2, b1)*ccw(a1, a2, b2) <= 0 &&
         ccw(b1, b2, a1)*ccw(b1, b2, a2) <= 0;
}

// 線分と点
bool isecSP(P a1, P a2, P b) {
  return !ccw(a1, a2, b);
}


/* 距離　各直線・線分は縮退してはならない */

// 点pの直線aへの射影点を返す
P proj(P a1, P a2, P p) {
  return a1 + dot(a2-a1, p-a1)/norm(a2-a1) * (a2-a1);
}

// 点pの直線aへの反射点を返す
P reflection(P a1, P a2, P p) {
  return 2.0*proj(a1, a2, p) - p;
}

D distLP(P a1, P a2, P p) {
  return abs(proj(a1, a2, p) - p);
}

D distLL(P a1, P a2, P b1, P b2) {
  return isecLL(a1, a2, b1, b2) ? 0 : distLP(a1, a2, b1);
}

D distLS(P a1, P a2, P b1, P b2) {
  return isecLS(a1, a2, b1, b2) ? 0 : min(distLP(a1, a2, b1), distLP(a1, a2, b2));
}

D distSP(P a1, P a2, P p) {
  P r = proj(a1, a2, p);
  if (isecSP(a1, a2, r)) return abs(r-p);
  return min(abs(a1-p), abs(a2-p));
}

D distSS(P a1, P a2, P b1, P b2) {
  if (isecSS(a1, a2, b1, b2)) return 0;
  return min(min(distSP(a1, a2, b1), distSP(a1, a2, b2)),
             min(distSP(b1, b2, a1), distSP(b1, b2, a2)));
}

// 2直線の交点
P crosspointLL(P a1, P a2, P b1, P b2) {
  D d1 = cross(b2-b1, b1-a1);
  D d2 = cross(b2-b1, a2-a1);
  if (EQ(d1, 0) && EQ(d2, 0)) return a1;  // same line
  if (EQ(d2, 0)) throw "kouten ga nai";   // 交点がない
  return a1 + d1/d2 * (a2-a1);
}

int solve(){
    P a, b;
    D ax, ay, bx, by; cin >> ax >> ay >> bx >> by;
    a = {ax, ay};
    b = {bx, by};
    int N; cin >> N;
    vc<tuple<P, P, int>> lines;
    vc<pair<P, int>> cross;
    rep(i, N){
        P s, t;
        D sx, sy, tx, ty; cin >> sx >> sy >> tx >> ty;
        s = {sx, sy};
        t = {tx, ty};
        int o, l; cin >> o >> l;
        if (o) l ^= 1;
        lines.push_back({s, t, l});
        if (isecSS(a, b, s, t)){
            cross.push_back({crosspointLL(a, b, s, t), l});
        }
    }
    sort(all(cross), [&](auto p1, auto p2){return (EQ(p1.first.real(), p2.first.real()) ? p1.first.imag() < p2.first.imag() : p1.first.real() < p2.first.real());});
    int ret = 0;
    rep(i, len(cross) - 1) if (cross[i].second != cross[i + 1].second) ret++;
    return ret;
}
int main(){
    vi ans;
    int T; cin >> T;
    rep(i, T) ans.push_back(solve());
    
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 3528
final_rank: 18

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;

using ll = long long;
using i64 = long long;
using pll = pair<ll,ll>;
using plll = pair<pll,ll>;
using pii =pair<int,int>;

constexpr ll mod = 1000000007;

int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int dX[4]={1,0,-1,0};
int dY[4]={0,-1,0,1};



//library

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

const double EPS = 1e-10;
const double PI = asinl(1) * 2;

struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):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 k){return Point(x*k,y*k);}
    Point operator/(double k){return Point(x/k,y/k);}
    double norm(){return x*x+y*y;}
    double abs(){return sqrt(norm());}

    bool operator<(const Point &p) const{
        return x!=p.x?x<p.x:y<p.y;
        //grid-point only
        //return !equals(x,p.x)?x<p.x:!equals(y,p.y)?y<p.y:0;
    }

    bool operator==(const Point &p) const{
        return fabs(x-p.x)<EPS and fabs(y-p.y)<EPS;
    }
};

bool sort_x(Point a,Point b){
    return a.x!=b.x?a.x<b.x:a.y<b.y;
}

bool sort_y(Point a,Point b){
    return a.y!=b.y?a.y<b.y:a.x<b.x;
}

typedef Point Vector;
typedef vector<Point> Polygon;

struct Segment{
    Point p1,p2;
    Segment(){}
    Segment(Point p1, Point p2):p1(p1),p2(p2){}
};
typedef Segment Line;

struct Circle{
    Point c;
    double r;
    Circle(){}
    Circle(Point c,double r):c(c),r(r){}
};

double norm(Vector a){
    return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
    return sqrt(norm(a));
}

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;
}

Point orth(Point p){return Point(-p.y,p.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)/norm(base);
    return s.p1+base*r;
}

Point reflect(Segment s,Point p){
    return p+(project(s,p)-p)*2.0;
}

double arg(Vector p){
    return atan2(p.y,p.x);
}

Vector polar(double a,double r){
    return Point(cos(r)*a,sin(r)*a);
}

// COUNTER CLOCKWISE
static const int CCW_COUNTER_CLOCKWISE = 1;
static const int CCW_CLOCKWISE = -1;
static const int CCW_ONLINE_BACK = 2;
static const int CCW_ONLINE_FRONT = -2;
static const int CCW_ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){
    Vector a = p1-p0;
    Vector b = p2-p0;
    if(cross(a,b) > EPS) return CCW_COUNTER_CLOCKWISE;
    if(cross(a,b) < -EPS) return CCW_CLOCKWISE;
    if(dot(a,b) < -EPS) return CCW_ONLINE_BACK;
    if(a.norm()<b.norm()) return CCW_ONLINE_FRONT;
    return CCW_ON_SEGMENT;
}

bool intersectSS(Point p1,Point p2,Point p3,Point p4){
    return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 and
            ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
}

bool intersectSS(Segment s1,Segment s2){
    return intersectSS(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool intersectPS(Polygon p,Segment l){
    int n=p.size();
    for(int i=0;i<n;++i)
        if(intersectSS(Segment(p[i],p[(i+1)%n]),l)) return 1;
    return 0;
}

double getDistanceLP(Line l,Point p){
    return fabs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
    if(dot(s.p2-s.p1,p-s.p1) < 0.0 ) return abs(p-s.p1);
    if(dot(s.p1-s.p2,p-s.p2) < 0.0 ) return abs(p-s.p2);
    return getDistanceLP(s,p);
}

double getDistanceSS(Segment s1,Segment s2){
    if(intersectSS(s1,s2)) return 0.0;
    return min(
            min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
            min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
}

// intercsect of circles
static const int ICC_SEPERATE = 4;
static const int ICC_CIRCUMSCRIBE = 3;
static const int ICC_INTERSECT = 2;
static const int ICC_INSCRIBE = 1;
static const int ICC_CONTAIN = 0;

int intersectCC(Circle c1,Circle c2){
    if(c1.r<c2.r) swap(c1,c2);
    double d=abs(c1.c-c2.c);
    double r=c1.r+c2.r;
    if(equals(d,r)) return ICC_CIRCUMSCRIBE;
    if(d>r) return ICC_SEPERATE;
    if(equals(d+c2.r,c1.r)) return ICC_INSCRIBE;
    if(d+c2.r<c1.r) return ICC_CONTAIN;
    return ICC_INTERSECT;
}

bool intersectSC(Segment s,Circle c){
    return getDistanceSP(s,c.c)<=c.r;
}

int intersectCS(Circle c,Segment s){
    if(norm(project(s,c.c)-c.c)-c.r*c.r>EPS) return 0;
    double d1=abs(c.c-s.p1),d2=abs(c.c-s.p2);
    if(d1<c.r+EPS and d2<c.r+EPS) return 0;
    if((d1<c.r-EPS and d2>c.r+EPS)
       or (d1>c.r+EPS and d2<c.r-EPS)) return 1;
    Point h=project(s,c.c);
    if(dot(s.p1-h,s.p2-h)<0) return 2;
    return 0;
}

Point getCrossPointSS(Segment s1,Segment s2){
    for(int k=0;k<2;++k){
        if(getDistanceSP(s1,s2.p1)<EPS) return s2.p1;
        if(getDistanceSP(s1,s2.p2)<EPS) return s2.p2;
        swap(s1,s2);
    }
    Vector base=s2.p2-s2.p1;
    double d1=fabs(cross(base,s1.p1-s2.p1));
    double d2=fabs(cross(base,s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return s1.p1+(s1.p2-s1.p1)*t;
}

Point getCrossPointLL(Line l1,Line l2){
    double a=cross(l1.p2-l1.p1,l2.p2-l2.p1);
    double b=cross(l1.p2-l1.p1,l1.p2-l2.p1);
    if(fabs(a)<EPS and fabs(b)<EPS) return l2.p1;
    return l2.p1+(l2.p2-l2.p1)*(b/a);
}

Polygon getCrossPointCL(Circle c,Line l){
    Polygon ps;
    Point pr=project(l,c.c);
    Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
    if(equals(getDistanceLP(l,c.c),c.r)){
        ps.emplace_back(pr);
        return ps;
    }
    double base=sqrt(c.r*c.r-norm(pr-c.c));
    ps.emplace_back(pr+e*base);
    ps.emplace_back(pr-e*base);
    return ps;
}

Polygon getCrossPointCS(Circle c,Segment s){
    Line l(s);
    Polygon res=getCrossPointCL(c,l);
    if(intersectCS(c,s)==2) return res;
    if(res.size()>1u){
        if(dot(l.p1-res[0],l.p2-res[0])>0) swap(res[0],res[1]);
        res.pop_back();
    }
    return res;
}


Polygon getCrossPointCC(Circle c1,Circle c2){
    Polygon p(2);
    double d=abs(c1.c-c2.c);
    double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t=arg(c2.c-c1.c);
    p[0]=c1.c+polar(c1.r,t+a);
    p[1]=c1.c+polar(c1.r,t-a);
    return p;
}

// IN:2 ON:1 OUT:0
int contains(Polygon g,Point p){
    int n=g.size();
    bool x=false;
    for(int i=0;i<n;++i){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(fabs(cross(a,b)) < EPS and dot(a,b) < EPS) return 1;
        if(a.y>b.y) swap(a,b);
        if(a.y < EPS and EPS < b.y and cross(a,b) > EPS )
            x = !x;
    }
    return (x?2:0);
}

// BEGIN IGNORE
Polygon andrewScan(Polygon s){
    Polygon u,l;
    if(s.size()<3) return s;
    sort(s.begin(),s.end());
    u.push_back(s[0]);
    u.push_back(s[1]);
    l.push_back(s[s.size()-1]);
    l.push_back(s[s.size()-2]);
    for(int i=2;i<(int)s.size();++i){
        for(int n=u.size();
            n>=2 and ccw(u[n-2],u[n-1],s[i])!=CCW_CLOCKWISE;
            n--){
            u.pop_back();
        }
        u.push_back(s[i]);
    }
    for(int i=s.size()-3;i>=0;i--){
        for(int n=l.size();
            n>=2 and ccw(l[n-2],l[n-1],s[i])!=CCW_CLOCKWISE;
            n--){
            l.pop_back();
        }
        l.push_back(s[i]);
    }
    reverse(l.begin(),l.end());
    for(int i=u.size()-2;i>=1;i--) l.push_back(u[i]);
    return l;
}
// END IGNORE

Polygon convex_hull(Polygon ps){
    int n=ps.size();
    sort(ps.begin(),ps.end(),sort_y);
    int k=0;
    Polygon qs(n*2);
    for(int i=0;i<n;++i){
        while(k>1 and cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0)
            k--;
        qs[k++]=ps[i];
    }
    for(int i=n-2,t=k;i>=0;i--){
        while(k>t and cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0)
            k--;
        qs[k++]=ps[i];
    }
    qs.resize(k-1);
    return qs;
}

double diameter(Polygon s){
    Polygon p=s;
    int n=p.size();
    if(n==2) return abs(p[0]-p[1]);
    int i=0,j=0;
    for(int k=0;k<n;++k){
        if(p[i]<p[k]) i=k;
        if(!(p[j]<p[k])) j=k;
    }
    double res=0;
    int si=i,sj=j;
    while(i!=sj or j!=si){
        res=max(res,abs(p[i]-p[j]));
        if(cross(p[(i+1)%n]-p[i],p[(j+1)%n]-p[j])<0.0){
            i=(i+1)%n;
        }else{
            j=(j+1)%n;
        }
    }
    return res;
}

bool isConvex(Polygon p){
    bool f=1;
    int n=p.size();
    for(int i=0;i<n;++i){
        int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
        f&=t!=CCW_CLOCKWISE;
    }
    return f;
}

double area(Polygon s){
    double res=0;
    for(int i=0;i<(int)s.size();++i){
        res+=cross(s[i],s[(i+1)%s.size()])/2.0;
    }
    return res;
}

double area(Circle c1,Circle c2){
    double d=abs(c1.c-c2.c);
    if(c1.r+c2.r<=d+EPS) return 0;
    if(d<=fabs(c1.r-c2.r)){
        double r=min(c1.r,c2.r);
        return PI*r*r;
    }
    double res=0;
    for(int k=0;k<2;++k){
        double rc=(d*d+c1.r*c1.r-c2.r*c2.r)/(2*d*c1.r);
        double th=acosl(rc)*2;
        res+=(th-sinl(th))*c1.r*c1.r/2;
        swap(c1,c2);
    }
    return res;
}

Polygon convexCut(Polygon p,Line l){
    Polygon q;
    for(int i=0;i<(int)p.size();++i){
        Point a=p[i],b=p[(i+1)%p.size()];
        if(ccw(l.p1,l.p2,a)!=-1) q.push_back(a);
        if(ccw(l.p1,l.p2,a)*ccw(l.p1,l.p2,b)<0)
            q.push_back(getCrossPointLL(Line(a,b),l));
    }
    return q;
}

Line bisector(Point p1,Point p2){
    Circle c1=Circle(p1,abs(p1-p2)),c2=Circle(p2,abs(p1-p2));
    Polygon p=getCrossPointCC(c1,c2);
    if(cross(p2-p1,p[0]-p1)>0) swap(p[0],p[1]);
    return Line(p[0],p[1]);
}

Vector translate(Vector v,double theta){
    Vector res;
    res.x=cos(theta)*v.x-sin(theta)*v.y;
    res.y=sin(theta)*v.x+cos(theta)*v.y;
    return res;
}

vector<Line> corner(Line l1,Line l2){
    vector<Line> res;
    if(isParallel(l1,l2)){
        double d=getDistanceLP(l1,l2.p1)/2.0;
        Vector v1=l1.p2-l1.p1;
        v1=v1/v1.abs()*d;
        Point p=l2.p1+translate(v1,90.0*(PI/180.0));
        double d1=getDistanceLP(l1,p);
        double d2=getDistanceLP(l2,p);
        if(fabs(d1-d2)>d){
            p=l2.p1+translate(v1,-90.0*(PI/180.0));
        }
        res.push_back(Line(p,p+v1));
    }else{
        Point p=getCrossPointLL(l1,l2);
        Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
        v1=v1/v1.abs();
        v2=v2/v2.abs();
        res.push_back(Line(p,p+(v1+v2)));
        res.push_back(
                Line(p,p+translate(v1+v2,90.0*(PI/180.0))));
    }
    return res;
}

Polygon tangent(Circle c1,Point p2){
    Circle c2=Circle(p2,sqrt(norm(c1.c-p2)-c1.r*c1.r));
    Polygon p=getCrossPointCC(c1,c2);
    sort(p.begin(),p.end());
    return p;
}

vector<Line> tangent(Circle c1,Circle c2){
    vector<Line> ls;
    if(c1.r<c2.r) swap(c1,c2);
    double g=norm(c1.c-c2.c);
    if(equals(g,0)) return ls;
    Point u=(c2.c-c1.c)/sqrt(g);
    Point v=orth(u);
    for(int s=1;s>=-1;s-=2){
        double h=(c1.r+s*c2.r)/sqrt(g);
        if(equals(1-h*h,0)){
            ls.emplace_back(c1.c+u*c1.r,c1.c+(u+v)*c1.r);
        }else if(1-h*h>0){
            Point uu=u*h,vv=v*sqrt(1-h*h);
            ls.emplace_back(
                    c1.c+(uu+vv)*c1.r,c2.c-(uu+vv)*c2.r*s);
            ls.emplace_back(
                    c1.c+(uu-vv)*c1.r,c2.c-(uu-vv)*c2.r*s);
        }
    }

    return ls;
}

double closest_pair(Polygon &a,int l=0,int r=-1){
    if(r<0){
        r=a.size();
        sort(a.begin(),a.end(),sort_x);
    }
    if(r-l<=1) return abs(a[0]-a[1]);
    int m=(l+r)>>1;
    double x=a[m].x;
    double d=min(closest_pair(a,l,m),closest_pair(a,m,r));
    inplace_merge(a.begin()+l,a.begin()+m,a.begin()+r,sort_y);

    Polygon b;
    for(int i=l;i<r;++i){
        if(fabs(a[i].x-x)>=d) continue;
        for(int j=0;j<(int)b.size();++j){
            double dy=a[i].y-next(b.rbegin(),j)->y;
            if(dy>=d) break;
            d=min(d,abs(a[i]-*next(b.rbegin(),j)));
        }
        b.emplace_back(a[i]);
    }
    return d;
}

vector<vector<int>>
segmentArrangement(vector<Segment> &ss, Polygon &ps){
    int n=ss.size();
    for(int i=0;i<n;++i){
        ps.emplace_back(ss[i].p1);
        ps.emplace_back(ss[i].p2);
        for(int j=i+1;j<n;++j)
            if(intersectSS(ss[i],ss[j]))
                ps.emplace_back(getCrossPointSS(ss[i],ss[j]));
    }
    sort(ps.begin(),ps.end());
    ps.erase(unique(ps.begin(),ps.end()),ps.end());

    vector<vector<int> > G(ps.size());
    for(int i=0;i<n;++i){
        vector<pair<double,int> > ls;
        for(int j=0;j<(int)ps.size();++j)
            if(getDistanceSP(ss[i],ps[j])<EPS)
                ls.emplace_back(make_pair(norm(ss[i].p1-ps[j]),j));

        sort(ls.begin(),ls.end());
        for(int j=0;j+1<(int)ls.size();++j){
            int a=ls[j].second,b=ls[j+1].second;
            G[a].emplace_back(b);
            G[b].emplace_back(a);
        }
    }
    for(auto &v:G){
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
    }
    return G;
}

struct EndPoint{
    Point p;
    int seg,st;
    EndPoint(){}
    EndPoint(Point p,int seg,int st):p(p),seg(seg),st(st){}
    bool operator<(const EndPoint &ep)const{
        if(p.y==ep.p.y) return st<ep.st;
        return p.y<ep.p.y;
    }
};

int manhattan_intersection(
        vector<Segment> ss,const int INF){
    const int BTM = 0;
    const int LFT = 1;
    const int RGH = 2;
    const int TOP = 3;

    int n=ss.size();
    vector<EndPoint> ep;
    for(int i=0;i<n;++i){
        if(ss[i].p1.y==ss[i].p2.y){
            if(ss[i].p1.x>ss[i].p2.x) swap(ss[i].p1,ss[i].p2);
            ep.emplace_back(ss[i].p1,i,LFT);
            ep.emplace_back(ss[i].p2,i,RGH);
        }else{
            if(ss[i].p1.y>ss[i].p2.y) swap(ss[i].p1,ss[i].p2);
            ep.emplace_back(ss[i].p1,i,BTM);
            ep.emplace_back(ss[i].p2,i,TOP);
        }
    }
    sort(ep.begin(),ep.end());

    set<int> bt;
    bt.insert(INF);

    int cnt=0;
    for(int i=0;i<n*2;++i){
        if(ep[i].st==TOP){
            bt.erase(ep[i].p.x);
        }else if(ep[i].st==BTM){
            bt.emplace(ep[i].p.x);
        }else if(ep[i].st==LFT){
            auto b=bt.lower_bound(ss[ep[i].seg].p1.x);
            auto e=bt.upper_bound(ss[ep[i].seg].p2.x);
            cnt+=distance(b,e);
        }
    }

    return cnt;
}

double area(Polygon ps,Circle c){
    if(ps.size()<3u) return 0;
    function<double(Circle, Point, Point)> dfs=
            [&](Circle c,Point a,Point b){
                Vector va=c.c-a,vb=c.c-b;
                double f=cross(va,vb),res=0;
                if(equals(f,0.0)) return res;
                if(max(abs(va),abs(vb))<c.r+EPS) return f;
                Vector d(dot(va,vb),cross(va,vb));
                if(getDistanceSP(Segment(a,b),c.c)>c.r-EPS)
                    return c.r*c.r*atan2(d.y,d.x);
                auto u=getCrossPointCS(c,Segment(a,b));
                if(u.empty()) return res;
                if(u.size()>1u and dot(u[1]-u[0],a-u[0])>0)
                    swap(u[0],u[1]);
                u.emplace(u.begin(),a);
                u.emplace_back(b);
                for(int i=1;i<(int)u.size();++i)
                    res+=dfs(c,u[i-1],u[i]);
                return res;
            };
    double res=0;
    for(int i=0;i<(int)ps.size();++i)
        res+=dfs(c,ps[i],ps[(i+1)%ps.size()]);
    return res/2;
}

//end



using Graph =vector<vector<ll>>;

int main(){
    int n;
    cin>>n;

    for (int i0=0; i0<n; i0++){
        double xa,ya,xb,yb;
        cin>>xa>>ya>>xb>>yb;
        Segment S0={Point(xa,ya),Point(xb,yb)};

        int m;
        cin>>m;
        vector<pair<Point,int>> P;

        for (int i=0; i<m; i++){
            double xs,ys,xt,yt;
            int o,l;
            cin>>xs>>ys>>xt>>yt>>o>>l;

            int f=(o^l);
            Segment S1={Point(xs,ys),Point(xt,yt)};
            if (intersectSS(S0,S1)){
                P.emplace_back(getCrossPointSS(S0,S1),f);
            }
        }
        auto comp=[&](auto& a, auto&b){
            if (a.first.x==b.first.x){
                return a.first.y<b.first.y;
            }
            return a.first.x<b.first.x;
        };
        sort(P.begin(),P.end(),comp);
        int ans=0;
        for (int i=1; i<P.size(); i++){
            if (P[i].second!=P[i-1].second)ans++;
        }
        cout<<ans<<endl;


    }

}
accuracy: 1
time_ms: 50
memory_kb: 3552
final_rank: 19

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using ll = long long;
#define MOD 1000000007
#define Mod 998244353
const int MAX = 1000000005;
const long long INF = 1000000000000000005LL;
using namespace std;
//using namespace atcoder;


const double EPS = 1e-9;

struct Point {
	double x, y;
	
	Point operator+(Point& other) {
		return {x + other.x, y + other.y};
	}
	Point operator-(Point& other) {
		return {x - other.x, y - other.y};
	}
};

struct Segment {
	Point a, b;
};

double norm(Point P) {return sqrt(P.x*P.x + P.y*P.y);}
double arg(Point P) {return atan2(P.y, P.x);}

double dot(Point P, Point Q) {
	return P.x*Q.x + P.y*Q.y;
}

double cross(Point P, Point Q) {
	return P.x*Q.y - P.y*Q.x;
}

int ccw(Point a, Point b, Point c) {
	if (cross(b - a, c - a) > EPS) return 1;
	if (cross(b - a, c - a) < -EPS) return -1;
	if (dot(b - a, c - a) < -EPS) return 2;
	if (norm(b - a) + EPS < norm(c - a)) return -2;
	return 0;
}

bool intersect(Segment s1, Segment s2) {
    bool b1 = (ccw(s1.a, s1.b, s2.a)*ccw(s1.a, s1.b, s2.b) <= 0);
    bool b2 = (ccw(s2.a, s2.b, s1.a)*ccw(s2.a, s2.b, s1.b) <= 0);
    return b1 && b2;
}

Point cross_point(Segment s1, Segment s2) {
	Point a = s1.a, b = s1.b, c = s2.a, d = s2.b;
	Point p;
	p.x = a.x + cross(a-c, d-c)/cross(d-c, b-a) * (b-a).x;
	p.y = a.y + cross(a-c, d-c)/cross(d-c, b-a) * (b-a).y;
	return p;
}

struct CPoint {
    Point p;
    int o, l;
};

bool solve() {
    Point a, b;
    cin >> a.x >> a.y >> b.x >> b.y;
    Segment s1 = {a, b};
    int n;
    cin >> n;
    vector<CPoint> crosses;
    for (int i = 0; i < n; i++) {
        Point c, d;
        int o, l;
        cin >> c.x >> c.y >> d.x >> d.y >> o >> l;
        Segment s2 = {c, d};
        if (!intersect(s1, s2)) continue;
        crosses.push_back({cross_point(s1, s2), o, l});
    }
    sort(crosses.begin(), crosses.end(), [&](CPoint& a, CPoint& b) -> bool {
        if (fabs(a.p.x - b.p.x) < EPS) return a.p.y < b.p.y;
        return a.p.x < b.p.x;
    });
    int ans = 0;
    for (int i = 1; i < crosses.size(); i++) {
        int pl = (crosses[i-1].o ? crosses[i-1].l : 1-crosses[i-1].l);
        int nl = (crosses[i].o ? crosses[i].l : 1-crosses[i].l);
        ans += (pl != nl);
    }
    cout << ans << endl;
    return true;
}

int main() {
    ios::sync_with_stdio(0); cin.tie();
    int t;
    cin >> t;
    while (t--) {solve();}
}
accuracy: 1
time_ms: 20
memory_kb: 3480
final_rank: 2

code_snippet: #include <bits/stdc++.h>

#include <algorithm>
#include <cmath>
#include <iterator>
#include <utility>
#include <vector>

using Real = long double;
constexpr Real EPS = 1e-10;
const Real PI = std::acos(-1);

int sign(Real x) {
    return x < -EPS ? -1 : x > EPS ? 1 : 0;
}

bool eq(Real lhs, Real rhs) {
    return sign(rhs - lhs) == 0;
}

bool lte(Real lhs, Real rhs) {
    return sign(rhs - lhs) >= 0;
}

bool lt(Real lhs, Real rhs) {
    return sign(rhs - lhs) > 0;
}

bool gte(Real lhs, Real rhs) {
    return lte(rhs, lhs);
}

bool gt(Real lhs, Real rhs) {
    return lt(rhs, lhs);
}

struct Point {
    Real x;
    Real y;
    Point(Real x = 0, Real y = 0): x(x), y(y) {}
    Point& operator+=(Point rhs) {
        this->x += rhs.x;
        this->y += rhs.y;
        return *this;
    }
    Point& operator-=(Point rhs) {
        this->x -= rhs.x;
        this->y -= rhs.y;
        return *this;
    }
    Point& operator*=(Real k) {
        this->x *= k;
        this->y *= k;
        return *this;
    }
    Point& operator/=(Real k) {
        this->x /= k;
        this->y /= k;
        return *this;
    }
    friend Point operator+(Point lhs, Point rhs) {
        return lhs += rhs;
    }
    friend Point operator-(Point lhs, Point rhs) {
        return lhs -= rhs;
    }
    friend Point operator*(Point p, Real k) {
        return p *= k;
    }
    friend Point operator/(Point p, Real k) {
        return p /= k;
    }
    friend Point operator*(Real k, Point p) {
        return p * k;
    }
    friend Point operator/(Real k, Point p) {
        return p / k;
    }
    friend bool operator==(Point lhs, Point rhs) {
        return eq(lhs.x, rhs.x) && eq(lhs.y, rhs.y);
    }
    friend bool operator<(Point lhs, Point rhs) {
        if (eq(lhs.x, rhs.x)) return lt(lhs.y, rhs.y);
        return lt(lhs.x, rhs.x);
    }
    friend bool operator>(Point lhs, Point rhs) {
        return rhs < lhs;
    }
};

using Points = std::vector<Point>;
using Polygon = Points;
using Vector = Point;

Real norm(Vector p) {
    return p.x * p.x + p.y * p.y;
}

Real abs(Vector p) {
    return std::sqrt(norm(p));
}

Real dot(Vector lhs, Vector rhs) {
    return lhs.x * rhs.x + lhs.y * rhs.y;
}

Real cross(Vector lhs, Vector rhs) {
    return lhs.x * rhs.y - lhs.y * rhs.x;
}

int ccw(Point p0, Point p1, Point p2) {
    Vector a = p1 - p0;
    Vector b = p2 - p0;

    if (cross(a, b) > EPS) return 1;

    if (cross(a, b) < -EPS) return -1;

    if (dot(a, b) < 0) return 2;

    if (norm(a) < norm(b)) return -2;

    return 0;
}

struct Circle {
    Real r;
    Point c;
    Circle() {}
    Circle(Real r, Point c): r(r), c(c) {}
};

struct Segment {
    Segment() {}
    Segment(Point p0, Point p1): p0(p0), p1(p1) {}
    Point p0, p1;
};

struct Line {
    Line() {}
    Line(Point p0, Point p1): p0(p0), p1(p1) {}
    explicit Line(Segment s): p0(s.p0), p1(s.p1) {}
    Point p0, p1;
};

Real distance(Point lhs, Point rhs) {
    return abs(rhs - lhs);
}

Real distance(Line l, Point p) {
    return std::abs(cross(l.p1 - l.p0, p - l.p0)) / abs(l.p1 - l.p0);
}

Real distance(Segment s, Point p) {
    if (dot(s.p1 - s.p0, p - s.p0) < 0) {
        return distance(p, s.p0);
    }
    if (dot(s.p0 - s.p1, p - s.p1) < 0) {
        return distance(p, s.p1);
    }
    return distance(Line(s), p);
}

bool intersect(Segment lhs, Segment rhs) {
    return ccw(lhs.p0, lhs.p1, rhs.p0) * ccw(lhs.p0, lhs.p1, rhs.p1) <= 0
           && ccw(rhs.p0, rhs.p1, lhs.p0) * ccw(rhs.p0, rhs.p1, lhs.p1) <= 0;
}

bool intersect(Segment s, Point p) {
    return ccw(s.p0, s.p1, p) == 0;
}

Real distance(Segment lhs, Segment rhs) {
    if (intersect(lhs, rhs)) {
        return Real(0);
    }
    return std::min({distance(lhs, rhs.p0), distance(lhs, rhs.p1), distance(rhs, lhs.p0), distance(rhs, lhs.p1)});
}

bool parallel(Vector lhs, Vector rhs) {
    return eq(cross(lhs, rhs), 0);
}

bool parallel(Segment lhs, Segment rhs) {
    return parallel(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

bool parallel(Line lhs, Line rhs) {
    return parallel(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

Point crosspoint(Line lhs, Line rhs) {
    Real a = cross(lhs.p1 - lhs.p0, rhs.p1 - rhs.p0);
    Real b = cross(lhs.p1 - lhs.p0, lhs.p1 - rhs.p0);
    return rhs.p0 + (rhs.p1 - rhs.p0) * b / a;
}

bool intersect(Line l, Segment s) {
    return ccw(l.p0, l.p1, s.p0) * ccw(l.p0, l.p1, s.p1) <= 0;
}

bool intersect(Circle c, Line l) {
    return lte(distance(l, c.c), c.r);
}

bool intersect(Circle c, Point p) {
    return eq(distance(c.c, p), c.r);
}

int intersect(Circle lhs, Circle rhs) {
    if (gt(lhs.r, rhs.r)) std::swap(lhs, rhs);
    Real d = distance(lhs.c, rhs.c);
    if (lt(lhs.r + rhs.r, d)) return 4;
    if (eq(lhs.r + rhs.r, d)) return 3;
    if (gt(lhs.r + d, rhs.r)) return 2;
    if (eq(lhs.r + d, rhs.r)) return 1;
    return 0;
}

bool orthogonal(Vector lhs, Vector rhs) {
    return eq(dot(lhs, rhs), 0);
}

bool orthogonal(Segment lhs, Segment rhs) {
    return orthogonal(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

bool orthogonal(Line lhs, Line rhs) {
    return orthogonal(lhs.p0 - lhs.p1, rhs.p0 - rhs.p1);
}

Point crosspoint(Segment lhs, Segment rhs) {
    Real d0 = distance(Line(lhs.p0, lhs.p1), rhs.p0);
    Real d1 = distance(Line(lhs.p0, lhs.p1), rhs.p1);
    return rhs.p0 + (rhs.p1 - rhs.p0) * (d0 / (d0 + d1));
}

Real arg(Vector p) {
    return std::atan2(p.y, p.x);
}

Vector polar(Real a, Real r) {
    return Point(std::cos(r) * a, std::sin(r) * a);
}

Point rotate(Point p, Real t) {
    Point v = polar(1, t);
    return Point(p.x * v.x - p.y * v.y, p.x * v.y + p.y * v.x);
}

Real angle(Point p0, Point p1, Point p2) {
    Real a = arg(p0 - p1);
    Real b = arg(p2 - p1);
    if (gt(a, b)) std::swap(a, b);
    return std::min(b - a, 2 * PI - (b - a));
}

Points crosspoint(Circle lhs, Circle rhs) {
    Real d = abs(lhs.c - rhs.c);
    if (eq(d, lhs.r + rhs.r)) return {lhs.c + lhs.r * (rhs.c - lhs.c) / d};
    Real a = std::acos((lhs.r * lhs.r + d * d - rhs.r * rhs.r) / (2 * lhs.r * d));
    Real t = arg(rhs.c - lhs.c);
    return {lhs.c + polar(lhs.r, t + a), lhs.c + polar(lhs.r, t - a)};
}

Point projection(Segment s, Point p) {
    Vector a = p - s.p0;
    Vector b = s.p1 - s.p0;
    Real t = dot(a, b) / norm(b);
    return s.p0 + t * b;
}

Point projection(Line l, Point p) {
    Vector a = p - l.p0;
    Vector b = l.p1 - l.p0;
    Real t = dot(a, b) / norm(b);
    return l.p0 + t * b;
}

Point reflection(Segment s, Point p) {
    return p + (projection(s, p) - p) * Real(2);
}

Point reflection(Line l, Point p) {
    return p + (projection(l, p) - p) * Real(2);
}

Points crosspoint(Circle c, Line l) {
    Vector p = projection(l, c.c);
    Real t = std::sqrt(c.r * c.r - norm(c.c - p));
    if (eq(t, 0)) return {p};
    Vector e = (l.p1 - l.p0) / abs(l.p1 - l.p0);
    return {p + t * e, p + -t * e};
}

Real area(Polygon poly) {
    int n = poly.size();
    Real result = 0;
    for (int i = 0; i < n; i++) {
        result += cross(poly[i], poly[(i + 1) % n]);
    }
    return result / 2;
}

Real perimeter(Polygon poly) {
    int n = poly.size();
    Real result = 0;
    for (int i = 0; i < n; i++) {
        result += abs(poly[i] - poly[(i + 1) % n]);
    }
    return result;
}

bool convex(Polygon poly) {
    int n = poly.size();
    for (int i = 0; i < n; i++) {
        if (ccw(poly[i], poly[(i + 1) % n], poly[(i + 2) % n]) == -1) return false;
    }
    return true;
}

int contain(Polygon poly, Point p) {
    int n = poly.size();
    bool parity = false;
    for (int i = 0; i < n; i++) {
        Point a = poly[i] - p;
        Point b = poly[(i + 1) % n] - p;
        if (gt(a.y, b.y)) std::swap(a, b);
        if (lte(a.y, 0) && lt(0, b.y) && lt(cross(a, b), 0)) parity ^= true;
        if (eq(cross(a, b), 0) && lte(dot(a, b), 0)) return 1;
    }
    return (parity ? 2 : 0);
}

Polygon convex_hull(Points points) {
    std::sort(points.begin(), points.end(), [](Point lhs, Point rhs) {
        if (eq(lhs.x, rhs.x)) return lt(lhs.y, rhs.y);
        return lt(lhs.x, rhs.x);
    });
    int n = points.size();
    Points lower, upper;
    lower.push_back(points[n - 1]);
    lower.push_back(points[n - 2]);
    upper.push_back(points[0]);
    upper.push_back(points[1]);
    for (int i = n - 3; i >= 0; i--) {
        for (int m = lower.size(); m >= 2 && ccw(lower[m - 2], lower[m - 1], points[i]) >= 0; m--) {
            lower.pop_back();
        }
        lower.push_back(points[i]);
    }
    for (int i = 2; i < n; i++) {
        for (int m = upper.size(); m >= 2 && ccw(upper[m - 2], upper[m - 1], points[i]) >= 0; m--) {
            upper.pop_back();
        }
        upper.push_back(points[i]);
    }
    std::reverse(lower.begin(), lower.end());
    std::copy(std::next(upper.rbegin()), std::prev(upper.rend()), std::back_inserter(lower));
    return lower;
}

Polygon convex_cut(Polygon poly, Line l) {
    int n = poly.size();
    Polygon res;
    for (int i = 0; i < n; i++) {
        Point a = poly[i];
        Point b = poly[(i + 1) % n];
        if (ccw(l.p0, l.p1, a) != -1) res.push_back(a);
        if (ccw(l.p0, l.p1, a) * ccw(l.p0, l.p1, b) == -1) {
            res.push_back(crosspoint(l, Line(a, b)));
        }
    }
    return res;
}

Line bisector(Point p0, Point p1, Point p2) {
    return Line(p1, p1 + polar(1, angle(p0, p1, p2) / 2));
}

Circle incircle(Point p0, Point p1, Point p2) {
    Point c = crosspoint(bisector(p0, p1, p2), bisector(p1, p2, p0));
    Real r = std::abs(2 * area({p0, p1, p2}) / perimeter({p0, p1, p2}));
    return Circle(r, c);
}

Line perpendicular(Line l, Point p) {
    Vector v = l.p1 - l.p0;
    return Line(p, p + Vector(-v.y, v.x));
}

Line perpendicular_bisector(Segment s) {
    return perpendicular(Line(s), (s.p0 + s.p1) / 2);
}

Circle circumscribed_circle(Point p0, Point p1, Point p2) {
    Point c = crosspoint(perpendicular_bisector(Segment(p0, p1)), perpendicular_bisector(Segment(p0, p2)));
    return Circle(distance(p0, c), c);
}

Real area(Circle c) {
    return c.r * c.r * PI;
}

Points tangent(Circle c, Point p) {
    return crosspoint(c, Circle(std::sqrt(norm(c.c - p) - c.r * c.r), p));
}

int solve() {
    Point start, goal;
    std::cin >> start.x >> start.y;
    std::cin >> goal.x >> goal.y;
    Segment segment(start, goal);
    int n;
    std::cin >> n;
    std::vector<std::pair<Point, int>> cp;
    for (int i = 0; i < n; i++) {
        Point p, q;
        std::cin >> p.x >> p.y;
        std::cin >> q.x >> q.y;
        Segment s(p, q);
        int a, b;
        std::cin >> a >> b;
        if (intersect(segment, s)) {
            cp.emplace_back(crosspoint(segment, s), a ^ b);
        }
    }
    std::sort(cp.begin(), cp.end());
    int ans = 0;
    for (int l = 0, r = 0; l < (int)cp.size(); l = r) {
        while (r < (int)cp.size() && cp[l].second == cp[r].second) r++;
        ans++;
    }
    std::cout << std::max(0, ans - 1) << std::endl;
    return 0;
}

int main() {
    int n;
    std::cin >> n;
    while (n--) solve();
}
accuracy: 1
time_ms: 50
memory_kb: 3480
final_rank: 16

code_snippet: #include <bits/stdc++.h>

//#define rep(i, N) for(ll i = 0; i < (ll)(N); ++i)
//#define per(i, N) for(ll i = (ll)(N) - 1; i >= 0; --i)
//#define all(v) (v).begin(), (v).end()
//#define rall(v) (v).rbegin(), (v).rend()
//#define bit(n, k) (((n) >> (k)) & 1)
//#define pcnt(n) (bitset<64>(n).count())
//#define endl '\n'
//#define fi first
//#define se second
//#define mkpr make_pair
//#define mktpl make_tuple
//#define eb emplace_back
//template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& V) {
//    for (auto& it : V) is >> it;
//    return is;
//}
//template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& V) {
//    for (int i = 0 ; i < (int)V.size() ; i++) {
//        os << V[i] << (i + 1 == (int)V.size() ? "" : " ");
//    }
//    return os;
//}
//using namespace std;






namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

namespace geometryR2 {

using Real = long double;

namespace internal {

Real EPS{1e-12};
constexpr i32 negative{-1};
constexpr i32 zero{};
constexpr i32 positive{1};

} // namespace internal

Real& Eps() {
    return internal::EPS;
}

i32 Sign(Real value) {
    if (value < -Eps()) return internal::negative;
    if (value > Eps()) return internal::positive;
    return internal::zero;
}

bool Zero(Real value) {
    return Sign(value) == internal::zero;
}

bool Positive(Real value) {
    return Sign(value) == internal::positive;
}

bool Negative(Real value) {
    return Sign(value) == internal::negative;
}

bool Equal(Real a, Real b) {
    return Zero(a - b);
}

bool Smaller(Real a, Real b) {
    return Negative(a - b);
}

bool Bigger(Real a, Real b) {
    return Positive(a - b);
}

Real Square(Real value) {
    return (Zero(value) ? value : value * value);
}

Real Sqrt(Real value) {
    assert(!Negative(value));
    return (Zero(value) ? value : sqrtl(value));
}

Real Abs(Real value) {
    return (Negative(value) ? -value : value);
}

} // namespace geometryR2
 
} // namespace zawa



namespace zawa {

namespace geometryR2 {

constexpr Real PI{acosl(-1)};
constexpr Real TAU{static_cast<Real>(2) * PI};

constexpr Real ArcToRadian(Real arc) {
    return (arc * PI) / static_cast<Real>(180);
}

constexpr Real RadianToArc(Real radian) {
    return (radian * static_cast<Real>(180)) / PI;
}

} // namespace geometryR2

} // namespace zawa


namespace zawa {

namespace geometryR2 {

class Point {
private:
    Real x_{}, y_{};
public:
    /* constructor */
    Point() = default;
    Point(Real x, Real y) : x_{x}, y_{y} {}

    /* getter, setter */
    Real x() const {
        return x_;
    }
    Real& x() {
        return x_;
    }
    Real y() const {
        return y_;
    }
    Real& y() {
        return y_;
    }

    /* operator */
    Point& operator+=(const Point& rhs) {
        x_ += rhs.x();
        y_ += rhs.y();
        return *this;
    }
    friend Point operator+(const Point& lhs, const Point& rhs) {
        return Point{lhs} += rhs;
    }
    Point operator+() const {
        return *this;
    }
    Point& operator-=(const Point& rhs) {
        x_ -= rhs.x();
        y_ -= rhs.y();
        return *this;
    }
    friend Point operator-(const Point& lhs, const Point& rhs) {
        return Point{lhs} -= rhs;
    }
    Point operator-() const {
        return Point{} - *this;
    }
    Point& operator*=(Real k) {
        x_ *= k;
        y_ *= k;
        return *this;
    }
    friend Point operator*(Real k, const Point& p) {
        return Point{p} *= k;
    }
    friend Point operator*(const Point& p, Real k) {
        return Point{p} *= k;
    }
    Point& operator/=(Real k) {
        assert(!Zero(k));
        x_ /= k;
        y_ /= k;
        return *this;
    }
    friend Point operator/(Real k, const Point& p) {
        return Point{p} /= k;
    }
    friend Point operator/(const Point& p, Real k) {
        return Point{p} /= k;
    }
    friend bool operator==(const Point& lhs, const Point& rhs) {
        return Equal(lhs.x(), rhs.x()) and Equal(lhs.y(), rhs.y());
    }
    friend bool operator!=(const Point& lhs, const Point& rhs) {
        return !Equal(lhs.x(), rhs.x()) or !Equal(lhs.y(), rhs.y());
    }
    friend bool operator<(const Point& lhs, const Point& rhs) {
        return Smaller(lhs.x(), rhs.x()) or 
            (Equal(lhs.x(), rhs.x()) and Smaller(lhs.y(), rhs.y()));
    }
    friend bool operator<=(const Point& lhs, const Point& rhs) {
        return Smaller(lhs.x(), rhs.x()) or 
            (Equal(lhs.x(), rhs.x()) and (Smaller(lhs.y(), rhs.y()) or Equal(lhs.y(), rhs.y())));
    }
    friend bool operator>(const Point& lhs, const Point& rhs) {
        return Bigger(lhs.x(), rhs.x()) or
            (Equal(lhs.x(), rhs.x()) and Bigger(lhs.y(), rhs.y()));
    }
    friend bool operator>=(const Point& lhs, const Point& rhs) {
        return Bigger(lhs.x(), rhs.x()) or
            (Equal(lhs.x(), rhs.x()) and (Bigger(lhs.y(), rhs.y()) or Equal(lhs.y(), rhs.y())));
    }
    friend std::istream& operator>>(std::istream& is, Point& p) {
        is >> p.x_ >> p.y_;
        return is;
    }
    friend std::ostream& operator<<(std::ostream& os, const Point& p) {
        os << '(' << p.x_ << ',' << p.y_ << ')';
        return os;
    }
    
    /* member function */
    Real normSquare() const {
        return Square(x_) + Square(y_);
    }
    Real norm() const {
        return Sqrt(normSquare());
    }
    void normalize() {
        assert((*this) != Point{});
        (*this) /= norm(); 
    }
    Point normalized() const {
        Point res{*this};
        res.normalize();
        return res;
    }
    Point rotated(Real radian) const {
        return Point{
            x_ * cosl(radian) - y_ * sinl(radian),
            x_ * sinl(radian) + y_ * cosl(radian)
        };
    }
    void rotate(Real radian) {
        *this = rotated(radian); 
    }
    Point rotatedByArc(Real arc) const {
        return rotated(ArcToRadian(arc));
    }
    void rotateByArc(Real arc) {
        *this = rotatedByArc(arc);
    }
    Real argument() const {
        return (Negative(y_) ? TAU : static_cast<Real>(0)) + atan2l(y_, x_);
    }
    Real argumentByArc() const {
        return RadianToArc(argument());
    }

    /* friend function */
    friend Real Dot(const Point& lhs, const Point& rhs) {
        return lhs.x() * rhs.x() + lhs.y() * rhs.y();
    }
    friend Real Cross(const Point& lhs, const Point& rhs) {
        return lhs.x() * rhs.y() - lhs.y() * rhs.x();
    }
    friend Real Argument(const Point& lhs, const Point& rhs) {
        return rhs.argument() - lhs.argument();
    }
    friend bool ArgComp(const Point& lhs, const Point& rhs) {
        return Smaller(lhs.argument(), rhs.argument());
    }
};

using Vector = Point;

} // namespace geometryR2

} // namespace zawa


namespace zawa {

namespace geometryR2 {

enum RELATION {
    // p0 -> p1 -> p2の順で直線上に並んでいる
    ONLINE_FRONT = -2,
    // (p1 - p0) -> (p2 - p0)が時計回りになっている
    CLOCKWISE,
    // p0 -> p2 -> p1の順で直線上に並んでいる
    ON_SEGMENT,
    // (p1 - p0) -> (p2 - p0)が反時計回りになっている
    COUNTER_CLOCKWISE,
    // p2 -> p0 -> p1、またはp1 -> p0 -> p2の順で直線上に並んでいる
    ONLINE_BACK
};

RELATION Relation(const Point& p0, const Point& p1, const Point& p2) {
    Point a{p1 - p0}, b{p2 - p0};
    if (Positive(Cross(a, b))) return COUNTER_CLOCKWISE;
    if (Negative(Cross(a, b))) return CLOCKWISE;
    if (Negative(Dot(a, b))) return ONLINE_BACK;
    if (Smaller(a.normSquare(), b.normSquare())) return ONLINE_FRONT;
    return ON_SEGMENT;
};

} // namespace geometryR2

} // namespace zawa


namespace zawa {

namespace geometryR2 {

Real Distance(const Point& p0, const Point& p1) {
    return Point{p1 - p0}.norm();
}

Real DistanceSquare(const Point& p0, const Point& p1) {
    return Point{p1 - p0}.normSquare();
}

} // namespace geometryR2

} // namespace zawa


namespace zawa {

namespace geometryR2 {

class Segment {
private:
    Point p0_{}, p1_{};
public:
    /* constructor */
    Segment() = default;
    Segment(const Point& p0, const Point& p1) : p0_{p0}, p1_{p1} {}
    Segment(Real x0, Real y0, Real x1, Real y1) : p0_{x0, y0}, p1_{x1, y1} {}

    /* getter setter */
    const Point& p0() const {
        return p0_;
    }
    Point& p0() {
        return p0_;
    }
    const Point& p1() const {
        return p1_;
    }
    Point& p1() {
        return p1_;
    }

    /* member function */
    bool valid() const {
        return p0_ != p1_;
    }
    bool straddle(const Segment& s) const {
        return Relation(p0_, p1_, s.p0()) * Relation(p0_, p1_, s.p1()) <= 0;
    }
    Real length() const {
        assert(valid());
        return Distance(p0_, p1_);
    }
    Point midpoint() const {
        assert(valid());
        return p0_ + Vector{p1_ - p0_} / static_cast<Real>(2);
    }
};

} // namespace geometryR2

} // namespace zawa



namespace zawa {

namespace geometryR2 {

bool Intersect(const Segment& s0, const Segment& s1) {
    assert(s0.valid());
    assert(s1.valid());
    return s0.straddle(s1) and s1.straddle(s0);
}

} // namespace geometryR2

} // namespace zawa




namespace zawa {

namespace geometryR2 {

bool Parallel(const Segment& s0, const Segment& s1) {
    assert(s0.valid());
    assert(s1.valid());
    return Zero(Cross(s0.p1() - s0.p0(), s1.p1() - s1.p0()));
}

} // namespace geometryR2

} // namespace zawa


namespace zawa {

namespace geometryR2 {

Point CrossPoint(const Segment& s0, const Segment& s1) {
    assert(s0.valid());
    assert(s1.valid());
    assert(Intersect(s0, s1));
    if (Parallel(s0, s1)) {
        if (s0.p0() == s1.p0()) {
            if (Relation(s0.p0(), s0.p1(), s1.p1()) == ONLINE_BACK) {
                return s0.p0();
            }
            else {
                assert(false);
            }
        }
        else if (s0.p0() == s1.p1()) {
            if (Relation(s0.p0(), s0.p1(), s1.p0()) == ONLINE_BACK) {
                return s0.p0();
            }
            else {
                assert(false);
            }
        }
        else if (s0.p1() == s1.p0()) {
            if (Relation(s0.p1(), s0.p0(), s1.p1()) == ONLINE_BACK) {
                return s0.p1();
            }
            else {
                assert(false);
            }
        }
        else if (s0.p1() == s1.p1()) {
            if (Relation(s0.p1(), s0.p0(), s1.p0()) == ONLINE_BACK) {
                return s0.p1();
            }
            else {
                assert(false);
            }
        }
        else {
            assert(false);
        }
    }
    else {
        Vector base{s0.p1() - s0.p0()};
        Real baseNorm{base.norm()};
        Real r1{Abs(Cross(base, s1.p0() - s0.p0())) / baseNorm};
        Real r2{Abs(Cross(base, s1.p1() - s0.p0())) / baseNorm};
        return s1.p0() + (s1.p1() - s1.p0()) * (r1 / (r1 + r2));
    }
}

} // namespace geometryR2

} // namespace zawa



namespace zawa {

namespace geometryR2 {

Real Distance(const Point& p, const Segment& s) {
    assert(s.valid());
    if (Negative(Dot(s.p1() - s.p0(), p - s.p0()))) {
        return Distance(p, s.p0());
    }
    if (Negative(Dot(s.p0() - s.p1(), p - s.p1()))) {
        return Distance(p, s.p1());
    }
    return Abs(Cross(s.p1() - s.p0(), p - s.p0())) / s.length();
}

bool PointOnSegment(const Point& p, const Segment& s) {
    assert(s.valid());
    return Zero(Distance(p, s));
}

} // namespace geometryR2

} // namespace zawa

using namespace zawa;
using namespace geometryR2;

void solve() {
    Segment AB;
    std::cin >> AB.p0() >> AB.p1();
    int N;
    std::cin >> N;
    using item = std::tuple<Real, int, int>;
    std::vector<item> P;
    P.reserve(N);
    for (int i{} ; i < N ; i++) {
        Segment ST;
        std::cin >> ST.p0() >> ST.p1();
        int o, l;
        std::cin >> o >> l;
        if (!AB.valid()) {
            continue;
        }
        if (ST.valid()) {
            if (!Intersect(AB, ST)) continue;
            Point cp{CrossPoint(AB, ST)};
            P.emplace_back(Distance(AB.p0(), cp), o, l);
        }
        else {
            if (Zero(Distance(ST.p0(), AB))) {
                Point cp{ST.p0()};
                P.emplace_back(Distance(AB.p0(), cp), o, l);
            }
        }
    }
    if (!AB.valid()) {
        std::cout << 0 << '\n';
        return;
    }
    std::sort(P.begin(), P.end());
    // 地下....0
    // 高架....1
    int ans[2]{ 0, 0 }, cur[2]{ 0, 1 };
    for (const auto& [d, o, l] : P) {
        for (int i{} ; i < 2 ; i++) {
            if (o == 1) { // 自社
                if (cur[i] != l) {
                    cur[i] ^= 1;
                    ans[i]++;
                }
            }
            else if (o == 0) { // 他社
                if (cur[i] == l) {
                    cur[i] ^= 1;
                    ans[i]++;
                }
            }
            else {
                assert(false);
            }
        }
    }
    std::cout << std::min(ans[0], ans[1]) << '\n';
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int T;
    std::cin >> T;
    while (T--) {
        solve();
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3464
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (int i = 0; i < (int) (n); i++)
template<class T>
void chmax(T& p, T q) { if (p < q)p = q; };

using point=pair<double,double>;

double EPS=1e-12;
void solve() {
    cout<<fixed<<setprecision(14);
    point P,Q;
    cin>>P.first>>P.second>>Q.first>>Q.second;
    double dx=P.first-Q.first;
    double dy=P.second-Q.second;
    vector<pair<double,int>> C;
    ll N;
    cin>>N;
    rep(i,N){
        point S,T;
        int f,g;
        cin>>S.first>>S.second>>T.first>>T.second;
        cin>>f>>g;
        double DX=S.first-T.first;
        double DY=S.second-T.second;

        if(abs(dy*DX-dx*DY)<EPS)continue;

        double RX=T.first-Q.first;
        double RY=T.second-Q.second;
        double a=(RX*DY-RY*DX)/(dx*DY-dy*DX);
        double b;
        if(DX!=0)b=(a*dx-RX)/DX;
        else b=(a*dy-RY)/DY;
        if(a>1.0||a<0.0||b<0.0||b>1.0)continue;
        C.push_back({a,f^g});
    }
    sort(all(C));
    int an=0;
    ll CN=C.size();
    rep(i,CN-1)if(C[i].second!=C[i+1].second)an++;
    cout<<an<<endl;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N;
    cin>>N;
    rep(i,N){
        if(N==0)return 0;
        solve();
    }
    
}
accuracy: 1
time_ms: 30
memory_kb: 3436
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using R = long double;
using Point = std::pair<R, R>;
using Segment = std::pair<Point, Point>;

std::istream& operator>>(std::istream& is, Point& p) {
    is >> p.first >> p.second;
    return is;
}
std::ostream& operator<<(std::ostream& os, const Point& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}

const R EPS{1e-11};
bool Positive(R v) {
    return v > EPS;
}
bool Negative(R v) {
    return v < -EPS;
}
bool Zero(R v) {
    return !Positive(v) and !Negative(v);
}
bool Smaller(R a, R b) { // <
    return Negative(a - b);
}
bool Bigger(R a, R b) {
    return Positive(a - b);
}
bool Equal(R a, R b) {
    return Zero(a - b);
}
R Square(R v) {
    return (Zero(v) ? 0.0l : v * v);
}

Point operator+(const Point& p, const Point& q) {
    return Point{p.first + q.first, p.second + q.second};
}
Point operator-(const Point& p, const Point& q) {
    return Point{p.first - q.first, p.second - q.second};
}
Point operator*(const Point& p, R v) {
    return Point{p.first * v, p.second * v};
}
Point operator/(const Point& p, R v) {
    assert(!Zero(v));
    return Point{p.first / v, p.second / v};
}

R NormSquare(const Point& p) {
    return Square(p.first) + Square(p.second);
}
R Norm(const Point& p) {
    return sqrtl(NormSquare(p));
}
R DistanceSquare(const Point& p, const Point& q) {
    return NormSquare(p - q);
}

R Cross(const Point& p, const Point& q) {
    return p.first * q.second - p.second * q.first;
}
R Dot(const Point& p, const Point& q) {
    return p.first * q.first + p.second * q.second;
}

enum RELATION {
    ONLINE_FRONT = -2,
    CLOCKWISE,
    ON_SEGMENT,
    COUNTER_CLOCKWISE,
    ONLINE_BACK
};

RELATION Relation(const Point& p0, const Point& p1, const Point& p2) {
    Point a{p1 - p0}, b{p2 - p0};
    if (Positive(Cross(a, b))) return COUNTER_CLOCKWISE;
    if (Negative(Cross(a, b))) return CLOCKWISE;
    if (Negative(Dot(a, b))) return ONLINE_BACK;
    if (Smaller(NormSquare(a), NormSquare(b))) return ONLINE_FRONT;
    return ON_SEGMENT;
}

bool Straddle(const Segment& s, const Segment& t) {
    return Relation(s.first, s.second, t.first) * Relation(s.first, s.second, t.second) <= 0;
}

bool Intersect(const Segment& s, const Segment& t) {
    return Straddle(s, t) and Straddle(t, s);
}

Point CrossPoint(const Segment& s, const Segment& t) {
    assert(Intersect(s, t));
    Point base{s.second - s.first};
    R baseNorm{Norm(base)};
    R r1{std::abs(Cross(base, t.first - s.first)) / baseNorm};
    R r2{std::abs(Cross(base, t.second - s.first)) / baseNorm};
    return t.first + (t.second - t.first) * (r1 / (r1 + r2));
}

void solve() {
    Point A, B;
    std::cin >> A >> B;
    Segment S{A, B};
    int N;
    std::cin >> N;
    std::vector<std::pair<R, std::pair<int, int>>> C;
    C.reserve(N);
    for (int i{} ; i < N ; i++) {
        Point p, q;
        std::cin >> p >> q;
        Segment T{p, q};
        int o, l;
        std::cin >> o >> l;
        if (!Intersect(S, T)) continue;
        Point crossPoint{CrossPoint(S, T)};
        C.emplace_back(DistanceSquare(A, crossPoint), std::make_pair(o, l));
    }
    std::sort(C.begin(), C.end());
    std::pair<int, int> score[2];
    score[0] = std::pair<int, int>{ 0, 0 };
    score[1] = std::pair<int, int>{ 0, 1 };
    for (const auto& [_, P] : C) {
        auto [o, l]{P};
        for (int i{} ; i < 2 ; i++) {
            if (o == 0) { // other
                if (l == score[i].second) {
                    score[i].first++;
                    score[i].second ^= 1;
                }
            }
            else if (o == 1) { // my
                if (l != score[i].second) {
                    score[i].first++;
                    score[i].second ^= 1;
                }
            }
            else {
                assert(false);
            }
        }
    }
    std::cout << std::min(score[0].first, score[1].first) << '\n';
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int T;
    std::cin >> T;
    while (T--) {
        solve();
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3564
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
using Real = long double;
const Real EPS = 1e-8, PI = acos(Real(-1.0));
int sign(const Real& r) {
    if(r <= -EPS) return -1;
    if(r >= +EPS) return +1;
    return 0;
}
bool eq(const Real& a, const Real& b) {
    return sign(a - b) == 0;
}
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, const Point& p) {
    return os << p.real() << " " << p.imag();
}
Point operator*(const Point& p, const Real& d) {
    return Point(p.real() * d, p.imag() * d);
}
Point operator/(const Point& p, const Real& d) {
    return Point(p.real() / d, p.imag() / d);
}
Point rot(const Point& p, Real theta) {
    return p * Point(cos(theta), sin(theta));
}
Real dot(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).real();
}
Real cross(const Point& p1, const Point& p2) {
    return (conj(p1) * p2).imag();
}
Real dist(const Point& p1, const Point& p2) {
    return abs(p1 - p2);
}
bool comp_x(const Point& p1, const Point& p2) {
    return eq(p1.real(), p2.real()) ? p1.imag() < p2.imag() : p1.real() < p2.real();
}
bool comp_y(const Point& p1, const Point& p2) {
    return eq(p1.imag(), p2.imag()) ? p1.real() < p2.real() : p1.imag() < p2.imag();
}
bool comp_arg(const Point& p1, const Point& p2) {
    return arg(p1) < arg(p2);
}
int ccw(const Point& a, Point b, Point c) {
    b -= a;
    c -= a;
    if(sign(cross(b, c)) == 1) return 1;
    if(sign(cross(b, c)) == -1) return -1;
    if(sign(dot(b, c)) == -1) return +2;
    if(norm(b) < norm(c)) return -2;
    return 0;
}
Real closest_pair(vector<Point> ps) {
    if((int)ps.size() <= 1) return 1e18;
    sort(ps.begin(), ps.end(), comp_x);
    vector<Point> memo(ps.size());
    auto func = [&](auto& func, int l, int r) -> Real {
        if(r - l <= 1) return 1e18;
        int m = (l + r) >> 1;
        Real x = ps[m].real();
        Real res = min(func(func, l, m), func(func, m, r));
        inplace_merge(ps.begin() + l, ps.begin() + m, ps.begin() + r, comp_y);
        int cnt = 0;
        for(int i = l; i < r; ++i) {
            if(abs(ps[i].real() - x) >= res) continue;
            for(int j = 0; j < cnt; ++j) {
                Point d = ps[i] - memo[cnt - j - 1];
                if(d.imag() >= res) break;
                res = min(res, abs(d));
            }
            memo[cnt++] = ps[i];
        }
        return res;
    };
    return func(func, 0, (int)ps.size());
}
struct Line {
    Point a, b;
    Line() = default;
    Line(const Point& a, const Point& b)
        : a(a), b(b) {}
};
using Segment = Line;
bool is_parallel(const Line& a, const Line& b) {
    return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}
bool is_orthogonal(const Line& a, const Line& b) {
    return eq(dot(a.b - a.a, b.b - b.a), 0.0);
}
Point projection(const Line& l, const Point& p) {
    Real t = dot(p - l.a, l.b - l.a) / norm(l.b - l.a);
    return l.a + (l.b - l.a) * t;
}
Point reflection(const Line& l, const Point& p) {
    return p + (projection(l, p) - p) * 2.0;
}
bool is_intersect_lp(const Line& l, const Point& p) {
    return abs(ccw(l.a, l.b, p)) != 1;
}
bool is_intersect_sp(const Segment& s, const Point& p) {
    return ccw(s.a, s.b, p) == 0;
}
bool is_intersect_ll(const Line& l1, const Line& l2) {
    if(!eq(cross(l1.b - l1.a, l2.b - l2.a), 0.0)) return true;
    return eq(cross(l1.b - l1.a, l2.b - l1.a), 0.0);
}
bool is_intersect_ls(const Line& l, const Segment& s) {
    return sign(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a)) <= 0;
}
bool is_intersect_sl(const Segment& s, const Line& l) {
    return is_intersect_ls(l, s);
}
bool is_intersect_ss(const Segment& s1, const Segment& s2) {
    if(ccw(s1.a, s1.b, s2.a) * ccw(s1.a, s1.b, s2.b) > 0) return false;
    return ccw(s2.a, s2.b, s1.a) * ccw(s2.a, s2.b, s1.b) <= 0;
}
vector<Point> intersection_ll(const Line& l1, const Line& l2) {
    vector<Point> res;
    if(!is_intersect_ll(l1, l2)) return res;
    Real a = cross(l1.b - l1.a, l2.b - l2.a);
    Real b = cross(l1.b - l1.a, l1.b - l2.a);
    if(eq(a, 0.0) and eq(b, 0.0)) {
        res.push_back(l2.a);
    } else {
        res.push_back(l2.a + (l2.b - l2.a) * b / a);
    }
    return res;
}
vector<Point> intersection_ss(const Segment& s1, const Segment& s2) {
    return is_intersect_ss(s1, s2) ? intersection_ll(Line(s1), Line(s2)) : vector<Point>();
}
Real dist_lp(const Line& l, const Point& p) {
    return abs(p - projection(l, p));
}
Real dist_sp(const Segment& s, const Point& p) {
    Point h = projection(s, p);
    if(is_intersect_sp(s, h)) return abs(h - p);
    return min(abs(s.a - p), abs(s.b - p));
}
Real dist_ll(const Line& l1, const Line& l2) {
    if(is_intersect_ll(l1, l2)) return 0.0;
    return dist_lp(l1, l2.a);
}
Real dist_ss(const Segment& s1, const Segment& s2) {
    if(is_intersect_ss(s1, s2)) return 0.0;
    return min({dist_sp(s1, s2.a), dist_sp(s1, s2.b), dist_sp(s2, s1.a), dist_sp(s2, s1.b)});
}
Real dist_ls(const Line& l, const Segment& s) {
    if(is_intersect_ls(l, s)) return 0.0;
    return min(dist_lp(l, s.a), dist_lp(l, s.b));
}
Real dist_sl(const Segment& s, const Line& l) {
    return dist_ls(l, s);
}
struct Point2 {
    Point p;
    int o, l;
};
int main(void) {
    int tc;
    cin >> tc;
    while(tc--) {
        Point a, b;
        cin >> a >> b;
        Segment c = {a, b};
        int n;
        cin >> n;
        vector<Segment> seg(n);
        vector<int> o(n), l(n);
        vector<Point2> intersection;
        rep(i, 0, n) {
            Point s, t;
            cin >> s >> t;
            seg[i] = {s, t};
            cin >> o[i] >> l[i];
            o[i] = 1 - o[i];
            vector<Point> inter = intersection_ss(c, seg[i]);
            if(inter.empty()) continue;
            intersection.push_back({inter[0], o[i], l[i]});
        }
        if(intersection.empty()) {
            cout << 0 << '\n';
            continue;
        }
        auto comp = [&](const Point2& p, const Point2& q) -> bool {
            return abs(p.p - a) < abs(q.p - a);
        };
        sort(intersection.begin(), intersection.end(), comp);
        int ans = 0;
        int cur = intersection[0].l xor intersection[0].o;
        rep(i, 1, (int)intersection.size()) {
            int nex = intersection[i].l xor intersection[i].o;
            if(nex != cur) {
                ans++;
                cur = nex;
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3636
final_rank: 10

code_snippet: #line 1 "2003.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/2003"

#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Real.hpp"

#line 2 "/home/zawatin/compro/cp-documentation/Src/Template/TypeAlias.hpp"

#include <cstdint>
#include <cstddef>

namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa
#line 4 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Real.hpp"

#include <cmath>
#include <cassert>

namespace zawa {

namespace geometryR2 {

using Real = long double;
constexpr Real EPS{1e-12};

namespace internal {

constexpr i32 negative{-1};
constexpr i32 zero{};
constexpr i32 positive{1};

} // namespace internal

constexpr i32 Sign(Real value) {
    if (value < -EPS) return internal::negative;
    if (value > EPS) return internal::positive;
    return internal::zero;
}

constexpr bool Zero(Real value) {
    return Sign(value) == internal::zero;
}

constexpr bool Positive(Real value) {
    return Sign(value) == internal::positive;
}

constexpr bool Negative(Real value) {
    return Sign(value) == internal::negative;
}

constexpr bool Equal(Real a, Real b) {
    return Zero(a - b);
}

constexpr bool Smaller(Real a, Real b) {
    return Negative(a - b);
}

constexpr bool Bigger(Real a, Real b) {
    return Positive(a - b);
}

constexpr Real Square(Real value) {
    return (Zero(value) ? value : value * value);
}

constexpr Real Sqrt(Real value) {
    assert(!Negative(value));
    return (Zero(value) ? value : sqrtl(value));
}

constexpr Real Abs(Real value) {
    return (Negative(value) ? -value : value);
}

} // namespace geometryR2
 
} // namespace zawa
#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Segment.hpp"

#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Point.hpp"

#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Angle.hpp"

#line 4 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Angle.hpp"

#line 6 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Angle.hpp"

namespace zawa {

namespace geometryR2 {

constexpr Real PI{acosl(-1)};
constexpr Real TAU{static_cast<Real>(2) * PI};

constexpr Real ArcToRadian(Real arc) {
    return (arc * PI) / static_cast<Real>(180);
}

constexpr Real RadianToArc(Real radian) {
    return (radian * static_cast<Real>(180)) / PI;
}

} // namespace geometryR2

} // namespace zawa
#line 5 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Point.hpp"

#line 7 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Point.hpp"
#include <iostream>
#line 9 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Point.hpp"

namespace zawa {

namespace geometryR2 {

class Point {
private:
    Real x_{}, y_{};
public:
    /* constructor */
    Point() = default;
    Point(Real x, Real y) : x_{x}, y_{y} {}

    /* getter, setter */
    Real x() const {
        return x_;
    }
    Real& x() {
        return x_;
    }
    Real y() const {
        return y_;
    }
    Real& y() {
        return y_;
    }

    /* operator */
    Point& operator+=(const Point& rhs) {
        x_ += rhs.x();
        y_ += rhs.y();
        return *this;
    }
    friend Point operator+(const Point& lhs, const Point& rhs) {
        return Point{lhs} += rhs;
    }
    Point operator+() const {
        return *this;
    }
    Point& operator-=(const Point& rhs) {
        x_ -= rhs.x();
        y_ -= rhs.y();
        return *this;
    }
    friend Point operator-(const Point& lhs, const Point& rhs) {
        return Point{lhs} -= rhs;
    }
    Point operator-() const {
        return Point{} - *this;
    }
    Point& operator*=(Real k) {
        x_ *= k;
        y_ *= k;
        return *this;
    }
    friend Point operator*(Real k, const Point& p) {
        return Point{p} *= k;
    }
    friend Point operator*(const Point& p, Real k) {
        return Point{p} *= k;
    }
    Point& operator/=(Real k) {
        assert(!Zero(k));
        x_ /= k;
        y_ /= k;
        return *this;
    }
    friend Point operator/(Real k, const Point& p) {
        return Point{p} /= k;
    }
    friend Point operator/(const Point& p, Real k) {
        return Point{p} /= k;
    }
    friend bool operator==(const Point& lhs, const Point& rhs) {
        return Equal(lhs.x(), rhs.x()) and Equal(lhs.y(), rhs.y());
    }
    friend bool operator!=(const Point& lhs, const Point& rhs) {
        return !Equal(lhs.x(), rhs.x()) or !Equal(lhs.y(), rhs.y());
    }
    friend bool operator<(const Point& lhs, const Point& rhs) {
        return Smaller(lhs.x(), rhs.x()) or 
            (Equal(lhs.x(), rhs.x()) and Smaller(lhs.y(), rhs.y()));
    }
    friend bool operator<=(const Point& lhs, const Point& rhs) {
        return Smaller(lhs.x(), rhs.x()) or 
            (Equal(lhs.x(), rhs.x()) and (Smaller(lhs.y(), rhs.y()) or Equal(lhs.y(), rhs.y())));
    }
    friend bool operator>(const Point& lhs, const Point& rhs) {
        return Bigger(lhs.x(), rhs.x()) or
            (Equal(lhs.x(), rhs.x()) and Bigger(lhs.y(), rhs.y()));
    }
    friend bool operator>=(const Point& lhs, const Point& rhs) {
        return Bigger(lhs.x(), rhs.x()) or
            (Equal(lhs.x(), rhs.x()) and (Bigger(lhs.y(), rhs.y()) or Equal(lhs.y(), rhs.y())));
    }
    friend std::istream& operator>>(std::istream& is, Point& p) {
        is >> p.x_ >> p.y_;
        return is;
    }
    friend std::ostream& operator<<(std::ostream& os, const Point& p) {
        os << '(' << p.x_ << ',' << p.y_ << ')';
        return os;
    }
    
    /* member function */
    Real normSquare() const {
        return Square(x_) + Square(y_);
    }
    Real norm() const {
        return Sqrt(normSquare());
    }
    void normalize() {
        assert((*this) != Point{});
        (*this) /= norm(); 
    }
    Point normalized() const {
        Point res{*this};
        res.normalize();
        return res;
    }
    Point rotated(Real radian) const {
        return Point{
            x_ * cosl(radian) - y_ * sinl(radian),
            x_ * sinl(radian) + y_ * cosl(radian)
        };
    }
    void rotate(Real radian) {
        *this = rotated(radian); 
    }
    Point rotatedByArc(Real arc) const {
        return rotated(ArcToRadian(arc));
    }
    void rotateByArc(Real arc) {
        *this = rotatedByArc(arc);
    }
    Real argument() const {
        return (Negative(y_) ? TAU : static_cast<Real>(0)) + atan2l(y_, x_);
    }
    Real argumentByArc() const {
        return RadianToArc(argument());
    }

    /* friend function */
    friend Real Dot(const Point& lhs, const Point& rhs) {
        return lhs.x() * rhs.x() + lhs.y() * rhs.y();
    }
    friend Real Cross(const Point& lhs, const Point& rhs) {
        return lhs.x() * rhs.y() - lhs.y() * rhs.x();
    }
    friend Real Argument(const Point& lhs, const Point& rhs) {
        return rhs.argument() - lhs.argument();
    }
    friend bool ArgComp(const Point& lhs, const Point& rhs) {
        return Smaller(lhs.argument(), rhs.argument());
    }
};

using Vector = Point;

} // namespace geometryR2

} // namespace zawa
#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Relation.hpp"

#line 5 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Relation.hpp"

namespace zawa {

namespace geometryR2 {

enum RELATION {
    // p0 -> p1 -> p2の順で直線上に並んでいる
    ONLINE_FRONT = -2,
    // (p1 - p0) -> (p2 - p0)が時計回りになっている
    CLOCKWISE,
    // p0 -> p2 -> p1の順で直線上に並んでいる
    ON_SEGMENT,
    // (p1 - p0) -> (p2 - p0)が反時計回りになっている
    COUNTER_CLOCKWISE,
    // p2 -> p0 -> p1、またはp1 -> p0 -> p2の順で直線上に並んでいる
    ONLINE_BACK
};

RELATION Relation(const Point& p0, const Point& p1, const Point& p2) {
    Point a{p1 - p0}, b{p2 - p0};
    if (Positive(Cross(a, b))) return COUNTER_CLOCKWISE;
    if (Negative(Cross(a, b))) return CLOCKWISE;
    if (Negative(Dot(a, b))) return ONLINE_BACK;
    if (Smaller(a.normSquare(), b.normSquare())) return ONLINE_FRONT;
    return ON_SEGMENT;
};

} // namespace geometryR2

} // namespace zawa
#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Distance/PointAndPoint.hpp"

#line 4 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Distance/PointAndPoint.hpp"

namespace zawa {

namespace geometryR2 {

Real Distance(const Point& p0, const Point& p1) {
    return Point{p1 - p0}.norm();
}

Real DistanceSquare(const Point& p0, const Point& p1) {
    return Point{p1 - p0}.normSquare();
}

} // namespace geometryR2

} // namespace zawa
#line 6 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Segment.hpp"

#include <algorithm>
#line 9 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Segment.hpp"

namespace zawa {

namespace geometryR2 {

class Segment {
private:
    Point p0_{}, p1_{};
public:
    /* constructor */
    Segment() = default;
    Segment(const Point& p0, const Point& p1) : p0_{p0}, p1_{p1} {}
    Segment(Real x0, Real y0, Real x1, Real y1) : p0_{x0, y0}, p1_{x1, y1} {}

    /* getter setter */
    const Point& p0() const {
        return p0_;
    }
    Point& p0() {
        return p0_;
    }
    const Point& p1() const {
        return p1_;
    }
    Point& p1() {
        return p1_;
    }

    /* member function */
    bool valid() const {
        return p0_ != p1_;
    }
    bool straddle(const Segment& s) const {
        return Relation(p0_, p1_, s.p0()) * Relation(p0_, p1_, s.p1()) <= 0;
    }
    Real length() const {
        assert(valid());
        return Distance(p0_, p1_);
    }
};

} // namespace geometryR2

} // namespace zawa
#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Distance/PointAndSegment.hpp"

#line 7 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Distance/PointAndSegment.hpp"

#line 9 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Distance/PointAndSegment.hpp"

namespace zawa {

namespace geometryR2 {

Real Distance(const Point& p, const Segment& s) {
    assert(s.valid());
    if (Negative(Dot(s.p1() - s.p0(), p - s.p0()))) {
        return Distance(p, s.p0());
    }
    if (Negative(Dot(s.p0() - s.p1(), p - s.p1()))) {
        return Distance(p, s.p1());
    }
    return Abs(Cross(s.p1() - s.p0(), p - s.p0())) / s.length();
}

bool PointOnSegment(const Point& p, const Segment& s) {
    assert(s.valid());
    return Zero(Distance(p, s));
}

} // namespace geometryR2

} // namespace zawa
#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Intersect/SegmentAndSegment.hpp"

#line 4 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Intersect/SegmentAndSegment.hpp"

#line 6 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Intersect/SegmentAndSegment.hpp"

namespace zawa {

namespace geometryR2 {

bool Intersect(const Segment& s0, const Segment& s1) {
    assert(s0.valid());
    assert(s1.valid());
    return s0.straddle(s1) and s1.straddle(s0);
}

} // namespace geometryR2

} // namespace zawa
#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/CrossPoint/SegmentAndSegment.hpp"

#line 2 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Parallel/SegmentAndSegment.hpp"

#line 4 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Parallel/SegmentAndSegment.hpp"

#line 6 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/Parallel/SegmentAndSegment.hpp"

namespace zawa {

namespace geometryR2 {

bool Parallel(const Segment& s0, const Segment& s1) {
    assert(s0.valid());
    assert(s1.valid());
    return Zero(Cross(s0.p1() - s0.p0(), s1.p1() - s1.p0()));
}

} // namespace geometryR2

} // namespace zawa
#line 7 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/CrossPoint/SegmentAndSegment.hpp"

#line 9 "/home/zawatin/compro/cp-documentation/Src/GeometryR2/CrossPoint/SegmentAndSegment.hpp"

namespace zawa {

namespace geometryR2 {

Point CrossPoint(const Segment& s0, const Segment& s1) {
    assert(s0.valid());
    assert(s1.valid());
    assert(Intersect(s0, s1));
    if (Parallel(s0, s1)) {
        if (s0.p0() == s1.p0()) {
            if (Relation(s0.p0(), s0.p1(), s1.p1()) == ONLINE_BACK) {
                return s0.p0();
            }
            else {
                assert(false);
            }
        }
        else if (s0.p0() == s1.p1()) {
            if (Relation(s0.p0(), s0.p1(), s1.p0()) == ONLINE_BACK) {
                return s0.p0();
            }
            else {
                assert(false);
            }
        }
        else if (s0.p1() == s1.p0()) {
            if (Relation(s0.p1(), s0.p0(), s1.p1()) == ONLINE_BACK) {
                return s0.p1();
            }
            else {
                assert(false);
            }
        }
        else if (s0.p1() == s1.p1()) {
            if (Relation(s0.p1(), s0.p0(), s1.p0()) == ONLINE_BACK) {
                return s0.p1();
            }
            else {
                assert(false);
            }
        }
        else {
            assert(false);
        }
    }
    else {
        Vector base{s0.p1() - s0.p0()};
        Real baseNorm{base.norm()};
        Real r1{Abs(Cross(base, s1.p0() - s0.p0())) / baseNorm};
        Real r2{Abs(Cross(base, s1.p1() - s0.p0())) / baseNorm};
        return s1.p0() + (s1.p1() - s1.p0()) * (r1 / (r1 + r2));
    }
}

} // namespace geometryR2

} // namespace zawa
#line 9 "2003.test.cpp"

#line 12 "2003.test.cpp"
#include <vector>

using namespace zawa::geometryR2;

struct item {
    Segment seg{};
    int have{};
    int h{};
    item() = default;
};

void solve() {
    Segment s;
    std::cin >> s.p0() >> s.p1(); 
    int n; std::cin >> n;
    std::vector<item> a(n);
    for (auto& i : a) {
        std::cin >> i.seg.p0() >> i.seg.p1();
        std::cin >> i.have >> i.h;
    }
    std::vector<Point> cross(n);
    std::vector<int> index;
    for (int i{} ; i < n ; i++) {
        if (a[i].seg.valid()) {
            if (!Intersect(s, a[i].seg)) continue;
            cross[i] = CrossPoint(s, a[i].seg);
            index.emplace_back(i);
        }
        else {
            if (!PointOnSegment(a[i].seg.p0(), s)) continue;
            cross[i] = a[i].seg.p0();
            index.emplace_back(i);
        }
    }
    std::sort(index.begin(), index.end(), [&](int i, int j) -> bool {
            return Smaller(Distance(s.p0(), cross[i]), Distance(s.p0(), cross[j]));
            });
    int dp[2]{0,0};
    for (auto i : index) {
        int nxt[2]{100000,100000};
        if (a[i].have == 0) {
            if (a[i].h == 0) {
                nxt[1] = std::min(dp[0] + 1, dp[1]);
            }
            else {
                nxt[0] = std::min(dp[0], dp[1] + 1);
            }
        }
        else {
            if (a[i].h == 0) {
                nxt[0] = std::min(dp[0], dp[1] + 1);
            }
            else {
                nxt[1] = std::min(dp[0] + 1, dp[1]);
            }
        }
        dp[0] = nxt[0];
        dp[1] = nxt[1];
    }
    int ans{std::min(dp[0], dp[1])};
    std::cout << ans << '\n';
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n; std::cin >> n;
    for (int i{} ; i < n ; i++) {
        solve();
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3580
final_rank: 9