Problem:
Railroad Conflict

Nate U. Smith は大都市圏の鉄道会社を経営している．この大都市圏には，彼の鉄道会社以外にライバルの鉄道会社がある．2 社は互いに競合関係にある．

この大都市圏では，列車の運行を容易にするため，全ての路線は両端の駅を結んだ線分を経路としている．また，踏切等の設置をさけるため，全ての路線は高架または地下に敷設されている．既存路線は，全線にわたって高架を走るか，または全線にわたって地下を走るかのいずれかである．

ところで，最近，この大都市圏にある 2 つの街区 A，B がさかんに開発されていることから，Nate の会社ではこれらの街区の間に新しい路線を設けることを決断した．この新路線は，従来の路線と同様に A，B を両端とする線分を経路としたいが，経路の途中には別の路線があることから，高架あるいは地下のいずれかに全線を敷設することは不可能である．そこで，路線の一部を高架に，残りの部分を地下に敷設することにした．このとき，新路線が自社の既存路線と交わるところでは，新路線と既存路線との間の乗り継ぎを便利にするため，既存路線が高架ならば新路線も高架に，既存路線が地下ならば新路線も地下を走るようにする．また，新路線が他社の既存路線と交わるところでは，他社による妨害をさけるため，既存路線が高架ならば新路線は地下に，既存路線が地下ならば新路線は高架を走るようにする．A 駅および B 駅をそれぞれ高架あるいは地下のいずれに設けるかは特に問わない．

当然のことながら，新路線が高架から地下に，あるいは地下から高架に移るところには出入口を設けなければならない．ところが，出入口を設けるためには費用がかかるため，新路線に設ける出入口の個数は最小限に抑えたい．それには，プログラマであるあなたの助けを要すると考えた Nate は，あなたを彼の会社に呼び出した．

あなたの仕事は，A 駅，B 駅の位置，そして既存路線に関する情報が与えられたときに，新路線において最低限設けなければならない出入口の個数を求めるプログラムを作成することである．

以下の図は，サンプルとして与えた入力および出力の内容を示したものである．

Input

入力の先頭行には単一の正の整数が含まれ，これはデータセットの個数を表す．それぞれのデータセットは次の形式で与えられる．

xa ya xb yb

n

xs1 ys1 xt1 yt1 o1 l1

xs2 ys2 xt2 yt2 o2 l2

...

xsn ysn xtn ytn on ln

ただし，(xa,ya) および (xb,yb) はそれぞれ A 駅，B 駅の座標を表す．N は既存路線の数を表す 100 以下の正の整数である．(xsi,ysi) および (ysi,yti) は i 番目の既存路線における始点および終点の座標を表す．oi は i 番目の既存路線の所有者を表す整数である．これは 1 または 0 のいずれかであり，1 はその路線が自社所有であることを，0 は他社所有であることをそれぞれ表す．li は 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

Solution in JAVA (judge verdict: Wrong Answer)

import java.awt.geom.Point2D;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	
	static Point2D.Double a, b;
	static int n;
	
	static ArrayList<Point2D.Double> s, t;
	static int[] o, h;
	
	private static double cross(Point2D.Double a, Point2D.Double b)
	{
		return (a.x * b.y - a.y * b.x);
	}
	
	private static Point2D.Double add(Point2D.Double a, Point2D.Double b)
	{
		return new Point2D.Double(a.x + b.x, a.y + b.y);
	}
	
	private static Point2D.Double sub(Point2D.Double a, Point2D.Double b)
	{
		return new Point2D.Double(a.x - b.x, a.y - b.y);
	}
	
	private static Point2D.Double mul(Point2D.Double a, double t)
	{
		return new Point2D.Double(a.x * t, a.y * t);
	}
	
	private static Boolean isCrossing(Point2D.Double a1, Point2D.Double a2, Point2D.Double b1, Point2D.Double b2)
	{
		return (cross(sub(a2, a1), sub(b1, a1)) * cross(sub(a2, a1), sub(b2, a1)) < 1e-10) &&
			   (cross(sub(b2, b1), sub(a1, b1)) * cross(sub(b2, b1), sub(a2, b1)) < 1e-10);
	}
	
	private static Point2D.Double crosspoint(Point2D.Double a1, Point2D.Double a2, Point2D.Double b1, Point2D.Double b2)
	{
		Point2D.Double b = sub(b2, b1);
		double d1 = Math.abs( cross(b, sub(a1, b1)) );
		double d2 = Math.abs( cross(b, sub(a2, b1)) );
		double t = d1 / (d1 + d2);
		return add(a1, mul(sub(a2, a1), t));
	}
	
	public static void main(String[] args)
	{
		
		Scanner sca = new Scanner(System.in);
		
		int allnum = sca.nextInt();
		
		for(;allnum > 0;allnum--)
			{
			
			a = new Point2D.Double(sca.nextDouble(), sca.nextDouble());
			b = new Point2D.Double(sca.nextDouble(), sca.nextDouble());
			
			n = sca.nextInt();
			
			int i, j, k;
			ArrayList<Point2D.Double> crossp = new ArrayList<Point2D.Double>();
			double[] dis;
			
			s = new ArrayList<Point2D.Double>();
			t = new ArrayList<Point2D.Double>();
			o = new int[n];
			h = new int[n];
			crossp = new ArrayList<Point2D.Double>();
			dis = new double[n];
			
			for(i = 0;i < n;i++)
			{
				Point2D.Double ss = new Point2D.Double(sca.nextDouble(), sca.nextDouble());
				Point2D.Double tt = new Point2D.Double(sca.nextDouble(), sca.nextDouble());
				int oo = sca.nextInt();
				int hh = sca.nextInt();
				
				if(isCrossing(a, b, ss, tt))
				{
					s.add(ss);
					t.add(tt);
					o[i] = oo;
					h[i] = hh;
					
					Point2D.Double cp = crosspoint(a, b, ss, tt);
					crossp.add(cp);
					
					double dx = a.x - cp.x;
					double dy = a.y - cp.y;
					dis[i] = Math.sqrt(dx*dx + dy*dy);
				}
				else
				{
					i--;
					n--;
				}
			}
			
			for(i = n;i > 0;i--)
			{
				for(j = 0;j < (i - 1);j++)
				{
					if(dis[j] > dis[j + 1])
					{
						double tmp;
						tmp = dis[j];    dis[j] = dis[j+1];    dis[j+1] = tmp;
						
						int tmpi;
						tmpi = o[j];     o[j] = o[j+1];    o[j+1] = tmpi;
						tmpi = h[j];     h[j] = h[j+1];    h[j+1] = tmpi;
					}
				}
			}
			
			int point = 0;
			int num = 0;
			
			for(i = 0;i < n;i++)
			{
				if(o[i] == 1 && h[i] == 0)
				{
					if(point != 0)
					{
						num++;
						point = 0;
					}
				}
				else if(o[i] == 1 && h[i] == 1)
				{
					if(point != 1)
					{
						num++;
						point = 1;
					}
				}
				else if(o[i] == 0 && h[i] == 0)
				{
					if(point != 1)
					{
						num++;
						point = 1;
					}
				}
				else
				{
					if(point != 0)
					{
						num++;
						point = 0;
					}
				}
			}
			
			if((o[0] == 1 && h[0] == 1) || (o[0] == 0 && h[0] == 0)) num--;
			
			System.out.println(num);
		}
	}
}