Problem:
Counter-Clockwise

For given three points p0, p1, p2, print

COUNTER_CLOCKWISE

if p0, p1, p2 make a counterclockwise turn (1),

CLOCKWISE

if p0, p1, p2 make a clockwise turn (2),

ONLINE_BACK

if p2 is on a line p2, p0, p1 in this order (3),

ONLINE_FRONT

if p2 is on a line p0, p1, p2 in this order (4),

ON_SEGMENT

if p2 is on a segment p0p1 (5).

Input

xp0 yp0 xp1 yp1
q
xp20 yp20
xp21 yp21
...
xp2q-1 yp2q-1

In the first line, integer coordinates of p0 and p1 are given. Then, q queries are given for integer coordinates of p2.

Output

For each query, print the above mentioned status.

Constraints

1 ≤ q ≤ 1000

-10000 ≤ xi, yi ≤ 10000

p0 and p1 are not identical.

Sample Input 1

0 0 2 0
2
-1 1
-1 -1

Sample Output 1

COUNTER_CLOCKWISE
CLOCKWISE

Sample Input 2

0 0 2 0
3
-1 0
0 0
3 0

Sample Output 2

ONLINE_BACK
ON_SEGMENT
ONLINE_FRONT

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Aoj.CGL.Lib;
 
namespace Aoj.CGL.Chapter1C
{
    class Program
    {
        public static string ConvertCcwToStr(Ccw ccw)
        {
            var map = new Dictionary<Ccw, string> (){
                {Ccw.CounterClockwise, "COUNTER_CLOCKWISE"},
                {Ccw.Clockwise, "CLOCKWISE"},
                {Ccw.OnLineBack, "ONLINE_BACK" },
                {Ccw.OnSegment, "ON_SEGMENT"},
                {Ccw.OnLineFront, "ONLINE_FRONT"},
            };
 
            return map[ccw];
        }
 
        public static void Solve()
        {
            int[] input = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
            Vector v1 = new Vector(input[0], input[1]);
            Vector v2 = new Vector(input[2], input[3]);
            Vector baseV = v2 - v1;
 
            int q = int.Parse(Console.ReadLine());
  
            for (int i = 0; i < q; i++)
            {
                int[] x_y = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
 
                Vector v = new Vector(x_y[0], x_y[1]) - v1;
                Ccw ccw = Vector.CountrClockWise(baseV, v);
 
                Console.WriteLine("{0}", ConvertCcwToStr(ccw));
            }
        }
 
        public static void Main()
        {
            // Console.SetIn(new System.IO.StreamReader("ComputationalGeometry/Input/01_Projection_C_03.txt"));
            // var sw = new Stopwatch();
            // sw.Start();
 
            Solve();
 
            // Console.WriteLine("{0}ms", sw.ElapsedMilliseconds);
        }
    }
}
 
namespace Aoj.CGL.Lib
{
    using Line = Segment;
 
    using Polygon = List<Point>;
 
    public enum Ccw
    {
        CounterClockwise,
        Clockwise,
        OnLineBack,
        OnSegment,
        OnLineFront,
    };
 
    public struct Point
    {
        private double _x;
        private double _y;
 
        public double X { get { return _x;} }
        public double Y { get { return _y;} }
 
        public Point(double x, double y)
        {
            _x = x;
            _y = y;
        }
 
        public static Point operator +(Point p1, Point p2)
        {
            return new Point(p1.X + p2.X, p1.Y + p2.Y);
        }
 
        public static Point operator -(Point p1, Point p2)
        {
            return new Point(p1.X - p2.X, p1.Y - p2.Y);
        }
 
        public static Point operator *(Point p, double k)
        {
            return new Point(p.X * k, p.Y * k);
        }
 
        public static Point operator *(double k, Point p)
        {
            return p * k;
        }
 
        public static explicit operator Vector(Point p)
        {
            return new Vector(p.X, p.Y);
        }
 
        public static bool IsOrthogonal(Point a1, Point a2, Point b1, Point b2)
        {
            return Vector.IsOrthogonal((Vector)(a1 - a2), (Vector)(b1 - b2));
        }
 
        public static bool IsParallel(Point a1, Point a2, Point b1, Point b2)
        {
            return Vector.IsParallel((Vector)(a1 - a2), (Vector)(b1 - b2));
        }
 
        public override string ToString()
        {
            return string.Format("x:{0},y:{1}", X, Y);
        }
    }
 
    public struct Segment
    {
        private Point _p1;
        private Point _p2;
 
        public Point P1 { get{ return _p1; } }
        public Point P2 { get{ return _p2; } }
 
        public Segment(Point p1, Point p2)
        {
            _p1 = p1;
            _p2 = p2;
        }
 
        public Segment(double x1, double y1, double x2, double y2)
        {
            _p1 = new Point(x1, y1);
            _p2 = new Point(x2, y2);
        }
        public static bool IsOrthogonal(Segment s1, Segment s2)
        {
            return Vector.IsOrthogonal((Vector)(s1.P1 - s1.P2), (Vector)(s2.P1 - s2.P2));
        }
 
        public static bool IsParallel(Segment s1, Segment s2)
        {
            return Vector.IsParallel((Vector)(s1.P1 - s1.P2), (Vector)(s2.P1 - s2.P2));
        }
 
        public override string ToString()
        {
            return string.Format("P1x:{0},P1y:{1}, P2x:{2},P2y:{3}", P1.X, P1.Y, P2.X, P2.Y);
        }
    }
 
    public struct Circle
    {
        private Point _p;
        private double _r;
 
        public Point P { get { return _p; } }
        public double R { get { return _r; } }
 
        public Circle(Point p, double r)
        {
            _p = p;
            _r = r;
        }
 
        public override string ToString()
        {
            return string.Format("px:{0},py:{1},r:{2}", P.X, P.Y, R);
        }
    }
 
    public struct Vector
    {
        private double _x;
        private double _y;
 
        public double X { get { return _x;} }
        public double Y { get { return _y;} }
 
        public Vector(double x, double y)
        {
            _x = x;
            _y = y;
        }
 
        public double Norm()
        {
            return X * X + Y * Y;
        }
 
        public double Abs()
        {
            return Math.Sqrt(Norm());
        }
 
        public Vector Normalize()
        {
            double mag = Abs();
            return new Vector(X * mag, Y * mag);
        }
 
        public static Vector operator +(Vector v1, Vector v2)
        {
            return new Vector(v1.X + v2.X, v1.Y + v2.Y);
        }
 
        public static Vector operator -(Vector v1, Vector v2)
        {
            return new Vector(v1.X - v2.X, v1.Y - v2.Y);
        }
 
        public static Vector operator *(Vector v, double k)
        {
            return new Vector(v.X * k, v.Y * k);
        }
 
        public static Vector operator *(double k, Vector v)
        {
            return v * k;
        }
 
        public static double Dot(Vector v1, Vector v2)
        {
            return v1.X * v2.X + v1.Y * v2.Y;
        }
 
        public static double Cross(Vector v1, Vector v2)
        {
            return v1.X * v2.Y - v1.Y * v2.X;
        }
 
        public static bool IsOrthogonal(Vector v1, Vector v2)
        {
            return Dot(v1, v2) == 0.0;
        }
 
        public static bool IsParallel(Vector v1, Vector v2)
        {
            return Cross(v1, v2) == 0.0;
        }
 
        public static Vector Project(Vector v, Vector onNormal)
        {
            // mag = |b|cos?? / |a|
            //     = |a||b|cos?? / |a|^2
            double mag = Dot(v, onNormal) / onNormal.Norm();
            return new Vector(onNormal.X * mag, onNormal.Y * mag);
        }
 
        public static Vector Reflect(Vector v, Vector inNormal)
        {
            // TODO Unity?????????¨????????????????????????????????????
            Vector p = Project(v, inNormal);
            return 2.0 * p - v;
        }
 
        public static Ccw CountrClockWise(Vector baseV, Vector v)
        {
            double cross = Cross(baseV, v);
            if (cross > 0.0)
                return Ccw.CounterClockwise;
            else if (cross < 0.0)
                return Ccw.Clockwise;
            else if (Dot(baseV, v) < 0.0)
                return Ccw.OnLineBack;
            else if (baseV.Norm() < v.Norm())
                return Ccw.OnLineFront;
            else
               return Ccw.OnSegment;
        }
 
        public override string ToString()
        {
            return string.Format("x:{0},y:{1}", X, Y);
        }
    }
}