#include #include #include #include using namespace std; typedef long double ld; ld eps = 1e-6; struct point { ld x, y; point(ld x, ld y) : x(x), y(y) {} point() {} }; point operator+(point a, point b) { return point(a.x + b.x, a.y + b.y); } point operator*(ld x, point a) { return point(x * a.x, x * a.y); } ld dot(point a, point b) { return a.x * b.x + a.y * b.y; } point vec(point a, point b) { return point(b.x - a.x, b.y - a.y); } ld len(point v) { return sqrt(dot(v, v)); } ld dist(point a, point b) { return len(vec(a, b)); } ld det(point a, point b) { return a.x * b.y - a.y * b.x; } point cast(point a, point b, point p) { point ab = vec(a, b); return a + (dot(ab, vec(a, p)) / dot(ab, ab)) * ab; } pair cut(point a, point b, point x, point y) { if (det(vec(a, b), vec(a, x)) * det(vec(a, b), vec(a, y)) > 0) return pair(false, 0); point c = cast(a, b, x); point d = cast(a, b, y); point i = c + (len(vec(c, x)) / (len(vec(c, x)) + len(vec(d, y)))) * vec(c, d); return pair(true, dist(x, i)); } point reflect(point a, point b, point p) { point c = cast(a, b, p); return p + (2.0 * vec(p, c)); } int n; vector> mirr(8); vector obj(17); point start, p_end; void reflect_all(vector& per, int lim) { for (int i = 0; i < lim; i++) { for (int j = 2 * (i+1); j < 2*n+1; j++) { obj[j] = reflect(obj[2*i], obj[2*i+1], obj[j]); } } } void fill_obj(vector& per) { for (int i = 0; i < n; i++) { obj[2*i] = mirr[per[i]].first; obj[2*i+1] = mirr[per[i]].second; } obj[2*n] = p_end; } pair from_order(vector& per, int lim) { fill_obj(per); reflect_all(per, lim); ld ldist = 0; point e = obj[2*n]; for (int i = 0; i < lim; i++) { auto c = cut(obj[2*i], obj[2*i+1], start, e); if (!c.first || c.second < ldist + eps) return pair(false, 0); ldist = c.second; } if (dist(start, e) < ldist + eps) return pair(false, 0); for (int i = lim; i < n; i++) { if (cut(obj[2*i], obj[2*i+1], start, e).first) return pair(false, 0); } point seg = vec(start, e); return pair(true, atan2(seg.y, seg.x)); } int main() { ios_base::sync_with_stdio(0); cin >> n; cin >> start.x >> start.y >> p_end.x >> p_end.y; for (int i = 0; i < n; i++) { cin >> mirr[i].first.x; cin >> mirr[i].first.y; cin >> mirr[i].second.x; cin >> mirr[i].second.y; } if (n == 0) { cout << 1 << endl; return 0; } vector per(n), f(n+1), res_part(n+1, 0); f[0] = 1; for (int i = 0; i < n; i++) { per[i] = i; f[i+1] = f[i] * (i+1); } vector dirs; do { for (int i = 0; i < n; i++) { auto r = from_order(per, i+1); if (r.first) dirs.push_back(r.second); } } while (next_permutation(per.begin(), per.end())); auto r0 = from_order(per, 0); if (r0.first) dirs.push_back(r0.second); if (dirs.size() == 0) { cout << 0 << endl; return 0; } int res = 0; sort(dirs.begin(), dirs.end()); for (int i = 1; i < dirs.size(); i++) { if (dirs[i-1] < dirs[i] + 1e-12) res++; } if (dirs[0] + 2.0 * M_PI + 1e-12> dirs[dirs.size()-1]) res++; cout << res << endl; return 0; }