#include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
#include <utility>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double 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; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

bool intersectSS(const L& a, const L& b){
    return ( ccw(a[0],a[1],b[0]) *ccw(a[0],a[1],b[1]) <= 0 ) &&
        ( ccw(b[0],b[1],a[0]) *ccw(b[0],b[1],a[1]) <= 0 );
}
bool intersectSP(const L& s, const P &p){
    return abs(cross(s[0]-p, s[1]-p))<EPS  && dot(s[0]-p, s[1]-p)<EPS;
}

P projection(const L& l, const P& p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
P reflection(const L& l, const P& p) {
    return p + 2.0*(projection(l, p) -p);
}
L reflection(const L& l, const L& m){
    return L(reflection(l, m[0]), reflection(l, m[1]));
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

const int maxrep = 1300;

int main(){
    while(1){
        int sx,sy;
        cin >> sx >> sy;
        if(sx == 0) break;

        P s(sx, sy);
        vector<L> mirror(2);
        for(int d=0; d<2; d++){
            int xs,ys,xt,yt;
            cin >> xs >> ys >> xt >> yt;
            mirror[d] = L(P(xs, ys), P(xt, yt));
        }

        //反射後の鏡・幽霊の位置
        vector<vector<L> > w(2, vector<L>(maxrep));
        vector<vector<P> > p(2, vector<P>(maxrep));
        for(int d=0; d<2; d++){
            w[d][0] = mirror[1-d];
            w[d][1] = mirror[d];
            p[d][0] = s;
            p[d][1] = reflection(w[d][1], p[d][0]);
            for(int i=2; i<maxrep; i++){
                w[d][i] = reflection(w[d][i-1], w[d][i-2]);
                p[d][i] = reflection(w[d][i], p[d][i-1]);
            }
        }
        
        int ans = 0;
        for(int d=0; d<2; d++){
            for(int i=1; i<maxrep && ans<100; i++){
                L ray(p[d][0], p[d][i]);
                //コーナーケース:別の鏡に遮られる
                if(!isParallel(ray, w[d][0]) && intersectSS(ray, w[d][0])){
                    L ray2(crosspointLL(ray, w[d][0]), ray[1]);
                    if(intersectSS(ray2, w[d][1])) continue;
                }
                //順番に通過していればよい
                bool ok = true;
                for(int j=1; j<=i; j++){
                    if(isParallel(ray, w[d][j]) || !intersectSS(ray, w[d][j])){
                        ok = false;
                        break;
                    }
                    ray[0] = crosspointLL(ray, w[d][j]);
                }
                if(ok){
                    ans++;
                }
            }
        }
        if(ans >= 100){
            cout << "TOO MANY" << endl;
        }else{
            cout << ans << endl;
        }
    }
    return 0;
}


### Prompt

Construct a cpp code solution to the problem outlined:

Mr. Hoge is in trouble. He just bought a new mansion, but it’s haunted by a phantom. He asked a famous conjurer Dr. Huga to get rid of the phantom. Dr. Huga went to see the mansion, and found that the phantom is scared by its own mirror images. Dr. Huga set two flat mirrors in order to get rid of the phantom.

As you may know, you can make many mirror images even with only two mirrors. You are to count up the number of the images as his assistant. Given the coordinates of the mirrors and the phantom, show the number of images of the phantom which can be seen through the mirrors.



Input

The input consists of multiple test cases. Each test cases starts with a line which contains two positive integers, px and py (1 ≤ px, py ≤ 50), which are the x- and y-coordinate of the phantom. In the next two lines, each line contains four positive integers ux, uy, vx and vy (1 ≤ ux, uy, vx, vy ≤ 50), which are the coordinates of the mirror.

Each mirror can be seen as a line segment, and its thickness is negligible. No mirror touches or crosses with another mirror. Also, you can assume that no images will appear within the distance of 10-5 from the endpoints of the mirrors.

The input ends with a line which contains two zeros.

Output

For each case, your program should output one line to the standard output, which contains the number of images recognized by the phantom. If the number is equal to or greater than 100, print “TOO MANY” instead.

Example

Input

4 4
3 3 5 3
3 5 5 6
4 4
3 3 5 3
3 5 5 5
0 0


Output

4
TOO MANY

### Response

```cpp
#include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
#include <utility>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};

namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double 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; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

bool intersectSS(const L& a, const L& b){
    return ( ccw(a[0],a[1],b[0]) *ccw(a[0],a[1],b[1]) <= 0 ) &&
        ( ccw(b[0],b[1],a[0]) *ccw(b[0],b[1],a[1]) <= 0 );
}
bool intersectSP(const L& s, const P &p){
    return abs(cross(s[0]-p, s[1]-p))<EPS  && dot(s[0]-p, s[1]-p)<EPS;
}

P projection(const L& l, const P& p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
P reflection(const L& l, const P& p) {
    return p + 2.0*(projection(l, p) -p);
}
L reflection(const L& l, const L& m){
    return L(reflection(l, m[0]), reflection(l, m[1]));
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

const int maxrep = 1300;

int main(){
    while(1){
        int sx,sy;
        cin >> sx >> sy;
        if(sx == 0) break;

        P s(sx, sy);
        vector<L> mirror(2);
        for(int d=0; d<2; d++){
            int xs,ys,xt,yt;
            cin >> xs >> ys >> xt >> yt;
            mirror[d] = L(P(xs, ys), P(xt, yt));
        }

        //反射後の鏡・幽霊の位置
        vector<vector<L> > w(2, vector<L>(maxrep));
        vector<vector<P> > p(2, vector<P>(maxrep));
        for(int d=0; d<2; d++){
            w[d][0] = mirror[1-d];
            w[d][1] = mirror[d];
            p[d][0] = s;
            p[d][1] = reflection(w[d][1], p[d][0]);
            for(int i=2; i<maxrep; i++){
                w[d][i] = reflection(w[d][i-1], w[d][i-2]);
                p[d][i] = reflection(w[d][i], p[d][i-1]);
            }
        }
        
        int ans = 0;
        for(int d=0; d<2; d++){
            for(int i=1; i<maxrep && ans<100; i++){
                L ray(p[d][0], p[d][i]);
                //コーナーケース:別の鏡に遮られる
                if(!isParallel(ray, w[d][0]) && intersectSS(ray, w[d][0])){
                    L ray2(crosspointLL(ray, w[d][0]), ray[1]);
                    if(intersectSS(ray2, w[d][1])) continue;
                }
                //順番に通過していればよい
                bool ok = true;
                for(int j=1; j<=i; j++){
                    if(isParallel(ray, w[d][j]) || !intersectSS(ray, w[d][j])){
                        ok = false;
                        break;
                    }
                    ray[0] = crosspointLL(ray, w[d][j]);
                }
                if(ok){
                    ans++;
                }
            }
        }
        if(ans >= 100){
            cout << "TOO MANY" << endl;
        }else{
            cout << ans << endl;
        }
    }
    return 0;
}


```