Problem:
Coin Slider
You are playing a coin puzzle. The rule of this puzzle is as follows:
There are $N$ coins on a table. The $i$-th coin is a circle with $r_i$ radius, and its center is initially placed at ($sx_i, sy_i$). Each coin also has a target position: you should move the $i$-th coin so that its center is at ($tx_i, ty_i$). You can move coins one by one and can move each coin at most once. When you move a coin, it must move from its initial position to its target position along the straight line. In addition, coins cannot collide with each other, including in the middle of moves.
The score of the puzzle is the number of the coins you move from their initial position to their target position. Your task is to write a program that determines the maximum score for a given puzzle instance.
Input
The input consists of a single test case formatted as follows.
$N$
$r_1$ $sx_1$ $sy_1$ $tx_1$ $ty_1$
:
$r_N$ $sx_N$ $sy_N$ $tx_1$ $ty_N$
The first line contains an integer $N$ ($1 \leq N \leq 16$), which is the number of coins used in the puzzle. The $i$-th line of the following $N$ lines consists of five integers: $r_i, sx_i, sy_i, tx_i,$ and $ty_i$ ($1 \leq r_i \leq 1,000, -1,000 \leq sx_i, sy_i, tx_i, ty_i \leq 1,000, (sx_i, sy_i) \ne (tx_i, ty_i)$). They describe the information of the $i$-th coin: $r_i$
is the radius of the $i$-th coin, $(sx_i, sy_i)$ is the initial position of the $i$-th coin, and $(tx_i, ty_i)$ is the target position of the $i$-th coin.
You can assume that the coins do not contact or are not overlapped with each other at the initial positions. You can also assume that the maximum score does not change even if the radius of each coin changes by $10^{-5}$.
Output
Print the maximum score of the given puzzle instance in a line.
Sample Input 1
3
2 0 0 1 0
2 0 5 1 5
4 1 -10 -5 10
Output for Sample Input 1
2
Sample Input 2
3
1 0 0 5 0
1 0 5 0 0
1 5 5 0 5
Output for Sample Input 2
3
Sample Input 3
4
1 0 0 5 0
1 0 5 0 0
1 5 5 0 5
1 5 0 0 0
Output for Sample Input 3
0
In the first example, the third coin cannot move because it is disturbed by the other two coins.

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define vl vector<ll>
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define eps 0.000000001

struct point {
	double x,y;
};

// p1-p2を通る直線上に、点pから引いた垂線の足を返す
point projection(const point& p1, const point& p2, const point& p){
	double dx = p2.x - p1.x;
	double dy = p2.y - p1.y;

	double wx = p.x - p1.x;
	double wy = p.y - p1.y;

	double dot_wd = wx * dx + wy * dy;
	double dot_dd = dx * dx + dy * dy;
	double t = dot_wd / dot_dd;

	return { p1.x + t * dx, p1.y + t * dy };
}

// 点pと、直線p1-p2の距離を求める
double point_line_distance(point p, point p1, point p2){
	double num = fabs((p2.x - p1.x) * (p1.y - p.y) - (p1.x - p.x) * (p2.y - p1.y));
	double den = hypot(p2.x - p1.x, p2.y - p1.y);
	return num / den;
}

// 点pと、線分p1-p2の距離を求める
double point_segment_distance(point p,point p1, point p2){
	//まず、点と直線の距離にすべきものかどうかを判定します。

	point tmp=projection(p1,p2,p);
	if((p1.x<=tmp.x&&tmp.x<=p2.x)||(p2.x<=tmp.x&&tmp.x<=p1.x)){
		return point_line_distance(p,p1,p2);
	}else{
		double p1dis = (p1.x-p.x)*(p1.x-p.x)+(p1.y-p.y)*(p1.y-p.y);
		p1dis=sqrt(p1dis);
		double p2dis = (p2.x-p.x)*(p2.x-p.x)+(p2.y-p.y)*(p2.y-p.y);
		p2dis=sqrt(p2dis);
		return min(p1dis,p2dis);
	}
}

int main() {
	ll n;
	cin>>n;
	vector<double> r(n),sx(n),sy(n),tx(n),ty(n);
	rep(i,n)cin>>r[i]>>sx[i]>>sy[i]>>tx[i]>>ty[i];

	vector<bool> dp(1LL<<n,false);
	dp[0]=true;

	

	rep(b,1LL<<n){
		if(!dp[b])continue;
		rep(i,n){
			if(b&(1LL<<i))continue;
			//新たにiを移動させられるか考える.
			
			//iの移動経路の線分
			point start={sx[i],sy[i]};
			point goal={tx[i],ty[i]};
			bool f=true;
			rep(j,n){
				if(i==j)continue;
				//j個目の円盤と衝突するかを考える。
				point tmp;
				if(b&(1LL<<j))tmp={tx[j],ty[j]};
				else tmp={sx[j],sy[j]};
				
				if(point_segment_distance(tmp,start,goal)+eps<r[i]+r[j]){
					f=false;
					break;
				}
			}
			if(f){
				dp[b+(1LL<<i)]=true;
			}
		}
	}
	ll ans=0;
	rep(b,1LL<<n){
		if(dp[b])ans=max(ans,(ll)__popcount(b));
	}
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 4

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

using ll=long long;
#define rep(i,n) for(int i=0;i<n;i++)
/*
- `Point p(x, y)` で座標/ベクトルを宣言できる
- `cout << fixed << setprecision(10);` で小数出力の桁数を指定できる
*/
using Real = double;
using Point = complex<Real>;
using Poly = vector<Point>;
Real eps = 1e-6;

int Round(Real x) { return static_cast<int>(round(x)); }

// 同じか判定
bool equal(Point a, Point b) { return abs(a - b) < eps; }

struct Line {
  // 点 a, b を通る直線
  Point a, b;
  Line() = default;
  Line(Point a, Point b) : a(a), b(b) {}
  Line(Real A, Real B, Real C) {
    // 直線の方程式 Ax + By = C;
    if(equal(A, 0)) a = Point(0, C / B), b = Point(1, C / B);
    else if(equal(B, 0)) a = Point(C / A, 0), b = Point(C / A, 1);
    else a = Point(0, C / B), b = Point(C / A, 0);
  }
};

using Segment = Line;

Real dot(Point a, Point b) { return a.real() * b.real() + a.imag() * b.imag(); }
// 外積(cross product): a×b=|a||b|sinΘ
Real cross(Point a, Point b) {
  return a.real() * b.imag() - a.imag() * b.real();
}
// 線分 L と点 p の距離
Real distSegPoint(Segment L, Point p) {
  if(dot(L.b - L.a, p - L.a) < eps) return abs(p - L.a);
  if(dot(L.a - L.b, p - L.b) < eps) return abs(p - L.b);
  return abs(cross(L.b - L.a, p - L.a)) / abs(L.b - L.a);
}

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

    int N;
    cin>>N;
    vector<double> R(N);
    vector<Point> S(N),T(N);
    rep(i,N){
        cin>>R[i];
        double x,y;
        cin>>x>>y;
        S[i]={x,y};
        cin>>x>>y;
        T[i]={x,y};
    }
    vector<bool> OK(1<<N,0);
    OK[0]=1;
    rep(bit,1<<N){
        rep(i,N){
            if(bit&(1<<i)){
                if(!OK[bit-(1<<i)])continue;
                Segment SG(S[i],T[i]);
                bool ok=1;
                rep(j,N){
                    if(j==i)continue;
                    double d=distSegPoint(SG,(bit&(1<<j)?T:S)[j]);
                    if(d<R[i]+R[j])ok=0;
                }
                if(ok)OK[bit]=1;
            }
        }
    }
    
    int an=0;
    rep(bit,1<<N)if(OK[bit])an=max(an,__builtin_popcount(bit));
    cout<<an<<endl;

}
accuracy: 1
time_ms: 60
memory_kb: 3536
final_rank: 5

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


using namespace std;
//make -f ../makefile SRC=
/*
TODO
dp on mask + geometry
dp state: if bit is set => move to new pos; otherwise stay in original

WA on test 2 (provided)
3
1 0 0 5 0
1 0 5 0 0
1 5 5 0 5

Output for Sample Input 2
3
test:
0
*/

//------------------------------------------------------------------------------
bool DEBUG = false;
const double PI = 3.14159265358979311600;
const double INF = 1e18;
const double EPS = 1e-9;

const int MAX_N = 16;
static double RA[MAX_N];
static double X1[MAX_N];
static double Y1[MAX_N];
static double X2[MAX_N];
static double Y2[MAX_N];

static bool S[ 1<<MAX_N ];

//------------------------------------------------------------------------------
struct Point
{
    double x;
    double y;
    Point(): x(INF), y(INF) {}
    Point(double x1, double x2): x(x1), y(x2) {}
    bool operator==(const Point& p1) const
    {
        return fabs(x-p1.x) < EPS && fabs(y-p1.y) < EPS;
    }
    bool operator!=(const Point& p1) const
    {
        return fabs(x-p1.x) > EPS || fabs(y-p1.y) > EPS;
    }
    bool operator<(const Point& p1) const
    {
        return x < p1.x || (fabs(x-p1.x) < EPS && y < p1.y);
    }
    void debug() const { printf("%0.1lf %0.1lf\n", x, y); }
};

typedef vector<Point> Points;


//------------------------------------------------------------------------------
struct Line
{
    double a, b, c;

    Line(): a(0), b(0), c(0) {}

    Line(double a1, double b1, double c1): a(a1), b(b1), c(c1) {}

    Line(double x1, double y1, double x2, double y2)
    : a(y2-y1), b(x1-x2), c(x1*(y1-y2) + y1*(x2-x1)) {}

    Line(const Point& p1, const Point& p2)
    : a(p2.y-p1.y), b(p1.x-p2.x), c(p1.x*(p1.y-p2.y) + p1.y*(p2.x-p1.x)) {}

    bool operator<(const Line& L1) const
    {
        if (a == L1.a && b == L1.b) return c < L1.c;
        else if (b == L1.b && c == L1.c) return a < L1.a;
        else if (c == L1.c && a == L1.a) return b < L1.b;
        else if (a == L1.a) return b < L1.b;
        else if (b == L1.b) return c < L1.c;
        return a < L1.a;
    }
    bool operator==(const Line& L1) const
    {
        return fabs(a-L1.a) < EPS && fabs(b-L1.b) < EPS && fabs(c-L1.c) < EPS;
    }
    bool operator!=(const Line& L1) const
    {
        return fabs(a-L1.a) >= EPS || fabs(b-L1.b) >= EPS || fabs(c-L1.c) >= EPS;
    }
    void debug() const { printf("a=%lf, b=%lf, c=%lf\n", a, b, c); }
};

typedef vector<Line> Lines;


//------------------------------------------------------------------------------
double dist2(const Point& A, const Point& B)
{
    return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y);
}


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

double dist(const Point& A, const Point& B)
{
    return dist(A.x, A.y, B.x, B.y);
}

Line eqt_of_line(double x1, double y1, double x2, double y2)
{
    double a = y2-y1;
    double b = x1-x2;
    double c = x1*(y1-y2) + y1*(x2-x1);
    return Line(a, b, c);
}

Line eqt_of_line(const Point& P1, const Point& P2)
{
    return eqt_of_line(P1.x, P1.y, P2.x, P2.y);
}

Point intersection_of_lines(double a1, double b1, double c1, double a2, double b2, double c2)
{
    double x = (b1*c2-b2*c1)/(a1*b2-a2*b1);
    double y = (a2*c1-a1*c2)/(a1*b2-a2*b1);
    return Point(x, y);
}

Point intersection_of_lines(const Line& L1, const Line& L2)
{
    return intersection_of_lines(L1.a, L1.b, L1.c, L2.a, L2.b, L2.c);
}

double shortest_dist_to_line(double a, double b, double c, double x0, double y0)
{
    double y1 = fabs(a*x0 + b*y0 + c);
    double y2 = sqrt(a*a + b*b);
    return y1/y2;
}

double shortest_dist_to_line(const Line& L, const Point& P)
{
    return shortest_dist_to_line(L.a, L.b, L.c, P.x, P.y);
}

Point contact_point(double a, double b, double c, const Point& P0)
{
    double denom = a*a + b*b;
    if (fabs(denom) < EPS) return Point();
    double x0 = P0.x;
    double y0 = P0.y;
    double cx = b*(b*x0-a*y0)-a*c;
    cx /= denom;
    double cy = a*(-b*x0+a*y0)-b*c;
    cy /= denom;
    return Point(cx, cy);
}

Point contact_point(const Line& L, const Point& P0)
{
    return contact_point(L.a, L.b, L.c, P0);
}

Line perpendicular(const Point& P, const Point& B, const Point& A)
{
    if (B == P) return Line(A, B);

    Line PB(P, B);
    Point C = contact_point(PB, A);
    if (C == Point()) return Line();

    return Line(A, C);
}

bool on_segment(const Point& P1, const Point& P2, const Point& Q)
{
    return fabs(dist(P1,Q)+dist(Q,P2)-dist(P1,P2)) < EPS;
}
//------------------------------------------------------------------------------
bool collide(const Point& start, const Point& end, double radius, const Point& P, double R)
{
    if (dist(start,P) < radius+R || dist(end,P) < radius+R) return true;
    Point Q = contact_point(Line(start,end), P);
    //if (DEBUG) { printf("contact_point: "); Q.debug(); }
    if (Q == Point()) return true;
    if (on_segment(start, end, Q) && dist(P,Q) < radius+R) return true;
    return false;
}

bool feasible(int N, int mask, int i)
{
    Point start(X1[i], Y1[i]);
    Point end(X2[i], Y2[i]);
    double radius = RA[i];
    Point P;
    double R;
    for (int j=0; j<N; ++j)
    {
        if (j == i) continue;
        R = RA[j];
        if (mask & (1<<j)) P = Point(X2[j], Y2[j]);
        else P = Point(X1[j], Y1[j]);

        if (collide(start, end, radius, P, R)) return false;
    }
    return true;
}

//------------------------------------------------------------------------------
int solve(int N)
{
    for (int mask=0; mask<(1<<N); ++mask) S[mask] = false;
    S[0] = true;
    
    /*
    if (DEBUG)
    {
        bool ok = feasible(N, 0, 0);
        printf("ok=%d\n", ok);
        return -1;
    }
    */
    for (int mask=0; mask<(1<<N); ++mask)
    {
        // start from a feasible config:
        if (!S[mask]) continue;
        for (int i=0; i<N; ++i)
        {
            // try moving unmoved ball i:
            if (mask & (1<<i)) continue;
            bool ok = feasible(N, mask, i);
            if (DEBUG) printf("mask=%s, i=%d, ok=%d\n", bitset<3>(mask).to_string().c_str(), i, ok);
            if (ok)
            {
                S[ mask | (1<<i) ] = true;
            }
        }
    }
    int res = 0;
    for (int mask=0; mask<(1<<N); ++mask)
        if (S[mask])
            res = max(res, __builtin_popcount(mask));
    return res;
}

//------------------------------------------------------------------------------
void test()
{
    Point start(5,5);
    Point end(0,5);
    double radius = 1;
    Point P(0,5);
    double R = 1;
    bool not_ok = collide(start, end, radius, P, R);
    printf("collide=%d\n", not_ok);
}

//------------------------------------------------------------------------------
int main()
{
    //DEBUG = true;
    //test(); return 0;
    //--------------------------------------------------------------------------
    int N, num;
    num = scanf("%d ", &N);
    for (int i=0; i<N; ++i) num = scanf("%lf %lf %lf %lf %lf ", &RA[i], &X1[i], &Y1[i], &X2[i], &Y2[i]);
    int res = solve(N);
    printf("%d\n", res);
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 110
memory_kb: 3600
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define srep(i, s, t) for(int i = (s); i < (t); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
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; }
using ll = long long;
using ld = long double;

double eps = 1e-6;
int main() {
    int N; cin >> N;
    vector<int> R(N);
    vector<pair<int, int>> S(N), T(N);
    rep(i, N) cin >> R[i] >> S[i].first >> S[i].second >> T[i].first >> T[i].second;
    vector<int> dp(1 << N, 0);
    dp[0] = 1;
    rep(cmb, 1 << N) if (dp[cmb]) rep(v, N) if (~cmb >> v & 1){
        auto [sx, sy] = S[v];
        auto [tx, ty] = T[v];
        int nr = R[v];

        if (sx > tx){
            swap(sx, tx);
            swap(sy, ty);
        }

        vector<tuple<int, int, int>> P;
        rep(i, N) if (i != v){
            if (cmb >> i & 1) P.push_back({T[i].first, T[i].second, R[i]});
            else P.push_back({S[i].first, S[i].second, R[i]});
        }

        bool flag = true;
        for (auto [x, y, r] : P){
            int p1 = (x - sx) * (tx - sx) + (y - sy) * (ty - sy), p2 = (x - tx) * (sx - tx) + (y - ty) * (sy - ty);
            if (p1 >= 0 && p2 >= 0){
                double a = sy - ty, b = tx - sx, c = -sy * (tx - sx) + sx * (ty - sy);
                double d = abs(a * x + b * y + c) / sqrt(a * a + b * b);
                if (d < r + nr - eps) flag = false;
            }
            if ((sx - x) * (sx - x) + (sy - y) * (sy - y) < (r + nr) * (r + nr)) flag = false;
            if ((tx - x) * (tx - x) + (ty - y) * (ty - y) < (r + nr) * (r + nr)) flag = false;
        }
        if (flag) dp[cmb | (1 << v)] = 1;
    }
    int ans = 0;
    rep(cmb, 1 << N) if (dp[cmb]) ans = max(ans, __builtin_popcount(cmb));
    cout << ans << endl;
}
accuracy: 1
time_ms: 90
memory_kb: 3440
final_rank: 10

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 N;
    cin >> N;
    vector<double> R(N);
    vector<vector<Point>> P(N, vector<Point>(2));
    rep(i,0,N) {
        cin >> R[i];
        double sx, sy, tx, ty;
        cin >> sx >> sy >> tx >> ty;
        P[i][0] = Point(sx,sy), P[i][1] = Point(tx,ty);
    }
    vector<vector<bool>> B(1<<N, vector<bool>(N,false));
    rep(i,0,1<<N) {
        vector<int> A(N,0);
        rep(j,0,N) {
            if (i & (1<<j)) A[j] = 1;
        }
        rep(j,0,N) {
            bool check = true;
            Segment Seg(P[j][0],P[j][1]);
            rep(k,0,N) {
                if (j == k) continue;
                if (Dist(Seg,P[k][A[k]]) < R[j] + R[k]) check = false;
            }
            if (check) B[i][j] = true;
        }
    }
    vector<int> vis(1<<N,false);
    queue<int> Q;
    vis[0] = true;
    Q.push(0);
    while(!Q.empty()) {
        int S = Q.front();
        Q.pop();
        rep(i,0,N) {
            if (!B[S][i]) continue;
            int NS = S ^ (1<<i);
            if (!vis[NS]) {
                vis[NS] = true;
                Q.push(NS);
            }
        }
    }
    int ANS = 0;
    rep(i,0,1<<N) {
        if (vis[i]) chmax(ANS,popcnt(i));
    }
    cout << ANS << endl;
}
accuracy: 1
time_ms: 190
memory_kb: 8300
final_rank: 20

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
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 < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

template < class T > struct point {
    T x, y;
    point() : x(0), y(0) {}
    point(T x, T y) : x(x), y(y) {}
    point(std::pair< T, T > 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 T r) { x *= r, y *= r; return *this; }
    point& operator/=(const T r) { 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 T r) const { return point(*this) *= r; }
    point operator/(const T r) const { return point(*this) /= r; }
    point operator-() const { return {-x, -y}; }
    bool operator==(const point& p) const { return x == p.x and y == p.y; }
    bool operator!=(const point& p) const { return x != p.x or  y != p.y; }
    bool operator<(const point& p) const { return x == p.x ? y < p.y : x < p.x; }
    point< T > rot(double theta) {
        static_assert(is_floating_point_v< T >);
        double cos_ = std::cos(theta), sin_ = std::sin(theta);
        return {cos_ * x - sin_ * y, sin_ * x + cos_ * y};
    }
};
template < class T > istream& operator>>(istream& is, point< T >& p) { return is >> p.x >> p.y; }
template < class T > ostream& operator<<(ostream& os, point< T >& p) { return os << p.x << " " << p.y; }
template < class T > T dot(const point< T >& a, const point< T >& b) { return a.x * b.x + a.y * b.y; }
template < class T > T det(const point< T >& a, const point< T >& b) { return a.x * b.y - a.y * b.x; }
template < class T > T norm(const point< T >& p) { return p.x * p.x + p.y * p.y; }
template < class T > double abs(const point< T >& p) { return std::sqrt(norm(p)); }
template < class T > double angle(const point< T >& p) { return std::atan2(p.y, p.x); }
template < class T > int sign(const T x) {
    T e = (is_integral_v< T > ? 1 : 1e-8);
    if(x <= -e) return -1;
    if(x >= +e) return +1;
    return 0;
}
template < class T > bool equals(const T& a, const T& b) { return sign(a - b) == 0; }
template < class T > int ccw(const point< T >& a, point< T > b, point< T > c) {
    b -= a, c -= a;
    if(sign(det(b, c)) == +1) return +1; // counter clockwise
    if(sign(det(b, c)) == -1) return -1; //         clockwise
    if(sign(dot(b, c)) == -1) return +2; // c-a-b
    if(norm(b) < norm(c)) return -2;     // a-b-c
    return 0;                            // a-c-b
}

template < class T > struct line {
    point< T > a, b;
    line() {}
    line(point< T > a, point< T > b) : a(a), b(b) {}
};
template < class T > point< T > projection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return l.a + (l.a - l.b) * dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
}
template < class T > point< T > reflection(const line< T >& l, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    return p + (projection(l, p) - p) * T(2);
}
template < class T > bool orthogonal(const line< T >& a, const line< T >& b) { return equals(dot(a.b - a.a, b.b - b.a), T(0)); }
template < class T > bool parallel  (const line< T >& a, const line< T >& b) { return equals(det(a.b - a.a, b.b - b.a), T(0)); }
template < class T > point< T > cross_point_ll(const line< T >& l, const line< T >& m) {
    static_assert(is_floating_point_v< T >);
    T A = det(l.b - l.a, m.b - m.a);
    T B = det(l.b - l.a, l.b - m.a);
    if(equals(abs(A), T(0)) and equals(abs(B), T(0))) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

template < class T > using segment = line< T >;
template < class T > bool intersect_ss(const segment< T >& s, const segment< T >& t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 and ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
template < class T > double distance_sp(const segment< T >& s, const point< T >& p) {
    static_assert(is_floating_point_v< T >);
    point r = projection(s, p);
    if(ccw(s.a, s.b, r) == 0) return abs(r - p);
    return std::min(abs(s.a - p), abs(s.b - p));
}
template < class T > double distance_ss(const segment< T >& a, const segment< T >& b) {
    if(intersect_ss(a, b)) return 0;
    return std::min({ distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b) });
}

template < class T > using polygon = std::vector< point< T > >;
template < class T > T area2(const polygon< T >& p) {
    T s = 0;
    int n = p.size();
    for(int i = 0; i < n; i++) s += det(p[i], p[(i + 1) % n]);
    return s;
}
template < class T > T area(const polygon< T >& p) { return area2(p) / T(2); }

template < class T > bool is_convex(const polygon< T >& p) {
    int n = p.size();
    for(int i = 0; i < n; i++) if(ccw(p[(i - 1 + n) % n], p[i], p[(i + 1) % n]) == -1) return false;
    return true;
}
template < class T > int contains(const polygon< T >& g, const point< T >& p) {
    int n = g.size();
    bool in = false;
    for(int i = 0; i < n; i++) {
        point a = g[i] - p, b = g[(i + 1) % n] - p;
        if(sign(a.y - b.y) == +1) std::swap(a, b);
        if(sign(a.y) <= 0 and sign(b.y) ==+1 and sign(det(a, b)) == -1) in = !in;
        if(sign(det(a, b)) == 0 and sign(dot(a, b)) <= 0) return 1; // ON
    }
    return in ? 2 : 0;
}
template < class T > polygon< T > convex_cut(const polygon< T >& p, const line< T >& l) {
    int n = p.size();
    polygon< T > res;
    for(int i = 0; i < n; i++) {
        point now = p[i], nxt = p[(i + 1) % n];
        if(ccw(l.a, l.b, now) != -1) res.push_back(now);
        if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) res.push_back(cross_point_ll(line(now, nxt), l));
    }
    return res;
}
template < class T > polygon< T > convex_hull(polygon< T >& p) {
    int n = p.size(), k = 0;
    if(n <= 2) return p;
    std::sort(p.begin(), p.end());
    polygon< T > ch(n + n);
    for(int i = 0; i < n; ch[k++] = p[i++])
        while(k >= 2 and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--])
        while(k >= t and sign(det(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) == -1) k--;
    ch.resize(k - 1);
    return ch;
}
template < class T > T diameter2(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    int n = p.size(), is = 0, js = 0;
    for(int i = 1; i < n; i++) {
        if(sign(p[i].y - p[is].y) == +1) is = i;
        if(sign(p[i].y - p[js].y) == -1) js = i;
    }
    T dist_max = norm(p[is] - p[js]);
    int maxi = is, i = is, maxj = js, j = js;
    do {
        if(sign(det(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j])) >= 0) j = (j + 1) % n; else i = (i + 1) % n;
        if(norm(p[i] - p[j]) > dist_max) {
            dist_max = norm(p[i] - p[j]);
            maxi = i, maxj = j;
        }
    } while(i != is or j != js);
    return dist_max;
}
template < class T > double diameter(const polygon< T >& p) {
    static_assert(is_floating_point_v< T >);
    return std::sqrt(diameter2(p));
}

template < class T > struct circle {
    point< T > p;
    T r;
    circle() = default;
    circle(point< T > p, T r) : p(p), r(r) {}
};
template < class T > istream& operator>>(istream& is, circle< T >& c) { return is >> c.p >> c.r; }
template < class T > int intersect_cc(circle< T > c1, circle< T > c2) {
    if(c1.r < c2.r) std::swap(c1, c2);
    T d = abs(c1.p - c2.p);
    if(sign(c1.r + c2.r - d) == -1) return 4;
    if(equals(c1.r + c2.r, d)) return 3;
    if(sign(c1.r - c2.r - d) == -1) return 2;
    if(equals(c1.r - c2.r, d)) return 1;
    return 0;
}
template < class T > std::pair<point< T >, point< T >> cross_point_cc(const circle< T >& c1, const circle< T >& c2) {
    T d = abs(c1.p - c2.p);
    T a = std::acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    T t = angle(c2.p - c1.p);
    point< T > p1 = c1.p + point< T >(std::cos(t + a), std::sin(t + a)) * c1.r;
    point< T > p2 = c1.p + point< T >(std::cos(t - a), std::sin(t - a)) * c1.r;
    return {p1, p2};
}

int main() {
    int N = in();
    using f64 = long double;
    vector<f64> r(N);
    vector<point<f64>> s(N), t(N);
    for(int i : rep(N)) cin >> r[i] >> s[i] >> t[i];

    vector dp(1 << N, false);
    dp[0] = true;
    for(int S : rep(1 << N)) if(dp[S]) {
        for(int i : rep(N)) if(!(S & (1 << i)))  {
            bool can_move = [&] {
                for(int j : rep(N)) if(j != i) {
                    if(distance_sp(segment<f64>(s[i], t[i]), S & (1 << j) ? t[j] : s[j]) < r[i] + r[j]) return false;
                }
                return true;
            }();

            if(can_move) dp[S | (1 << i)] = true;
        }
    }

    int ans = 0;
    for(int S : rep(1 << N)) if(dp[S]) chmax(ans, popcnt(S));
    print(ans);
}
accuracy: 1
time_ms: 150
memory_kb: 3548
final_rank: 13

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

#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_);
    }
    Point midpoint() const {
        assert(valid());
        return p0_ + Vector{p1_ - p0_} / static_cast<Real>(2);
    }
};

} // namespace geometryR2

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

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

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

namespace zawa {

namespace geometryR2 {

class Circle {
private:
    Point center_{};
    Real radius_{};
public:
    /* constructor */
    Circle() = default;
    Circle(const Point& center, Real radius) : center_{center}, radius_{radius} {
        assert(!Negative(radius));
    }
    Circle(Real x, Real y, Real r) : center_{x, y}, radius_{r} {
        assert(!Negative(r));
    }

    /* getter setter */
    const Point& center() const {
        return center_;
    }
    Point& center() {
        return center_;
    }
    Real radius() const {
        return radius_;
    }
    Real& radius() {
        return radius_;
    }

    /* operator */
    friend bool operator==(const Circle& lhs, const Circle& rhs) {
        return lhs.center() == rhs.center() and Equal(lhs.radius(), rhs.radius());
    }
    friend bool operator!=(const Circle& lhs, const Circle& rhs) {
        return lhs.center() != rhs.center() or !Equal(lhs.radius(), rhs.radius());
    }

    /* friend function */
    friend u32 NumberCommonTangent(const Circle& c0, const Circle& c1) {
        Real dist{DistanceSquare(c0.center(), c1.center())};
        Real down{Square(Abs(c0.radius() - c1.radius()))};
        if (Smaller(dist, down)) return 0;
        if (Equal(dist, down)) return 1;
        Real up{Square(c0.radius() + c1.radius())};
        if (Smaller(dist, up)) return 2;
        if (Equal(dist, up)) return 3;
        return 4;
    }
};

} // 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 7 "2862.test.cpp"

#line 9 "2862.test.cpp"
#include <vector>

using namespace zawa::geometryR2;

int main() {
    int n; std::cin >> n;
    std::vector<Real> r(n);
    std::vector<Point> s(n), t(n);
    for (int i{} ; i < n ; i++) {
        std::cin >> r[i] >> s[i] >> t[i];
    }
    std::vector<bool> dp((1 << n));
    dp[0] = true;
    for (int bit{} ; bit < (1 << n) ; bit++) {
        if (!dp[bit]) continue;
        for (int i{} ; i < n ; i++) if (!(bit & (1 << i))) {
            Segment seg{s[i], t[i]};
            bool can{true};
            for (int j{} ; j < n ; j++) if (i != j) {
                Circle c{(bit & (1 << j)) ? t[j] : s[j], r[j]};
                Real dist{Distance(c.center(), seg)};
                can &= Bigger(dist, c.radius() + r[i]);
            }
            if (can) dp[bit | (1 << i)] = true;
        }
    }
    int ans{};
    for (int bit{} ; bit < (1 << n) ; bit++) if (dp[bit]) {
        ans = std::max(ans, __builtin_popcount(bit));
    }
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 180
memory_kb: 3524
final_rank: 14

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class point2d {
public:
	double x, y;
	point2d() : x(0.0), y(0.0) {}
	point2d(double x_, double y_) : x(x_), y(y_) {}
	point2d operator+(const point2d& p) const { return point2d(x + p.x, y + p.y); }
	point2d operator-(const point2d& p) const { return point2d(x - p.x, y - p.y); }
	point2d operator*(double v) const { return point2d(x * v, y * v); }
	point2d operator/(double v) const { return point2d(x / v, y / v); }
	double abs() const { return sqrt(x * x + y * y); }
	double dot(const point2d& p) const { return x * p.x + y * p.y; }
	double cross(const point2d& p) const { return x * p.y - y * p.x; }
};

double distance(const point2d& p, const point2d& q1, const point2d& q2) {
	if ((p - q1).dot(q2 - q1) < 0.0) {
		return (p - q1).abs();
	}
	if ((p - q2).dot(q1 - q2) < 0.0) {
		return (p - q2).abs();
	}
	return abs((q2 - q1).cross(p - q1) / (q2 - q1).abs());
}

int main() {
	int N;
	cin >> N;
	vector<double> R(N);
	vector<point2d> S(N), T(N);
	for (int i = 0; i < N; i++) {
		cin >> R[i] >> S[i].x >> S[i].y >> T[i].x >> T[i].y;
	}
	vector<bool> dp(1 << N, false);
	dp[0] = true;
	for (int i = 0; i < (1 << N); i++) {
		if (!dp[i]) {
			continue;
		}
		for (int j = 0; j < N; j++) {
			if (((i >> j) & 1) == 0) {
				bool ok = true;
				for (int k = 0; k < N; k++) {
					if (j != k) {
						point2d tar = (((i >> k) & 1) == 1 ? T[k] : S[k]);
						double d = distance(tar, S[j], T[j]);
						if (d < R[j] + R[k]) {
							ok = false;
						}
					}
				}
				if (ok) {
					dp[i | (1 << j)] = true;
				}
			}
		}
	}
	int answer = 0;
	for (int i = 0; i < (1 << N); i++) {
		if (dp[i]) {
			answer = max(answer, __builtin_popcount(i));
		}
	}
	cout << answer << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3492
final_rank: 1

code_snippet: #include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

struct Point {
	double px, py;
};

Point operator-(const Point &a1, const Point &a2) {
	return Point {a1.px - a2.px, a1.py - a2.py};
}

double ABS(Point Diff) {
	return sqrt(Diff.px * Diff.px + Diff.py * Diff.py);
}

double crs(Point A1, Point A2) {
	return A1.px * A2.py - A1.py * A2.px;
}

double dot(Point A1, Point A2) {
	return A1.px * A2.px + A1.py * A2.py;
}

// Distance from A1A2 to A3
double dst_line(Point A1, Point A2, Point A3) {
	double val = crs(A2 - A1, A3 - A1);
	double dst = ABS(A2 - A1);
	return 1.0 * val / dst;
}

// Distance from segment A1A2 to A3
double dst_seg(Point A1, Point A2, Point A3) {
	double val1 = dot(A2 - A1, A3 - A1);
	double val2 = dot(A1 - A2, A3 - A2);
	if (val1 <= 0.0 || val2 <= 0.0) {
		double ret1 = ABS(A3 - A1);
		double ret2 = ABS(A3 - A2);
		return min(ret1, ret2);
	}
	return abs(dst_line(A1, A2, A3));
}

int N;
Point S[109], G[109]; double R[109];
int dp[1<<16];

int main() {
	// Input
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> R[i] >> S[i].px >> S[i].py >> G[i].px >> G[i].py;
	}
	
	// Dynamic Programming
	for (int i = 0; i < (1<<N); i++) dp[i] = -1;
	dp[0] = 0;
	for (int i = 0; i < (1<<N); i++) {
		if (dp[i] == -1) continue;
		for (int j = 0; j < N; j++) {
			if ((i / (1 << j)) % 2 == 1) continue;
			
			// Judge if moving coin j is possible
			bool flag = true;
			for (int k = 0; k < N; k++) {
				if (j == k) continue;
				Point P1 = S[j];
				Point P2 = G[j];
				Point P3 = S[k]; if ((i / (1 << k)) % 2 == 1) P3 = G[k];
				double dst = dst_seg(P1, P2, P3);
				if (dst < R[j] + R[k]) flag = false;
			}
			
			// Transition
			if (flag == true) {
				dp[i + (1 << j)] = max(dp[i + (1 << j)], dp[i] + 1);
			}
		}
	}
	
	// Get Answer
	int Answer = 0;
	for (int i = 0; i < (1<<N); i++) Answer = max(Answer, dp[i]);
	cout << Answer << endl;
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3716
final_rank: 11

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

/* macro */

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n - 1)); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i < (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n - i64(1))); i >= (i64)(a); i--)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define Bit(n) (1LL << (n))

/* macro end */

/* template */

namespace ebi {

#ifdef LOCAL
#define debug(...)                                                      \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cout << " :";
    debug_out(t...);
}

template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa) {
    return os << pa.first << " " << pa.second;
}

template <typename T1, typename T2>
std::istream &operator>>(std::istream &os, std::pair<T1, T2> &pa) {
    return os >> pa.fist >> pa.second;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
    for (std::size_t i = 0; i < vec.size(); i++)
        os << vec[i] << (i + 1 == vec.size() ? "" : " ");
    return os;
}

template <typename T>
std::istream &operator>>(std::istream &os, std::vector<T> &vec) {
    for (T &e : vec) std::cin >> e;
    return os;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
    if (opt) {
        os << opt.value();
    } else {
        os << "invalid value";
    }
    return os;
}

using std::size_t;
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;

template <class T, T init>
auto make_vector(int n) {
    return std::vector<T>(n, init);
}

template <class T, T init, typename Head, typename... Tail>
auto make_vector(Head n, Tail... ts) {
    return std::vector(n, make_vector<T, init>(ts...));
}

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

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

template <class T>
T pow(T x, i64 n) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = res * x;
        x = x * x;
        n >>= 1;
    }
    return res;
}

template <class T>
T mod_pow(T x, i64 n, i64 mod) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = (res * x) % mod;
        x = (x * x) % mod;
        n >>= 1;
    }
    return res;
}

template <class T>
T scan() {
    T val;
    std::cin >> val;
    return val;
}

template <class T>
struct Edge {
    int to;
    T cost;
    Edge(int _to, T _cost = 1) : to(_to), cost(_cost) {}
};

template <class T>
struct Graph : std::vector<std::vector<Edge<T>>> {
    using std::vector<std::vector<Edge<T>>>::vector;
    void add_edge(int u, int v, T w, bool directed = false) {
        (*this)[u].emplace_back(v, w);
        if (directed) return;
        (*this)[v].emplace_back(u, w);
    }
};

struct graph : std::vector<std::vector<int>> {
    using std::vector<std::vector<int>>::vector;
    void add_edge(int u, int v, bool directed = false) {
        (*this)[u].emplace_back(v);
        if (directed) return;
        (*this)[v].emplace_back(u);
    }
};

constexpr i64 LNF = std::numeric_limits<i64>::max() / 4;

constexpr int INF = std::numeric_limits<int>::max() / 2;

const std::vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
const std::vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};

}  // namespace ebi

#line 2 "geometry/circle.hpp"

#include <cmath>
#include <vector>

#line 2 "geometry/point.hpp"

#include <cstdint>
#line 5 "geometry/point.hpp"
#include <cassert>
#line 7 "geometry/point.hpp"
#include <algorithm>
#include <iostream>

namespace ebi {

constexpr long double EPS = 1e-7;

const long double PI = std::acos(-1);

namespace internal {

int sgn(long double a) { return (a < -EPS) ? -1 : (a > EPS) ? 1 : 0; }

long double add(long double a, long double b) {
    if (std::abs(a + b) < EPS * (std::abs(a) + std::abs(b))) return 0;
    return a + b;
}

}  // namespace internal

long double arg_to_radian(long double arg) {
    return PI * arg / (long double)(180);
}

struct point {
    long double x, y;

    point() = default;

    point(long double x, long double y) : x(x), y(y) {}

    point &operator+=(const point rhs) noexcept {
        x = internal::add(x, rhs.x);
        y = internal::add(y, rhs.y);
        return *this;
    }

    point &operator-=(const point rhs) noexcept {
        x = internal::add(x, -rhs.x);
        y = internal::add(y, -rhs.y);
        return *this;
    }

    point &operator*=(const point rhs) noexcept {
        long double _x = internal::add(x * rhs.x, -y * rhs.y);
        long double _y = internal::add(x * rhs.y, y * rhs.x);
        x = _x;
        y = _y;
        return *this;
    }

    point &operator*=(const long double k) noexcept {
        x *= k;
        y *= k;
        return *this;
    }

    point &operator/=(const long double k) {
        assert(internal::sgn(k) != 0);
        x /= k;
        y /= k;
        return *this;
    }

    point operator+(const point &rhs) const noexcept {
        return point(*this) += rhs;
    }

    point operator-(const point &rhs) const noexcept {
        return point(*this) -= rhs;
    }

    point operator*(const point &rhs) const noexcept {
        return point(*this) *= rhs;
    }

    point operator*(const long double rhs) const noexcept {
        return point(*this) *= rhs;
    }

    point operator/(const long double rhs) const { return point(*this) /= rhs; }

    point operator-() const noexcept { return point(0, 0) - *this; }

    long double abs() const noexcept {
        return std::sqrt(internal::add(x * x, y * y));
    }

    long double dot(const point rhs) const noexcept {
        return internal::add(x * rhs.x, y * rhs.y);
    }

    long double det(const point rhs) const noexcept {
        return internal::add(x * rhs.y, -y * rhs.x);
    }

    // arctan(y/x) (単位はラジアン)

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

    // x昇順, その後y昇順

    bool operator<(const point &rhs) const noexcept {
        if (internal::sgn(x - rhs.x)) return internal::sgn(x - rhs.x) < 0;
        return internal::sgn(y - rhs.y) < 0;
    }
};

std::ostream &operator<<(std::ostream &os, const point &a) {
    return os << a.x << " " << a.y;
}

std::istream &operator>>(std::istream &os, point &a) {
    return os >> a.x >> a.y;
}

point conj(const point &a) { return point(a.x, -a.y); }

// 点a をang(ラジアン)回転する

point rot(const point &a, long double ang) {
    return point(std::cos(ang) * a.x - std::sin(ang) * a.y,
                 std::sin(ang) * a.x + std::cos(ang) * a.y);
}

point rot90(const point &a) { return point(-a.y, a.x); }

long double dot(const point &a, const point &b) { return a.dot(b); }

long double det(const point &a, const point &b) { return a.det(b); }

long double abs(const point &a) { return a.abs(); }

long double norm(const point &a) { return internal::add(a.x * a.x, a.y * a.y); }

int isp(const point &a, const point &b, const point &c) {
    int flag = internal::sgn(det(b - a, c - a));
    if (flag == 0) {
        if (internal::sgn(dot(b - a, c - a)) < 0) return -2;
        if (internal::sgn(dot(a - b, c - b)) < 0) return +2;
    }
    return flag;
}

// 分割統治で最近点対を求める O(N log N)

long double closest_pair(std::vector<point> p) {
    std::sort(p.begin(), p.end());
    int n = p.size();
    auto f = [&](auto &&self, int l, int r) -> long double {
        if (r - l == 1) {
            return 1e9;
        }
        int mid = (l + r) / 2;
        long double x = p[mid].x;
        long double d = std::min(self(self, l, mid), self(self, mid, r));
        std::vector<point> b;
        b.reserve(r - l);
        int j = mid;
        for (int i = l; i < mid; i++) {
            while (j < r && p[j].y <= p[i].y) {
                b.emplace_back(p[j++]);
            }
            b.emplace_back(p[i]);
        }
        while (j < r) {
            b.emplace_back(p[j++]);
        }
        for (int i = 0; i < r - l; i++) {
            p[l + i] = b[i];
        }
        b.clear();
        for (int i = l; i < r; i++) {
            if (std::abs(p[i].x - x) >= d) continue;
            for (int j = int(b.size()) - 1; j >= 0; j--) {
                if (p[i].y - b[j].y >= d) break;
                d = std::min(d, abs(p[i] - b[j]));
            }
            b.emplace_back(p[i]);
        }
        return d;
    };
    return f(f, 0, n);
}

// ∠ABCを求める(ラジアン)

long double angle(const point &A, const point &B, const point &C) {
    long double a = (B - C).abs(), b = (C - A).abs(), c = (A - B).abs();
    long double cos =
        internal::add(internal::add(a * a, c * c), -b * b) / (2.0 * c * a);
    return std::acos(cos);
}

void arg_sort(std::vector<point> &a) {
    int n = a.size();
    std::vector ps(4, std::vector<point>());
    auto idx = [](point v) -> int {
        if (v.y >= 0)
            return (v.x >= 0) ? 0 : 1;
        else
            return (v.x >= 0) ? 3 : 2;
    };
    for (auto p : a) {
        assert(!(p.x == 0 && p.y == 0));
        ps[idx(p)].emplace_back(p);
    }
    a.clear();
    a.reserve(n);
    for (int i = 0; i < 4; i++) {
        std::sort(ps[i].begin(), ps[i].end(), [](point &p1, point &p2) -> bool {
            int flag = internal::sgn(internal::add(p1.x * p2.y, -p2.x * p1.y));
            return flag == 0 ? (norm(p1) < norm(p2)) : flag > 0;
        });
        for (auto &p : ps[i]) a.emplace_back(p);
    }
    return;
}

template <class T>
void arg_sort_ll(std::vector<std::pair<T, T>> &a) {
    using Point = std::pair<T, T>;
    int n = a.size();
    std::vector ps(4, std::vector<Point>());
    auto idx = [](Point v) -> int {
        if (v.second >= 0)
            return (v.first >= 0) ? 0 : 1;
        else
            return (v.first >= 0) ? 3 : 2;
    };
    for (auto p : a) {
        assert(!(p.first == 0 && p.second == 0));
        ps[idx(p)].emplace_back(p);
    }
    a.clear();
    a.reserve(n);
    for (int i = 0; i < 4; i++) {
        std::sort(ps[i].begin(), ps[i].end(), [](Point &p1, Point &p2) -> bool {
            T flag = p1.first * p2.second - p2.first * p1.second;
            return flag == 0 ? (p1.first * p1.first + p1.second * p1.second <
                                p2.first * p2.first + p2.second * p2.second)
                             : flag > 0;
        });
        for (auto &p : ps[i]) a.emplace_back(p);
    }
    return;
}

}  // namespace ebi
#line 2 "geometry/line.hpp"

#line 5 "geometry/line.hpp"

#line 7 "geometry/line.hpp"

namespace ebi {

struct line {
    point a, b;

    line(long double x1, long double y1, long double x2, long double y2)
        : a(x1, y1), b(x2, y2) {}

    line(const point &a, const point &b) : a(a), b(b) {}

    point proj(const point &p) const {
        return a + (b - a) * (dot(b - a, p - a) / norm(b - a));
    }

    point relf(const point &p) const { return proj(p) * double(2) - p; }

    long double distance(const point &c) const {
        return std::abs(det(c - a, b - a) / abs(b - a));
    }
};

int intersection(const line &a, const line &b) {
    if (internal::sgn(det(a.b - a.a, b.a - b.b)) != 0) {
        if (internal::sgn(dot(a.b - a.a, b.b - b.a)) == 0) {  // 垂直
            return 1;
        }
        return 0;                                                // 交差
    } else if (internal::sgn(det(a.b - a.a, b.a - a.a)) != 0) {  // 平行
        return 2;
    } else {  // 同一直線
        return 3;
    }
}

point cross_point(const point &a, const point &b, const point &c,
                  const point &d) {
    return a + (b - a) * det(c - a, d - c) / det(b - a, d - c);
}

// 交点があるか確認する！
point cross_point(const line &s, const line &t) {
    assert(intersection(s, t) < 2);
    return s.a +
           (s.b - s.a) * det(t.a - s.a, t.b - t.a) / det(s.b - s.a, t.b - t.a);
}

// 直線aと点cの距離
long double distance(const line &a, const point &c) {
    return std::abs(det(c - a.a, a.b - a.a) / abs(a.b - a.a));
}

long double distance(const line &a, const line &b) {
    if (intersection(a, b) < 2) {
        return 0;
    } else {
        return distance(a, b.a);
    }
}

}  // namespace ebi
#line 2 "geometry/line_segment.hpp"

#line 5 "geometry/line_segment.hpp"

#line 8 "geometry/line_segment.hpp"

namespace ebi {

struct line_segment {
    point a, b;

    line_segment() = default;

    line_segment(long double x1, long double y1, long double x2, long double y2)
        : a(x1, y1), b(x2, y2) {}

    line_segment(const point &a, const point &b) : a(a), b(b) {}
};

// 線分ab, cd が交わるか判定
bool intersection_line_segment(const point &a, const point &b, const point &c,
                               const point &d) {
    if (internal::sgn(isp(a, b, c) * isp(a, b, d)) <= 0 &&
        internal::sgn(isp(c, d, a) * isp(c, d, b)) <= 0) {
        return true;
    }
    return false;
}

// 線分ab, cd が交わるか判定
bool intersection(const line_segment &a, const line_segment &b) {
    return intersection_line_segment(a.a, a.b, b.a, b.b);
}

bool intersection(const line &a, const line_segment &b) {
    if (internal::sgn(det(b.a - a.a, a.b)) *
            internal::sgn(det(b.b - a.a, a.b)) <
        0) {
        return true;
    } else {
        return false;
    }
}

point cross_point(const line_segment &s, const line_segment &t) {
    assert(intersection(s, t));
    return s.a +
           (s.b - s.a) * det(t.a - s.a, t.b - t.a) / det(s.b - s.a, t.b - t.a);
}

long double distance(const line_segment &a, const point &c) {
    if (internal::sgn(dot(a.b - a.a, c - a.a)) < 0) {
        return abs(c - a.a);
    } else if (internal::sgn(dot(a.a - a.b, c - a.b)) < 0) {
        return abs(c - a.b);
    } else {
        return std::abs(det(c - a.a, a.b - a.a) / abs(a.b - a.a));
    }
}

long double distance(const line_segment &a, const line_segment &b) {
    if (intersection(a, b)) {
        return 0;
    } else {
        return std::min(std::min(distance(a, b.a), distance(a, b.b)),
                        std::min(distance(b, a.a), distance(b, a.b)));
    }
}

long double distance(const line &a, const line_segment &b) {
    if (intersection(a, b)) {
        return 0;
    } else {
        return std::min(distance(a, b.a), distance(a, b.b));
    }
}

}  // namespace ebi
#line 2 "geometry/polygon.hpp"

#line 5 "geometry/polygon.hpp"

#line 8 "geometry/polygon.hpp"

namespace ebi {

using Polygon = std::vector<point>;

long double area(const Polygon &poly) {
    long double s = 0;
    int n = poly.size();
    for (int i = 0; i < n; i++) {
        s = internal::add(s, det(poly[i], poly[(i + 1 != n) ? i + 1 : 0]));
    }
    s /= 2.0;
    return s;
}

// 凸多角形か判定. pに反時計回りで点が入っていると仮定
bool is_convex(const Polygon &poly) {
    int n = poly.size();
    for (int i = 0; i < n; i++) {
        if (isp(poly[i], poly[(i + 1 != n) ? i + 1 : 0],
                poly[(i + 2 < n) ? i + 2 : (i + 2) % n]) == -1) {
            return false;
        }
    }
    return true;
}

enum { OUT, ON, IN };

int contains(const Polygon &poly, const point &p) {
    bool in = false;
    int n = poly.size();
    for (int i = 0; i < n; i++) {
        point a = poly[i] - p;
        point b = poly[(i + 1 < n) ? i + 1 : 0] - p;
        if (a.y > b.y) std::swap(a, b);
        if (a.y <= 0 && 0 < b.y && det(a, b) < 0) in = !in;
        if (det(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}

long double convex_diameter(const Polygon &convex_poly) {
    int n = convex_poly.size();
    int is = 0, js = 0;
    for (int i = 1; i < n; i++) {
        if (convex_poly[i].y > convex_poly[is].y) is = i;
        if (convex_poly[i].y < convex_poly[js].y) js = i;
    }
    long double max = (convex_poly[is] - convex_poly[js]).abs();
    int i, max_i, j, max_j;
    i = max_i = is;
    j = max_j = js;
    do {
        if (det(convex_poly[(i + 1 < n) ? i + 1 : 0] - convex_poly[i],
                convex_poly[(j + 1 < n) ? j + 1 : 0] - convex_poly[j]) >= 0) {
            j = (j + 1 < n) ? j + 1 : 0;
        } else {
            i = (i + 1 < n) ? i + 1 : 0;
        }
        if ((convex_poly[i] - convex_poly[j]).abs() > max) {
            max = (convex_poly[i] - convex_poly[j]).abs();
            max_i = i;
            max_j = j;
        }
    } while (i != is || j != js);
    return max;
}

Polygon convex_polygon_cut(const Polygon &poly, const line &l) {
    Polygon ret;
    int n = poly.size();
    for (int i = 0; i < n; i++) {
        const point &now = poly[i];
        const point &nxt = poly[(i + 1 < n) ? i + 1 : 0];
        long double cf = det(l.a - now, l.b - now);
        long double cs = det(l.a - nxt, l.b - nxt);
        if (internal::sgn(cf) >= 0) {
            ret.emplace_back(now);
        }
        if (internal::sgn(cf) * internal::sgn(cs) < 0) {
            ret.emplace_back(cross_point(line(now, nxt), l));
        }
    }
    return ret;
}

}  // namespace ebi
#line 10 "geometry/circle.hpp"

namespace ebi {

struct circle {
    point c;
    long double r;
    circle() = default;
    circle(const point &c, long double r) : c(c), r(r) {}
};

int intersection(const circle &c1, const circle &c2) {
    long double d = abs(c1.c - c2.c);
    long double r1 = c1.r, r2 = c2.r;
    if (r1 < r2) std::swap(r1, r2);
    if (d > internal::add(r1, r2)) {
        return 4;
    } else if (d == internal::add(r1, r2)) {
        return 3;
    } else if (d > internal::add(r1, -r2)) {
        return 2;
    } else if (d == internal::add(r1, -r2)) {
        return 1;
    } else {
        return 0;
    }
}

circle incircle_of_triangle(const point &A, const point &B, const point &C) {
    long double a = abs(B - C), b = abs(C - A), c = abs(A - B);
    point in = A * a + B * b + C * c;
    in /= (a + b + c);
    long double r = distance(line(A, B), in);
    return circle(in, r);
}

circle circumscribed_circle_of_triangle(const point &A, const point &B,
                                        const point &C) {
    line p((A + B) / 2, (A + B) / 2 + rot90(B - A));
    line q((B + C) / 2, (B + C) / 2 + rot90(C - B));
    point cross = cross_point(p, q);
    return circle(cross, abs(A - cross));
}

std::vector<point> cross_point(const circle &c, const line &l) {
    std::vector<point> ps;
    long double d = distance(l, c.c);
    if (d == c.r) {
        ps.emplace_back(l.proj(c.c));
    } else if (d < c.r) {
        point p = l.proj(c.c);
        point v = l.b - l.a;
        v = v *
            std::sqrt(
                std::max(internal::add(c.r * c.r, -d * d), (long double)0)) /
            v.abs();
        ps.emplace_back(p + v);
        ps.emplace_back(p - v);
    }
    return ps;
}

std::vector<point> cross_point(const circle &c1, const circle &c2) {
    std::vector<point> ps;
    int flag = intersection(c1, c2);
    if (flag == 0 || flag == 4) {
        return ps;
    }
    long double d = (c2.c - c1.c).abs();
    long double x =
        internal::add(internal::add(d * d, c1.r * c1.r), -c2.r * c2.r) /
        (2.0 * d);
    point p = c1.c + (c2.c - c1.c) * x / d;
    point v = rot90(c2.c - c1.c);
    if (flag == 1 || flag == 3) {
        ps.emplace_back(p);
    } else {
        v = v *
            std::sqrt(
                std::max(internal::add(c1.r * c1.r, -x * x), (long double)0)) /
            v.abs();
        ps.emplace_back(p + v);
        ps.emplace_back(p - v);
    }
    return ps;
}

std::vector<point> cross_point(const circle &c, const line_segment &ls) {
    std::vector<point> ps = cross_point(c, line(ls.a, ls.b));
    std::vector<point> ret;
    for (auto p : ps) {
        if (internal::sgn(distance(ls, p)) == 0) {
            ret.emplace_back(p);
        }
    }
    return ret;
}

std::vector<point> tangent_to_circle(const circle &c, const point &p) {
    std::vector<point> ps;
    point v = p - c.c;
    long double d = v.abs();
    long double h = std::sqrt(
        std::max(internal::add(norm(v), -c.r * c.r), (long double)(0.0)));
    long double cos = c.r / d, sin = h / d;
    point f(internal::add(v.x * cos, -v.y * sin),
            internal::add(v.x * sin, v.y * cos));
    point g(internal::add(v.x * cos, v.y * sin),
            internal::add(-v.x * sin, v.y * cos));
    f = f * c.r / f.abs();
    g = g * c.r / g.abs();
    ps.emplace_back(c.c + f);
    ps.emplace_back(c.c + g);
    return ps;
}

std::vector<line> tangent(circle c1, circle c2) {
    std::vector<line> ret;
    int flag = intersection(c1, c2);
    if (flag == 2 || flag == 3 || flag == 4) {
        if (c1.r == c2.r) {
            point v = c2.c - c1.c;
            v = rot90(v * c1.r / abs(v));
            ret.emplace_back(line(c1.c + v, c2.c + v));
            ret.emplace_back(line(c1.c - v, c2.c - v));
        } else {
            point v = c1.c * (-c2.r) + c2.c * c1.r;
            v = v / (c1.r - c2.r);
            auto bs = tangent_to_circle(c1, v);
            auto as = tangent_to_circle(c2, v);
            for (int i = 0; i < (int)std::min(bs.size(), as.size()); i++) {
                ret.emplace_back(line(bs[i], as[i]));
            }
        }
    } else if (flag == 1) {
        point v = c2.c - c1.c;
        if (c1.r > c2.r)
            v = v * c1.r / v.abs();
        else
            v = v * (-c1.r) / v.abs();
        point p = c1.c + v;
        ret.emplace_back(line(p, p + rot90(v)));
    }
    if (flag == 4) {
        point p = c1.c * c2.r + c2.c * c1.r;
        p = p / (c1.r + c2.r);
        auto bs = tangent_to_circle(c1, p);
        auto as = tangent_to_circle(c2, p);
        for (int i = 0; i < (int)std::min(bs.size(), as.size()); i++) {
            ret.emplace_back(line(bs[i], as[i]));
        }
    } else if (flag == 3) {
        point v = c2.c - c1.c;
        v = v * c1.r / v.abs();
        point p = c1.c + v;
        ret.emplace_back(p, p + rot90(v));
    }
    return ret;
}

long double calc_common_area(const circle &c, const Polygon &poly) {
    if (int(poly.size()) < 3) return 0.0;
    long double s = 0;
    int n = poly.size();
    auto cross_area = [&](auto &&self, const point &a,
                          const point b) -> long double {
        point va = c.c - a, vb = c.c - b;
        long double f = det(va, vb) / 2.0, ret = 0.0;
        if (internal::sgn(f) == 0) return 0.0;
        if (std::max(va.abs(), vb.abs()) < c.r + EPS) return f;
        if (internal::sgn(
                internal::add(distance(line_segment(a, b), c.c), -c.r)) >= 0) {
            return c.r * c.r * (vb * conj(va)).arg() / 2.0;
        }
        auto ps = cross_point(c, line_segment(a, b));
        if (int(ps.size()) == 1) ps.emplace_back(ps.back());
        std::vector<point> tot = {a, ps[0], ps[1], b};
        std::sort(tot.begin(), tot.end());
        if (b < a) {
            std::reverse(tot.begin(), tot.end());
        }
        int sz = tot.size();
        for (int i = 0; i + 1 < sz; i++) {
            ret += self(self, tot[i], tot[i + 1]);
        }
        return ret;
    };
    for (int i = 0; i < n; i++) {
        s += cross_area(cross_area, poly[i], poly[(i + 1 < n) ? i + 1 : 0]);
    }
    return s;
}

long double common_area(const circle &c1, const circle &c2) {
    int flag = intersection(c1, c2);
    if (flag == 3 || flag == 4)
        return 0.0;
    else if (flag == 0 || flag == 1) {
        long double r = std::min(c1.r, c2.r);
        return PI * r * r;
    } else {
        long double d = (c1.c - c2.c).abs();
        long double theta1 = std::acos(
            internal::add(internal::add(c1.r * c1.r, d * d), -c2.r * c2.r) /
            (2.0 * c1.r * d));
        long double area1 = internal::add(
            c1.r * c1.r * theta1, -c1.r * c1.r * std::sin(theta1 * 2) / 2.0);
        long double theta2 = std::acos(
            internal::add(internal::add(c2.r * c2.r, d * d), -c1.r * c1.r) /
            (2.0 * c2.r * d));
        long double area2 = internal::add(
            c2.r * c2.r * theta2, -c2.r * c2.r * std::sin(theta2 * 2) / 2.0);
        return internal::add(area1, area2);
    }
}

}  // namespace ebi

namespace ebi {

void main_() {
    int n;
    std::cin >> n;
    std::vector circles(n, std::vector<circle>(2));
    rep(i, 0, n) {
        int r;
        std::cin >> r;
        rep(j, 0, 2) {
            circles[i][j].r = r;
            std::cin >> circles[i][j].c;
        }
    }
    std::vector<int> dp(1 << n, -1);
    dp[0] = 0;
    int ans = 0;
    rep(bit,0,1<<n) {
        rep(i,0,n) {
            if((bit >> i) & 1) {
                if(dp[bit^(1<<i)] < 0) continue;
                dp[bit] = dp[bit^(1<<i)] + 1;
                rep(j,0,n) {
                    if(i == j) continue;
                    auto c = circles[j][(bit >> j) & 1];
                    if(distance(line_segment(circles[i][0].c, circles[i][1].c), c.c) < c.r + circles[i][0].r) {
                        dp[bit] = -1;
                    }
                }
                if(dp[bit] >= 0) break;
            }
        }
        chmax(ans, dp[bit]);
    }
    std::cout << ans << '\n';
}

}  // namespace ebi

int main() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int t = 1;
    // std::cin >> t;
    while (t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3640
final_rank: 2

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

// arg(x) : argment,[-PI,PI]
using CP = complex<long double>;
#define X real()
#define Y imag()
const long double PI = acos(-1.0L);
const long double EPS = 1e-10;
bool operator==(const CP &l, const CP &r) { return norm(l - r) <= EPS; }
struct Circle {
  CP o;
  long double r;
  Circle(long double _x = 0.0L, long double _y = 0.0L, long double _r = 0.0L)
      : o(CP(_x, _y)), r(_r) {}
  Circle(CP _o, long double _r = 0.0) : o(_o), r(_r) {}
  bool operator<(const Circle &cr) const { return r < cr.r; }
};

struct Line {
  CP s, t;
  Line(long double sx = 0.0L, long double sy = 0.0L, long double tx = 0.0L,
       long double ty = 0.0L)
      : s(CP(sx, sy)), t(CP(tx, ty)) {}
  Line(CP _s, CP _t) : s(_s), t(_t) {}
};

// cos a
long double costh(const long double &a, const long double &b,
                  const long double &c) {
  return (b * b - a * a + c * c) / (2.0L * b * c);
}

// dot(a,b) = |a||b|cos x
long double dot(const CP &a, const CP &b) { return (conj(a) * b).X; }
// cross(a,b) : area of parallelogram
// sign : a-> b ,counter clockwise? + : -
long double cross(const CP &a, const CP &b) { return (conj(a) * b).Y; }
long double corner(const CP &a, const CP &b) {
  //[0,PI]
  return acos(dot(a, b) / (abs(a) * abs(b)));
}

CP projectionLP(const CP &s, const CP &t, const CP &p) {
  if (s == t) return s;
  CP base = t - s;
  long double r = dot(p - s, base) / norm(base);
  return s + base * r;
}
CP projectionLP(const Line &l, const CP &p) {
  return projectionLP(l.s, l.t, p);
}

CP reflectionLP(const CP &s, const CP &t, const CP &p) {
  CP tmp = (projectionLP(s, t, p) - p);
  tmp *= 2;
  return p + tmp;
}
CP reflectionLP(const Line &l, const CP &p) {
  return reflectionLP(l.s, l.t, p);
}

int calc_clockwiseSP(const CP &s, CP t, CP p) {
  t -= s;
  p -= s;
  if (cross(t, p) > EPS) return 1;    // "COUNTER_CLOCKWISE"
  if (cross(t, p) < -EPS) return -1;  //"CLOCK_WISE"
  if (dot(t, p) < 0) return 2;        // "ONLINE_BACK"
  if (norm(t) < norm(p)) return -2;   // "ONLINE_FRONT"
  return 0;                           // "ON_SEGMENT"
}
int calc_clockwiseSP(const Line &l, const CP &p) {
  return calc_clockwiseSP(l.s, l.t, p);
}

int parallel_orthogonalLL(const CP &s, CP t, const CP &a, CP b) {
  t -= s;
  b -= a;
  if (abs(cross(t, b)) <= EPS) return 2;  // "parallel"
  if (abs(dot(t, b)) <= EPS) return 1;    // "orthogonal"
  return 0;
}
int parallel_orthogonalLL(const Line &ll, const Line &lr) {
  return parallel_orthogonalLL(ll.s, ll.t, lr.s, lr.t);
}

CP intersectionLL(const CP &a, const CP &b, const CP &c, const CP &d) {
  return a + (b - a) * (cross(d - c, c - a) / cross(d - c, b - a));
}
CP intersectionLL(const Line &ll, const Line &lr) {
  return intersectionLL(ll.s, ll.t, lr.s, lr.t);
}

bool on_segSP(const CP &s, const CP &t, const CP &p) {
  // if not use end point, dot(s - p, t - p) < 0
  return abs(cross(s - p, t - p)) <= EPS && dot(s - p, t - p) <= 0;
}
bool on_segSP(const Line &l, const CP &p) { return on_segSP(l.s, l.t, p); }

// crossing segments? (a,b) and (c,d)
bool iscrossSS(const CP &a, const CP &b, const CP &c, const CP &d) {
  // parallel
  return calc_clockwiseSP(a, b, c) * calc_clockwiseSP(a, b, d) <= 0 &&
         calc_clockwiseSP(c, d, a) * calc_clockwiseSP(c, d, b) <= 0;
  // if (abs(cross(a - b, c - d)) <= EPS) {
  //   return on_segSP(a, b, c) || on_segSP(a, b, d) || on_segSP(c, d, a) ||
  //          on_segSP(c, d, b);
  // }
  // CP isp = intersectionLL(a, b, c, d);
  // return on_segSP(a, b, isp) && on_segSP(c, d, isp);
}

bool iscrossSS(const Line &ll, const Line &lr) {
  return iscrossSS(ll.s, ll.t, lr.s, lr.t);
}

long double distLP(const CP &s, const CP &t, const CP &p) {
  return abs(cross(t - s, p - s) / abs(t - s));
}
long double distLP(const Line &l, const CP &p) { return distLP(l.s, l.t, p); }

long double distSP(const CP &s, const CP &t, const CP &p) {
  if (dot(t - s, p - s) < 0) return abs(p - s);
  if (dot(s - t, p - t) < 0) return abs(p - t);
  return distLP(s, t, p);
}
long double distSP(const Line &l, const CP &p) { return distSP(l.s, l.t, p); }

long double distSS(const CP &a, const CP &b, const CP &c, const CP &d) {
  long double res = 1e18;
  if (iscrossSS(a, b, c, d)) return 0.0L;
  res = min(res, distSP(a, b, c));
  res = min(res, distSP(a, b, d));
  res = min(res, distSP(c, d, a));
  res = min(res, distSP(c, d, b));
  return res;
}
long double distSS(const Line &ll, const Line &lr) {
  return distSS(ll.s, ll.t, lr.s, lr.t);
}

// counter clockwise
bool is_convex(const vector<CP> &pol) {
  int n = pol.size();
  for (int i = 0; i < n; ++i)
    if (cross(pol[(i + 1) % n] - pol[i], pol[(i + 2) % n] - pol[(i + 1) % n]) <
        -EPS)
      return 0;
  return 1;
}

vector<CP> convex_hull(vector<CP> &ps) {
  auto lmd = [&](const CP &l, const CP &r) {
    if (l.X != r.X) return l.X < r.X;
    return l.Y < r.Y;
  };
  vector<CP> res;
  int psize = ps.size();
  sort(ps.begin(), ps.end(), lmd);
  int k = 0;
  res.resize(psize * 2);
  for (int i = 0; i < psize; ++i) {
    while (k > 1 && cross(res[k - 1] - res[k - 2], ps[i] - res[k - 1]) <= 0)
      --k;
    res[k++] = ps[i];
  }
  for (int i = psize - 2, t = k; i >= 0; --i) {
    while (k > t && cross(res[k - 1] - res[k - 2], ps[i] - res[k - 1]) <= 0)
      --k;
    res[k++] = ps[i];
  }
  res.resize(k - 1);
  return res;
}

long double convex_diameter(const vector<CP> &pol) {
  vector<CP> ps = pol;
  ps = convex_hull(ps);
  int n = ps.size(), i = 0, j = 0;
  if (n < 2) return 0.0L;
  if (n == 2) return abs(ps[0] - ps[1]);
  for (int k = 0; k < n; ++k) {
    if (ps[k].X < ps[i].X) i = k;
    if (ps[k].X > ps[j].X) j = k;
  }
  long double res = 0;
  int si = i, sj = j;
  while (i != sj || j != si) {
    res = max(res, abs(ps[i] - ps[j]));
    if (cross(ps[(i + 1) % n] - ps[i], ps[(j + 1) % n] - ps[j]) < 0)
      (++i) %= n;
    else
      (++j) %= n;
  }
  return res;
}

vector<CP> convex_cut(const vector<CP> &pol, const CP &s, const CP &t) {
  vector<CP> res;
  int n = pol.size();
  for (int i = 0; i < n; ++i) {
    CP nows = pol[i], nowt = pol[(i + 1) % n];
    if (cross(t - s, nows - s) >= -EPS) res.push_back(nows);
    if (cross(t - s, nows - s) * cross(t - s, nowt - s) < 0)
      res.push_back(intersectionLL(s, t, nows, nowt));
  }
  return res;
}
vector<CP> convex_cut(const vector<CP> &pol, const Line &l) {
  return convex_cut(pol, l.s, l.t);
}

// number of tangents
int iscrossCC(Circle l, Circle r) {
  if (l.r < r.r) swap(l, r);
  long double distlr = abs(l.o - r.o);
  if (l.r + r.r < distlr)
    return 4;  // not touch
  else if (abs(distlr - l.r - r.r) <= EPS)
    return 3;  // circumscription
  else if (l.r - r.r < distlr)
    return 2;  // cross
  else if (abs(distlr - l.r + r.r) <= EPS)
    return 1;  // inscribed
  else         // contain
    return 0;
}

vector<CP> intersectionCC(const Circle &c1, const Circle &c2) {
  vector<CP> res;
  if (iscrossCC(c1, c2) == 4) return res;

  long double d = abs(c1.o - c2.o);
  long double a = acos(costh(c2.r, c1.r, d));
  long double t = atan2(c2.o.imag() - c1.o.imag(), c2.o.real() - c1.o.real());
  res.push_back(c1.o + CP(cos(t + a) * c1.r, sin(t + a) * c1.r));
  res.push_back(c1.o + CP(cos(t - a) * c1.r, sin(t - a) * c1.r));
  if (res[0].X > res[1].X || (res[0].X == res[1].X && res[0].Y > res[1].Y))
    swap(res[0], res[1]);
  return res;
}

vector<CP> intersectionCL(const Circle &ci, const CP &s, CP t) {
  vector<CP> res(2, projectionLP(s, t, ci.o));
  long double r = sqrt(ci.r * ci.r - norm(res[0] - ci.o));
  if (r <= EPS || t == s) return res;
  t -= s;
  t *= r / abs(t);
  res[0] += t;
  res[1] -= t;
  if (res[0].X > res[1].X || (res[0].X == res[1].X && res[0].Y > res[1].Y))
    swap(res[0], res[1]);
  return res;
}
vector<CP> intersectionCL(const Circle &ci, const Line &l) {
  return intersectionCL(ci, l.s, l.t);
}

vector<CP> contactCP(const Circle &ci, const CP &p) {
  vector<CP> res;
  long double d = abs(ci.o - p);
  if (abs(d - ci.r) <= EPS) {
    res.push_back(p);
    return res;
  } else if (d < ci.r)
    return res;
  long double arg = asin(ci.r / d);
  res.push_back((ci.o - p) * CP(cos(arg), sin(arg)));
  res[0] *= (d * cos(arg)) / abs(res[0]);
  res[0] += p;
  res.push_back(reflectionLP(p, ci.o, res[0]));
  if (res[0].X > res[1].X || (res[0].X == res[1].X && res[0].Y > res[1].Y))
    swap(res[0], res[1]);
  return res;
}

vector<Line> tangentCC(Circle cl, Circle cr) {
  vector<Line> res;
  if (cl.r < cr.r) swap(cl, cr);
  long double g = abs(cl.o - cr.o);
  if (abs(g - 0.0L) <= EPS) return res;
  CP hor = (cr.o - cl.o) / g, ver;
  ver = hor * (CP(cos(PI * 0.5L), sin(PI * 0.5L)));
  for (int s : {-1, 1}) {
    long double h = (cl.r + s * cr.r) / g;
    if (abs(1 - h * h) <= EPS) {
      res.emplace_back(cl.o + hor * cl.r, cl.o + (hor + ver) * cl.r);
    } else if (1 - h * h > 0) {
      CP nhor = hor * h, nver = ver * sqrtl(1 - h * h);
      res.emplace_back(cl.o + (nhor + nver) * cl.r,
                       cr.o - (nhor + nver) * (cr.r * s));
      res.emplace_back(cl.o + (nhor - nver) * cl.r,
                       cr.o - (nhor - nver) * (cr.r * s));
    }
  }
  return res;
}

long double areaPol(const vector<CP> &pol) {
  int n = pol.size();
  long double res = 0;
  for (int i = 0; i < n; ++i)
    res += (pol[(i - 1 + n) % n].X - pol[(i + 1) % n].X) * pol[i].Y;
  return res / 2.0L;
}

int containPolP(const vector<CP> &pol, CP p) {
  bool con = 0, onseg = 0;
  int n = pol.size();
  for (int i = 0; i < n; ++i) {
    onseg |= on_segSP(pol[i], pol[(i + 1) % n], p);
    CP s = pol[i] - p, t = pol[(i + 1) % n] - p;
    if (s.Y > t.Y) swap(s, t);
    if (s.Y * t.Y <= 0 && t.Y > 0 && cross(s, t) < 0) con = !con;
  }
  if (onseg) return 1;
  if (con) return 2;
  return 0;
}

long double closest_pair(vector<CP> &ps, int l = -1, int r = -1,
                         bool reqsqrt = 0) {
  if (l == r && l == -1) {
    l = 0;
    r = ps.size();
    reqsqrt = 1;
    auto lmd = [&](const CP &l, const CP &r) {
      if (l.X != r.X) return l.X < r.X;
      return l.Y < r.Y;
    };
    sort(ps.begin(), ps.end(), lmd);
  }
  if (r - l < 2) return 1e18;
  if (r - l == 2) {
    if (ps[l].Y > ps[l + 1].Y) swap(ps[l], ps[l + 1]);
    if (reqsqrt) return abs(ps[l] - ps[l + 1]);
    return norm(ps[l] - ps[l + 1]);
  }
  int mid = (l + r) / 2;
  long double x = ps[mid].X,
              res = min(closest_pair(ps, l, mid), closest_pair(ps, mid, r));
  auto f = [](CP pl, CP pr) { return pl.Y < pr.Y; };
  inplace_merge(ps.begin() + l, ps.begin() + mid, ps.begin() + r, f);
  vector<CP> tmp;
  for (int i = l; i < r; ++i) {
    long double dx = abs(ps[i].X - x);
    int tsize = tmp.size();
    if (dx * dx >= res) continue;
    for (int j = 0; j < tsize; ++j) {
      CP delta = ps[i] - tmp[tsize - 1 - j];
      if (delta.Y * delta.Y >= res) break;
      res = min(res, norm(delta));
    }
    tmp.push_back(ps[i]);
  }
  if (reqsqrt) res = sqrtl(res);
  return res;
}

Circle min_ball(vector<CP> ps) {
  int n = ps.size();
  if (n == 1) return Circle(ps[0], 0.0L);
  mt19937 mt(int(time(0)));
  shuffle(ps.begin(), ps.end(), mt);
  auto make3 = [](const CP &a, const CP &b, const CP &c) {
    long double A = norm(b - c), B = norm(c - a), C = norm(a - b),
                S = cross(b - a, c - a);
    CP p = (A * (B + C - A) * a + B * (C + A - B) * b + C * (A + B - C) * c) /
           (4 * S * S);
    long double nowr = norm(p - a);
    return Circle(p, nowr);
  };
  auto make2 = [](const CP &a, const CP &b) {
    CP c = (a + b) / 2.0L;
    long double nowr = norm(a - c);
    return Circle(c, nowr);
  };
  auto in_circle = [](const CP &a, const Circle &c) {
    return norm(a - c.o) <= c.r + EPS;
  };
  Circle res = make2(ps[0], ps[1]);
  for (int i = 2; i < n; ++i)
    if (!in_circle(ps[i], res)) {
      res = make2(ps[0], ps[i]);
      for (int j = 1; j < i; ++j)
        if (!in_circle(ps[j], res)) {
          res = make2(ps[i], ps[j]);
          for (int k = 0; k < j; ++k)
            if (!in_circle(ps[k], res)) res = make3(ps[i], ps[j], ps[k]);
        }
    }
  res.r = sqrtl(res.r);
  return res;
}

bool arg_comp(CP a, CP b) {
  int up_down_a = a.Y > 0 || (abs(a.Y) <= EPS && a.X >= 0);
  int up_down_b = b.Y > 0 || (abs(b.Y) <= EPS && b.X >= 0);
  if (up_down_a != up_down_b) return up_down_a < up_down_b;
  if (a.X * b.Y == a.Y * b.X) return norm(a) < norm(b);
  return calc_clockwiseSP(CP(0, 0), a, b) == 1;
}
bool operator<(const Line &l, const Line &r) {
  CP lp = l.t - l.s, rp = r.t - r.s;
  return arg_comp(lp, rp);
}

int n;
vector<int> r;
vector<vector<CP>> v;

int solve();

int main() {
  cin >> n;
  r.resize(n);
  v.resize(2);
  for (int i = 0; i < n; ++i) {
    cin >> r[i];
    for (int j = 0; j < 2; ++j) {
      int x, y;
      cin >> x >> y;
      v[j].emplace_back(x, y);
    }
  }
  cout << solve() << endl;
  return 0;
}

int solve() {
  vector<int> dp(1 << n, 0);
  dp[0] = 1;
  for (int i = 0; i < (1 << n); ++i)
    if (dp[i])
      for (int j = 0; j < n; ++j)
        if (!(i >> j & 1)) {
          int ch = 1;
          for (int k = 0; k < n; ++k)
            if (j != k) {
              long double d = distSP(v[0][j], v[1][j], v[i >> k & 1][k]);
              if (d <= r[j] + r[k]) ch = 0;
            }
          if (ch) dp[i | (1 << j)] = 1;
        }
  int res = 0;
  for (int i = 1; i < (1 << n); ++i)
    if (dp[i]) res = max(res, (int)__builtin_popcount(i));
  return res;
}
accuracy: 1
time_ms: 360
memory_kb: 3520
final_rank: 18

code_snippet: #line 1 "main.cpp"
#pragma region Macros
#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;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define OVERLOAD3(_1, _2, _3, name, ...) name
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define REP1(i, n) for(int i = 0; i < (n); i++)
#define REP2(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(...) OVERLOAD3(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
constexpr int MOD2 = 998244353;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

void Case(int i) { cout << "Case #" << i << ": "; }
int popcount(int x) { return __builtin_popcount(x); }
ll popcount(ll x) { return __builtin_popcountll(x); }
#pragma endregion Macros

#line 1 "/home/siro53/kyo-pro/compro_library/geometry/geometry.hpp"
namespace geometry {
    // Point : 複素数型を位置ベクトルとして扱う
    // 実軸(real)をx軸、挙軸(imag)をy軸として見る
    using D = double;
    using Point = complex<D>;
    const D EPS = 1e-7;
    const D PI = acosl(-1);

    inline bool equal(const D &a, const D &b) { return fabs(a - b) < EPS; }

    // 単位ベクトル(unit vector)を求める
    Point unitVector(const Point &a) { return a / abs(a); }

    // 法線ベクトル(normal vector)を求める
    // 90度回転した単位ベクトルをかける
    // -90度がよければPoint(0, -1)をかける
    Point normalVector(const Point &a) { return a * Point(0, 1); }

    // 内積(dot product) : a・b = |a||b|cosΘ
    D dot(const Point &a, const Point &b) {
        return (a.real() * b.real() + a.imag() * b.imag());
    }

    // 外積(cross product) : a×b = |a||b|sinΘ
    D cross(const Point &a, const Point &b) {
        return (a.real() * b.imag() - a.imag() * b.real());
    }

    // 点pを反時計回りにtheta度回転
    // thetaはラジアン！！！
    Point rotate(const Point &p, const D &theta) {
        return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                     sin(theta) * p.real() + cos(theta) * p.imag());
    }

    // ラジアン->度
    D radianToDegree(const D &radian) { return radian * 180.0 / PI; }

    // 度->ラジアン
    D degreeToRadian(const D &degree) { return degree * PI / 180.0; }

    // 点の回転方向
    // 点a, b, cの位置関係について(aが基準点)
    int ccw(const Point &a, Point b, Point c) {
        b -= a, c -= a;
        // 点a, b, c が
        // 反時計回りの時、
        if(cross(b, c) > EPS) return 1;
        // 時計回りの時、
        if(cross(b, c) < -EPS) return -1;
        // c, a, bがこの順番で同一直線上にある時、
        if(dot(b, c) < 0) return 2;
        // a, b, cがこの順番で同一直線上にある場合、
        if(norm(b) < norm(c)) return -2;
        // cが線分ab上にある場合、
        return 0;
    }

    // Line : 直線を表す構造体
    // b - a で直線・線分を表せる
    struct Line {
        Point a, b;
        Line() = default;
        Line(Point a, Point b) : a(a), b(b) {}
        // Ax+By=C
        Line(D A, D B, D C) {
            if(equal(A, 0)) {
                a = Point(0, C / B), b = Point(1, C / B);
            } else if(equal(B, 0)) {
                b = Point(C / A, 0), b = Point(C / A, 1);
            } else {
                a = Point(0, C / B), b = Point(C / A, 0);
            }
        }
    };

    // Segment : 線分を表す構造体
    // Lineと同じ
    struct Segment : Line {
        Segment() = default;

        Segment(Point a, Point b) : Line(a, b) {}
    };

    // Circle : 円を表す構造体
    // pが中心の位置ベクトル、rは半径
    struct Circle {
        Point p;
        D r;

        Circle() = default;

        Circle(Point p, D r) : p(p), r(r) {}
    };

    // 2直線の直交判定 : a⊥b <=> dot(a, b) = 0
    bool isOrthogonal(const Line &a, const Line &b) {
        return equal(dot(a.b - a.a, b.b - b.a), 0);
    }
    // 2直線の平行判定 : a//b <=> cross(a, b) = 0
    bool isParallel(const Line &a, const Line &b) {
        return equal(cross(a.b - a.a, b.b - b.a), 0);
    }

    // 点cが直線ab上にあるか
    bool isPointOnLine(const Point &a, const Point &b, const Point &c) {
        return isParallel(Line(a, b), Line(a, c));
    }

    // 点cが"線分"ab上にあるか
    bool isPointOnSegment(const Point &a, const Point &b, const Point &c) {
        // |a-c| + |c-b| <= |a-b| なら線分上
        return (abs(a - c) + abs(c - b) < abs(a - b) + EPS);
    }

    // 直線lと点pの距離を求める
    D distanceBetweenLineAndPoint(const Line &l, const Point &p) {
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 線分lと点pの距離を求める
    // 定義：点pから「線分lのどこか」への最短距離
    D distanceBetweenSegmentAndPoint(const Segment &l, const Point &p) {
        if(dot(l.b - l.a, p - l.a) < EPS) return abs(p - l.a);
        if(dot(l.a - l.b, p - l.b) < EPS) return abs(p - l.b);
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 直線s, tの交点の計算
    Point crossPoint(const Line &s, const Line &t) {
        D d1 = cross(s.b - s.a, t.b - t.a);
        D d2 = cross(s.b - s.a, s.b - t.a);
        if(equal(abs(d1), 0) && equal(abs(d2), 0)) return t.a;
        return t.a + (t.b - t.a) * (d2 / d1);
    }

    // 線分s, tの交点の計算
    Point crossPoint(const Segment &s, const Segment &t) {
        return crossPoint(Line(s), Line(t));
    }

    // 線分sと線分tが交差しているかどうか
    // bound:線分の端点を含むか
    bool isIntersect(const Segment &s, const Segment &t, bool bound) {
        return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) < bound &&
               ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) < bound;
    }

    // 線分sとtの距離
    D distanceBetweenSegments(const Segment &s, const Segment &t) {
        if(isIntersect(s, t, 1)) return (D)(0);
        D ans = distanceBetweenSegmentAndPoint(s, t.a);
        chmin(ans, distanceBetweenSegmentAndPoint(s, t.b));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.a));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.b));
        return ans;
    }

    // 射影(projection)
    // 直線(線分)lに点pから引いた垂線の足を求める
    Point projection(const Line &l, const Point &p) {
        D 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) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    // 反射(reflection)
    // 直線lを対称軸として点pと線対称の位置にある点を求める
    Point reflection(const Line &l, const Point &p) {
        return p + (projection(l, p) - p) * (D)2.0;
    }

    // 2つの円の交差判定
    // 返り値は共通接線の数
    int isIntersect(const Circle &c1, const Circle &c2) {
        D d = abs(c1.p - c2.p);
        // 2つの円が離れている場合
        if(d > c1.r + c2.r + EPS) return 4;
        // 外接している場合
        if(equal(d, c1.r + c2.r)) return 3;
        // 内接している場合
        if(equal(d, abs(c1.r - c2.r))) return 1;
        // 内包している場合
        if(d < abs(c1.r - c2.r) - EPS) return 0;
        return 2;
    }

    // 2つの円の交点
    vector<Point> crossPoint(const Circle &c1, const Circle &c2) {
        vector<Point> res;
        int mode = isIntersect(c1, c2);
        // 2つの中心の距離
        D d = abs(c1.p - c2.p);
        // 2円が離れている場合
        if(mode == 4) return res;
        // 1つの円がもう1つの円に内包されている場合
        if(mode == 0) return res;
        // 2円が外接する場合
        if(mode == 3) {
            D t = c1.r / (c1.r + c2.r);
            res.emplace_back(c1.p + (c2.p - c1.p) * t);
            return res;
        }
        // 内接している場合
        if(mode == 1) {
            if(c2.r < c1.r - EPS) {
                res.emplace_back(c1.p + (c2.p - c1.p) * (c1.r / d));
            } else {
                res.emplace_back(c2.p + (c1.p - c2.p) * (c2.r / d));
            }
            return res;
        }
        // 2円が重なる場合
        D rc1 = (c1.r * c1.r + d * d - c2.r * c2.r) / (2 * d);
        D rs1 = sqrt(c1.r * c1.r - rc1 * rc1);
        if(c1.r - abs(rc1) < EPS) rs1 = 0;
        Point e12 = (c2.p - c1.p) / abs(c2.p - c1.p);
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, 1));
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, -1));
        return res;
    }

    // 点pが円cの内部(円周上も含む)に入っているかどうか
    bool isInCircle(const Circle &c, const Point &p) {
        D d = abs(c.p - p);
        return (equal(d, c.r) || d < c.r - EPS);
    }

    // 円cと直線lの交点
    vector<Point> crossPoint(const Circle &c, const Line &l) {
        vector<Point> res;
        D d = distanceBetweenLineAndPoint(l, c.p);
        // 交点を持たない
        if(d > c.r + EPS) return res;
        // 接する
        Point h = projection(l, c.p);
        if(equal(d, c.r)) {
            res.emplace_back(h);
            return res;
        }
        Point e = unitVector(l.b - l.a);
        D ph = sqrt(c.r * c.r - d * d);
        res.emplace_back(h - e * ph);
        res.emplace_back(h + e * ph);
        return res;
    }

    // 点pを通る円cの接線
    // 2本あるので、接点のみを返す
    vector<Point> tangentToCircle(const Point &p, const Circle &c) {
        return crossPoint(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
    }

    // 円の共通接線
    vector<Line> tangent(const Circle &a, const Circle &b) {
        vector<Line> ret;
        // 2円の中心間の距離
        D g = abs(a.p - b.p);
        // 円が内包されている場合
        if(equal(g, 0)) return ret;
        Point u = unitVector(b.p - a.p);
        Point v = rotate(u, PI / 2);
        for(int s : {-1, 1}) {
            D h = (a.r + b.r * s) / g;
            if(equal(h * h, 1)) {
                ret.emplace_back(a.p + (h > 0 ? u : -u) * a.r,
                                 a.p + (h > 0 ? u : -u) * a.r + v);

            } else if(1 - h * h > 0) {
                Point U = u * h, V = v * sqrt(1 - h * h);
                ret.emplace_back(a.p + (U + V) * a.r,
                                 b.p - (U + V) * (b.r * s));
                ret.emplace_back(a.p + (U - V) * a.r,
                                 b.p - (U - V) * (b.r * s));
            }
        }
        return ret;
    }

    // 多角形の面積を求める
    D PolygonArea(const vector<Point> &p) {
        D res = 0;
        int n = p.size();
        for(int i = 0; i < n - 1; i++) res += cross(p[i], p[i + 1]);
        res += cross(p[n - 1], p[0]);
        return res * 0.5;
    }

    // 凸多角形かどうか
    bool isConvex(const vector<Point> &p) {
        int n = p.size();
        int now, pre, nxt;
        for(int i = 0; i < n; i++) {
            pre = (i - 1 + n) % n;
            nxt = (i + 1) % n;
            now = i;
            if(ccw(p[pre], p[now], p[nxt]) == -1) return false;
        }
        return true;
    }

    // 凸包 O(NlogN)
    vector<Point> ConvexHull(vector<Point> &p) {
        int n = (int)p.size(), k = 0;
        sort(ALL(p), [](const Point &a, const Point &b) {
            return (real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b));
        });
        vector<Point> ch(2 * n);
        // 一直線上の3点を含める -> (< -EPS)
        // 含め無い -> (< EPS)
        for(int i = 0; i < n; ch[k++] = p[i++]) { // lower
            while(k >= 2 &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) { // upper
            while(k >= t &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        ch.resize(k - 1);
        return ch;
    }

    // 多角形gに点pが含まれているか?
    // 含まれる:2, 辺上にある:1, 含まれない:0
    int isContained(const vector<Point> &g, const Point &p) {
        bool in = false;
        int n = (int)g.size();
        for(int i = 0; i < n; i++) {
            Point a = g[i] - p, b = g[(i + 1) % n] - p;
            if(imag(a) > imag(b)) swap(a, b);
            if(imag(a) <= EPS && EPS < imag(b) && cross(a, b) < -EPS) in = !in;
            if(cross(a, b) == 0 && dot(a, b) <= 0) return 1;
        }
        return (in ? 2 : 0);
    }

} // namespace geometry
#line 76 "main.cpp"
using namespace geometry;

int main() {
    int N;
    cin >> N;
    vector<tuple<double, Point, Point>> coins(N);
    REP(i, N) {
        int r, sx, sy, gx, gy;
        cin >> r >> sx >> sy >> gx >> gy;
        coins[i] = {r, Point(sx, sy), Point(gx, gy)};
    }

    vector dp(1 << N, 0);
    dp[0] = 1;
    REP(mask, 1 << N) {
        if(dp[mask] == 0) continue;
        REP(i, N) {
            if(mask >> i & 1) continue;
            const auto& [ri, s_pi, g_pi] = coins[i];
            Segment base(s_pi, g_pi);
            bool ok = true;
            REP(j, N) {
                if(i == j) continue;
                const auto& [rj, s_pj, g_pj] = coins[j];
                double d;
                if(mask >> j & 1) {
                    d = distanceBetweenSegmentAndPoint(base, g_pj);
                } else {
                    d = distanceBetweenSegmentAndPoint(base, s_pj);
                }
                if(d <= ri + rj) {
                    ok = false;
                    break;
                }
            }
            if(ok) dp[mask | (1 << i)] = 1;
        }
    }
    int ans = 0;
    REP(mask, 1 << N) if(dp[mask] == 1) chmax(ans, popcount(mask));
    cout << ans << '\n';
}
accuracy: 1
time_ms: 60
memory_kb: 3456
final_rank: 3

code_snippet: // #pragma GCC target("avx2")
// #pragma GCC optimize("Ofast")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-8;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/all>
//using namespace atcoder;
//const int mod = 1e9 + 7;
const int mod = 998244353;

using Point = complex<double>;

double dot(Point a, Point b){
    return a.real() * b.real() + a.imag() * b.imag();
}

double cross(Point a, Point b){
    return a.real() * b.imag() - a.imag() * b.real();
}

struct Segment{
    Point a,b;
    Segment(Point a, Point b) : a(a), b(b) {}
};

double dist(Segment l, Point p){
    if(dot(l.b-l.a, p-l.a) < eps) return abs(p-l.a);
    if(dot(l.a-l.b, p-l.b) < eps) return abs(p-l.b);
    return abs(cross(l.b-l.a, p-l.a)) / abs(l.b-l.a);
}

bool dp[1<<16];

int main(){
    int n; cin >> n;
    vl r(n);
    vector<vector<Point>> p(n,vector<Point>(2));
    rep(i,n){
        int a,b,c,d;
        cin >> r[i] >> a >> b >> c >> d;
        p[i][0] = Point(a,b);
        p[i][1] = Point(c,d);
    }
    dp[0] = 1;
    rep(bit,1<<n){
        rep(i,n){
            bool f = true;
            Segment seg(p[i][0],p[i][1]);
            rep(j,n){
                if(i==j) continue;
                if(dist(seg,p[j][bit>>j&1]) <= eps + r[i] + r[j]){
                    f = false;
                }
            }
            if(f) dp[bit|1<<i] |= dp[bit];
        }
    }
    int ans = 0;
    rep(bit,1<<n) if(dp[bit]) chmax(ans, pcount(bit));
    cout << ans << endl; 
}
accuracy: 1
time_ms: 200
memory_kb: 3484
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define R cin>>
#define Z class
#define ll long long
#define ln cout<<'\n'
#define in(a) insert(a)
#define pb(a) push_back(a)
#define pd(a) printf("%.10f\n",a)
#define mem(a) memset(a,0,sizeof(a))
#define all(c) (c).begin(),(c).end()
#define iter(c) __typeof((c).begin())
#define rrep(i,n) for(ll i=(ll)(n)-1;i>=0;i--)
#define REP(i,m,n) for(ll i=(ll)(m);i<(ll)(n);i++)
#define rep(i,n) REP(i,0,n)
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
template<Z A>void pr(A a){cout<<a;ln;}
template<Z A,Z B>void pr(A a,B b){cout<<a<<' ';pr(b);}
template<Z A,Z B,Z C>void pr(A a,B b,C c){cout<<a<<' ';pr(b,c);}
template<Z A,Z B,Z C,Z D>void pr(A a,B b,C c,D d){cout<<a<<' ';pr(b,c,d);}
template<Z A>void PR(A a,ll n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
ll check(ll n,ll m,ll x,ll y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<61,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
const double INF = 1e12;
const double EPS = 1e-10;
typedef complex<double> P;
typedef pair<P,P> L;
double cross(const P& a, const P& b) {return imag(conj(a)*b);}
double dot(const P& a, const P& b) {return real(conj(a)*b);}
P projection(const L &l, const P &p){double t=dot(p-l.F,l.F-l.S)/norm(l.F-l.S);return l.F+t*(l.F-l.S);}
bool intersectSP(const L &s, const P &p){return abs(s.F-p)+abs(s.S-p)-abs(s.S-s.F)<EPS;}
double distanceSP(const L &s, const P &p) {
  const P r=projection(s,p);
  if(intersectSP(s,r)) return abs(r-p);
  return min(abs(s.F-p),abs(s.S-p));
}
struct C {
  P p; double r;
};

void Main() {
  int n;
  R n;
  C p[n][2];
  rep(i,n) {
    double r,x1,y1,x2,y2;
    cin >> r >> x1 >> y1 >> x2 >> y2;
    p[i][0]=(C){P(x1,y1),r};
    p[i][1]=(C){P(x2,y2),r};
  }
  int dp[1<<n],ans=0;
  memset(dp,-1,sizeof(dp));
  dp[0]=0;
  rep(t,1<<n) {
    if(dp[t]==-1) continue;
    rep(i,n) {
      if(t&(1<<i)) continue;
      bool f=1;
      L l=L(p[i][0].p,p[i][1].p);
      rep(j,n) {
        if(i==j) continue;
        P q;
        if(t&(1<<j)) q=p[j][1].p;
        else q=p[j][0].p;
        if(distanceSP(l,q)<p[i][0].r+p[j][0].r) f=0;
      }
      if(f) dp[t|(1<<i)]=max(dp[t|(1<<i)],dp[t]+1);
      ans=max(ans,dp[t|(1<<i)]);
    }
  }
  pr(ans);
}

int main(){ios::sync_with_stdio(0);cin.tie(0);Main();return 0;}
accuracy: 1
time_ms: 350
memory_kb: 3548
final_rank: 17

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

//geometry library by maine

//basic
using Real = double;
using Point = complex<Real>;
#define x real()
#define y imag()
const Real EPS = 1e-8, PI = acos(-1), INF = 1e10;

istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, Point p) {
    return os << fixed << setprecision(10) << p.x << " " << p.y;
}

Point operator*(const Point& p, const Real& d) { return Point(p.x * d, p.y * d); }

bool eq(const Real& r, const Real& s) { return abs(r - s) < EPS; }
bool eq(const Point& p, const Point& q) { return abs(p - q) < EPS; }

namespace std {
bool operator<(const Point& a, const Point& b) {
    return !eq(a.x, b.x) ? a.x < b.x : a.y < b.y;
}
}  // namespace std

Real get_angle(const Point& a, const Point& b, const Point& c) {
    return arg((c - a) / (b - a));
}

inline int inc(int i, int N) {
    return (i == N - 1 ? 0 : i + 1);
}
inline int dec(int i, int N) {
    return (i == 0 ? N - 1 : i - 1);
}

//unit vector
Point e(const Point& p) { return p / abs(p); }

//angle transformation
Real radian_to_degree(Real r) { return r * 180.0 / PI; }
Real degree_to_radian(Real d) { return d * PI / 180.0; }

//basic functions
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; }
Point rotate(const Real& theta, const Point& p) {
    return {cos(theta) * p.x - sin(theta) * p.y, sin(theta) * p.x + cos(theta) * p.y};
}
Point rotate90(const Point& p) {
    return {-p.y, p.x};
}

//structs : Line, Segment, Circle
struct Line {
    Point a, b;
    Line() = default;
    Line(Point a, Point b) : a(a), b(b) {}
    Point d() const { return e(b - a); }  //direction vector
    Point n() const {
        Point dd = d();
        return {dd.y, -dd.x};
    }  //normal vector
};
struct Segment : Line {
    Segment() = default;
    Segment(Point a, Point b) : Line(a, b) {}
};
struct Circle {
    Point p;
    Real r;
    Circle() = default;
    Circle(Point p, Real r) : p(p), r(r){};
};
using Points = vector<Point>;
using Polygon = vector<Point>;
using Polygons = vector<Polygon>;
using Lines = vector<Line>;
using Segments = vector<Segment>;
using Circles = vector<Circle>;

//happy functions
//https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
int ccw(const Point& a, const Point& bb, const Point& cc) {
    Point b = bb - a, c = cc - a;
    if (cross(b, c) > EPS)
        return 1;  //COUNTER_CLOCKWISE
    if (cross(b, c) < -EPS)
        return -1;  //CLOCKWISE
    if (dot(b, c) < 0)
        return 2;  //ONLINE_BACK  c-a-b
    if (norm(b) < norm(c))
        return -2;  //ONLINE_FRONT a-b-c
    return 0;       //ON_SEGMENT   a-c-b
}

bool parallel(const Line& l, const Line& m) { return eq(cross(l.d(), m.d()), 0.0); }
bool orthogonal(const Line& l, const Line& m) { return eq(dot(l.d(), m.d()), 0.0); }
Point projection(const Line& l, const Point& p) { return p + l.n() * dot(l.a - p, l.n()); }
Point reflection(const Line& l, const Point& p) { return p + l.n() * 2.0 * dot(l.a - p, l.n()); }

//intersect
bool intersect(const Line& l, const Point& p) { return abs(ccw(l.a, l.b, p)) != 1; }
bool intersect(const Line& l, const Line& m) { return !parallel(l, m) || (parallel(l, m) && intersect(l, m.a)); }
bool intersect(const Segment& s, const Point& p) { return ccw(s.a, s.b, p) == 0; }
bool intersect(const Line& l, const Segment& s) { return cross(l.d(), s.a - l.a) * cross(l.d(), s.b - l.a) < EPS; }
bool intersect(const Segment& s, const Segment& t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

//distance
Real distance(const Point& p, const Point& q) { return abs(p - q); }
Real distance(const Line& l, const Point& p) { return distance(p, projection(l, p)); }
Real distance(const Line& l, const Line& m) { return intersect(l, m) ? 0 : distance(l, m.a); }
Real distance(const Segment& s, const Point& p) {
    Point q = projection(s, p);
    return intersect(s, q) ? distance(p, q) : min(distance(s.a, p), distance(s.b, p));
}
Real distance(const Segment& s, const Segment& t) { return intersect(s, t) ? 0 : min({distance(s, t.a), distance(s, t.b), distance(t, s.a), distance(t, s.b)}); }
Real distance(const Line& l, const Segment& s) { return intersect(l, s) ? 0 : min(distance(l, s.a), distance(l, s.b)); }

//intersect circle
bool intersect(const Circle& c, const Point& p) { return eq(distance(c.p, p), c.r); }
bool intersect(const Circle& c, const Line& l) { return distance(l, c.p) <= c.r + EPS; }
int intersect(const Circle& c, const Segment& s) {
    if (!intersect(c, Line(s)))
        return 0;
    Real da = distance(c.p, s.a), db = distance(c.p, s.b);
    if (da < c.r + EPS && db < c.r + EPS)
        return 0;
    if (da > db)
        swap(da, db);
    if (da < c.r - EPS && db > c.r + EPS)
        return 1;
    if (intersect(s, projection(s, c.p)))
        return 2;
    return 0;
}
int intersect(Circle c1, Circle c2) {
    if (c1.r < c2.r)
        swap(c1, c2);
    Real d = distance(c1.p, c2.p);
    if (c1.r + c2.r < d)
        return 4;
    if (eq(c1.r + c2.r, d))
        return 3;
    if (c1.r - c2.r < d)
        return 2;
    if (eq(c1.r - c2.r, d))
        return 1;
    return 0;
}

//crosspoint
Point crosspoint(const Line& l, const Line& m) {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if (eq(abs(A), 0.0) && eq(abs(B), 0.0))
        return m.a;
    return m.a + (m.b - m.a) * B / A;
}
Point crosspoint(const Segment& s, const Segment& t) { return crosspoint(Line(s), Line(t)); }
pair<Point, Point> crosspoint(const Circle& c, const Line& l) {
    Point p = projection(l, c.p);
    if (eq(distance(l, c.p), c.r))
        return {p, p};
    Real len = sqrt(c.r * c.r - norm(p - c.p));
    return {p - len * l.d(), p + len * l.d()};
}
pair<Point, Point> crosspoint(const Circle& c, const Segment& s) {
    Line l(s);
    if (intersect(c, s) == 2)
        return crosspoint(c, l);
    auto ret = crosspoint(c, l);
    if (dot(s.a - ret.first, s.b - ret.first) < 0)
        ret.second = ret.first;
    else
        ret.first = ret.second;
    return ret;
}
pair<Point, Point> crosspoint(const Circle& c1, const Circle& c2) {
    Real d = distance(c1.p, c2.p);
    Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    Real t = atan2(c2.p.y - c1.p.y, c2.p.x - c1.p.x);
    Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
    Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
    return {p1, p2};
}

//tangent
pair<Point, Point> tangent(const Circle& c, const Point& p) {
    return crosspoint(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
}
Lines tangent(Circle c1, Circle c2) {
    Lines ret;
    if (c1.r < c2.r)
        swap(c1, c2);
    if (eq(c1.p, c2.p))
        return ret;
    Real g = norm(c1.p - c2.p);
    Point u = (c2.p - c1.p) / sqrt(g);
    Point v = rotate(PI / 2, u);
    for (int s : {-1, 1}) {
        Real h = (c1.r + s * c2.r) / sqrt(g);
        if (eq(1 - h * h, 0)) {
            ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
        } else if (1 - h * h > 0) {
            Point uu = u * h, vv = v * sqrt(1 - 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;
}

//convex
//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_B
bool is_convex(const Polygon& P) {
    int N = (int)P.size();
    for (int i = 0; i < N; i++) {
        if (ccw(P[i], P[(i + 1) % N], P[(i + 2) % N]) == -1)
            return false;
    }
    return true;
}
//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_A
Polygon convex_hull(Points P) {
    int N = (int)P.size(), k = 0;
    if (N <= 2)
        return P;
    sort(begin(P), end(P));
    Points ret(2 * N);
    for (int i = 0; i < N; ret[k++] = P[i++]) {
        while (k >= 2 && cross(ret[k - 1] - ret[k - 2], P[i] - ret[k - 1]) < EPS)
            --k;
    }
    for (int i = N - 2, t = k + 1; i >= 0; ret[k++] = P[i--]) {
        while (k >= t && cross(ret[k - 1] - ret[k - 2], P[i] - ret[k - 1]) < EPS)
            --k;
    }
    ret.resize(k - 1);
    return ret;
}
//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_B
Real convex_diameter(const Polygon& P) {
    int N = (int)P.size();
    int is = 0, js = 0;
    for (int i = 1; i < N; i++) {
        if (P[i].y < P[is].y)
            is = i;
        if (P[i].y > P[js].y)
            js = i;
    }
    Real maxdist = norm(P[is] - P[js]);
    int maxi, maxj, i, j;
    maxi = i = is;
    maxj = j = js;
    do {
        if (cross(P[inc(i, N)] - P[i], P[inc(j, N)] - P[j]) >= 0)
            j = inc(j, N);
        else
            i = inc(i, N);
        if (norm(P[i] - P[j]) > maxdist) {
            maxdist = norm(P[i] - P[j]);
            maxi = i;
            maxj = j;
        }
    } while (i != is || j != js);
    maxi = maxi;
    maxj = maxj;
    return sqrt(maxdist);
}
//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_C
Polygon convex_cut(const Polygon& P, const Line& l) {
    Polygon ret;
    int N = (int)P.size();
    for (int i = 0; i < N; i++) {
        Point now = P[i], nxt = P[(inc(i, N))];
        if (ccw(l.a, l.b, now) != -1)
            ret.emplace_back(now);
        if (ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) == -1)
            ret.emplace_back(crosspoint(Line(now, nxt), l));
    }
    return ret;
}

//other
enum
{
    OUT,
    ON,
    IN
};

//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_C
int contains(const Polygon& Q, const Point& p) {
    bool in = false;
    int N = (int)Q.size();
    for (int i = 0; i < N; i++) {
        Point a = Q[i] - p, b = Q[(i + 1) % N] - p;
        if (a.y > b.y)
            swap(a, b);
        if (a.y <= 0 && 0 < b.y && cross(a, b) < 0)
            in = !in;
        if (cross(a, b) == 0 && dot(a, b) <= 0)
            return ON;
    }
    return in ? IN : OUT;
}

//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_A
Real area(const Polygon& P) {
    Real A = 0;
    for (int i = 0; i < (int)P.size(); i++) {
        A += cross(P[i], P[(i + 1) % P.size()]);
    }
    return A * 0.5;
}

//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_H
Real cross_area(const Circle& c, const Point& a, const Point& b) {
    Point va = c.p - a, vb = c.p - b;
    Real f = cross(va, vb), ret = 0.0;
    if (eq(f, 0.0))
        return ret;
    if (max(abs(va), abs(vb)) < c.r + EPS)
        return f;
    if (distance(Segment(a, b), c.p) > c.r - EPS)
        return c.r * c.r * arg(vb * conj(va));
    auto u = crosspoint(c, Segment(a, b));
    vector<Point> V{a, u.first, u.second, b};
    for (int i = 0; i < (int)V.size() - 1; i++) {
        ret += cross_area(c, V[i], V[i + 1]);
    }
    return ret;
}
Real area(const Polygon& p, const Circle& c) {
    int N = (int)p.size();
    if (N < 3)
        return 0.0;
    Real ret = 0;
    for (int i = 0; i < N; i++) {
        ret += cross_area(c, p[i], p[inc(i, N)]);
    }
    return ret / 2.0;
}

//https://onlinejudge.u-aizu.ac.jp/problems/CGL_5_A
Real closest_pair(Points& P, int left, int right) {
    if (right - left <= 1)
        return 1e18;
    int mid = (left + right) / 2;
    Real xx = P[mid].x;
    Real dist = min(closest_pair(P, left, mid), closest_pair(P, mid, right));
    inplace_merge(P.begin() + left, P.begin() + mid, P.begin() + right, [&](const Point& a, const Point& b) { return a.y < b.y; });
    Points memo;
    memo.reserve(right - left);
    for (int i = left; i < right; i++) {
        if (abs(P[i].x - xx) >= dist)
            continue;
        for (int j = (int)memo.size() - 1; j >= 0; j--) {
            if (P[i].y - memo[j].y >= dist)
                break;
            dist = min(dist, distance(P[i], memo[j]));
        }
        memo.emplace_back(P[i]);
    }
    return dist;
}
Real closest_pair(Points P) {
    sort(begin(P), end(P));
    return closest_pair(P, 0, (int)P.size());
}

//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_B
Circle incircle(Polygon P) {
    assert((int)P.size() == 3);
    Real l0 = distance(P[1], P[2]), l1 = distance(P[0], P[2]), l2 = distance(P[0], P[1]);
    Circle c;
    c.p = crosspoint(Line(P[0], (P[1] * l1 + P[2] * l2) / (l1 + l2)), Line(P[1], (P[0] * l0 + P[2] * l2) / (l0 + l2)));
    c.r = distance(Line(P[0], P[1]), c.p);
    return c;
}

//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_C
Circle circumcircle(Polygon P) {
    assert((int)P.size() == 3);
    Circle c;
    c.p = crosspoint(Line((P[0] + P[1]) / 2.0, (P[0] + P[1]) / 2.0 + rotate90(P[0] - P[1])),
        Line((P[0] + P[2]) / 2.0, (P[0] + P[2]) / 2.0 + rotate90(P[0] - P[2])));
    c.r = distance(c.p, P[0]);
    return c;
}

int main() {
    int N;
    cin >> N;
    Circles C(N);
    Points T(N);
    for (int i = 0; i < N; i++) {
        cin >> C[i].r >> C[i].p >> T[i];
    }
    vector maine(1 << N, false);
    maine[0] = true;
    for (int bit = 0; bit < (1 << N); bit++) {
        if (!maine[bit])
            continue;
        for (int i = 0; i < N; i++) {
            if (~bit & (1 << i)) {
                bool flag = false;
                for (int j = 0; j < N; j++) {
                    if (i == j)
                        continue;
                    flag |= intersect(Circle(((bit & (1 << j)) ? T[j] : C[j].p), C[i].r + C[j].r), Segment(C[i].p, T[i]));
                }
                if (!flag)
                    maine[bit ^ (1 << i)] = true;
            }
        }
    }
    int ans = 0;
    for (int i = 0; i < (1 << N); i++) {
        if (maine[i])
            ans = max(ans, __builtin_popcount(i));
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 450
memory_kb: 3532
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;
    template<class t>
    void output(t a){
        if(was_output)cout << " ";
        cout << a;
        was_output = true;
    }
    void outendl(){
        was_output = false;
        cout << endl;
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    void out(t x){
        cout << x;
    }


    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }
}

using namespace templates;

template<class t>
class Vector2{
	public:
		t x;
		t y;
		Vector2():x(0), y(0){}
		Vector2(t a, t b):x(a), y(b){}
		Vector2(const Vector2 &o):x(o.x), y(o.y){}

		Vector2& operator+=(Vector2 o){x+=o.x;y+=o.y;return *this;}
		Vector2& operator-=(Vector2 o){x-=o.x;y-=o.y;return *this; }
		Vector2& operator*=(t o){x*=o;y*=o;return *this;}
		Vector2& operator/=(t o){x/=o;y/=o;return *this;}

		Vector2 operator+(Vector2 o){return Vector2(*this)+=o;}
		Vector2 operator-(Vector2 o){return Vector2(*this)-=o;}
		Vector2 operator*(t o){return Vector2(*this)*=o;}
		Vector2 operator/(t o){return Vector2(*this)/=o;}

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

		Vector2 normal(){
			return (*this) / abs();
		}
};

template<class t>
double abs(Vector2<t> x){
	return x.abs();
}

template<class t>
double dot(Vector2<t> x, Vector2<t> y){
	return x.x * y.x + x.y * y.y;
}

template<class t>
double cross(Vector2<t> x, Vector2<t> y){
	return x.x * y.y - x.y * y.x;
}

using vector2 = Vector2<double>;

int func(){
    int n = in();
    vector<vector2> starts(n);
    vector<vector2> ends(n);
    vector<double> rs(n);
    rep(i,n){
        rs[i] = in<double>();
        starts[i].x = in<double>();
        starts[i].y = in<double>();
        ends[i].x = in<double>();
        ends[i].y = in<double>();
    }
    method(dist,double,vector2 from,vector2 to,vector2 p){
        to -= from;
        p -= from;
        vector2 v = to;
        vector2 n = v.normal();
        double k = v.abs();
        double dis = dot(n,p);
        if(dis<0)dis=0;
        if(dis>k)dis=k;
        p -= n * dis;
        return abs(p);
    };
    vector<int> dp(bit(n),-1);
    method(rec,int,int moved){
        int &it = dp[moved];
        if(it>=0)return it;
        it = 0;
        rep(i,n){
            if(moved & bit(i))continue;
            bool flag = true;
            rep(j,n){
                if(i==j)continue;
                double dis = dist(starts[i],ends[i],(moved&bit(j))?ends[j]:starts[j]);
                if(dis < rs[i] + rs[j]){
                    flag = false;
                }
            }
            if(flag){
                chmax(it,rec(moved|bit(i))+1);
            }
        }
        return it;
    };
    return rec(0);
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << func() << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3592
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define inf 1000000000
#define INF 1000000000000000
#define ll long long
#define ull unsigned long long
#define M (int)(1e9+7)
#define P pair<int,int>
#define PLL pair<ll,ll>
#define FOR(i,m,n) for(int i=(int)m;i<(int)n;i++)
#define RFOR(i,m,n) for(int i=(int)m;i>=(int)n;i--)
#define rep(i,n) FOR(i,0,n)
#define rrep(i,n) RFOR(i,n,0)
#define all(a) a.begin(),a.end()
#define IN(a,n) rep(i,n){ cin>>a[i]; }
const int vx[4] = {0,1,0,-1};
const int vy[4] = {1,0,-1,0};
#define PI 3.14159265
#define F first
#define S second
#define PB push_back
#define EB emplace_back
#define int ll
#define vi vector<int>
#define double long double

struct Point
{
  double x;
  double y;
};

struct LineSegment
{
  Point start;
  Point end;
};

/**
 *    @brief 線分と点の距離を計算する。
 *       @param line 線分
 *          @param point 点
 *             @return ユークリッド距離
 *              */
double calc_dist(const LineSegment &line, const Point &point)
{
  double x0 = point.x, y0 = point.y;
  double x1 = line.start.x, y1 = line.start.y;
  double x2 = line.end.x, y2 = line.end.y;

  double a = x2 - x1;
  double b = y2 - y1;
  double a2 = a * a;
  double b2 = b * b;
  double r2 = a2 + b2;
  double tt = -(a * (x1 - x0) + b * (y1 - y0));

  if (tt < 0)
    return sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
  else if (tt > r2)
    return sqrt((x2 - x0) * (x2 - x0) + (y2 - y0) * (y2 - y0));

  double f1 = a * (y1 - y0) - b * (x1 - x0);
  return sqrt((f1 * f1) / r2);
}


bool is_crash(double r,double sx,double sy,double tx,double ty,double pr,double px,double py) {

  Point s = {sx,sy};
  Point t = {tx,ty};
  Point p = {px,py};

  double dist = calc_dist(LineSegment {s,t},p);


  //if(r==pr) cout<<kyori<<' '<<r+pr<<endl;
  //
  return r+pr - dist > 0;

}

int bit_count(int n) {
  if(n==0) return 0;
  return bit_count(n/2) + n%2;
}

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  cin>>n;
  vector<double> r(n),sx(n),sy(n),tx(n),ty(n);
  rep(i,n){
    cin>>r[i]>>sx[i]>>sy[i]>>tx[i]>>ty[i];
  }

  vector<int> bit(1<<n,0);

  bit[0]=1;

  rep(i,1<<n){
    if(!bit[i]) continue;
    //cout<<i<<endl;
    rep(j,n){
      if(i&(1<<j)) continue;
      //cout<<i<<' '<<j<<endl;
      bool flag = true;
      rep(k,n) {
        if(j==k) continue;
        if(i&(1<<k)){
          if(is_crash(r[j],sx[j],sy[j],tx[j],ty[j],r[k],tx[k],ty[k])){
            flag = false;
          }
        }
        else {
          if(is_crash(r[j],sx[j],sy[j],tx[j],ty[j],r[k],sx[k],sy[k])) {
            flag = false;
          }
        }
      }
      if(flag) {
        bit[i+(1<<j)] = 1;
      }
    }
  }

  int ans=0;

  rep(i,1<<n) {
    if(bit[i]){
      //cout<<i<<endl;
      ans=max(ans,bit_count(i));
    }
  }

  cout<<ans<<endl;


}
accuracy: 1
time_ms: 170
memory_kb: 3664
final_rank: 15

code_snippet: // #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)n; ++i)
#define rrep(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define ALL(v) v.begin(), v.end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
using ll = long long;
using ld = long double;
const array<int, 8> di = {0, 1, 0, -1, 1, 1, -1, -1}, dj = {1, 0, -1, 0, 1, -1, -1, 1};
const array<string, 2> YESNO = {"NO", "YES"};
const array<string, 2> YesNo = {"No", "Yes"};
const array<string, 2> yesno = {"no", "yes"};
void YES(bool b = true) { cout << YESNO[b] << '\n'; }
void Yes(bool b = true) { cout << YesNo[b] << '\n'; }
void yes(bool b = true) { cout << yesno[b] << '\n'; }
template<typename T, typename U>
inline bool chmax(T& a, const U& b) {
    if (a < b){
        a = b;
        return true;
    }
    return false;
}
template<typename T, typename U>
inline bool chmin(T& a, const U& b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<typename T>
T MAX(const vector<T>& v) { return *max_element(v.begin(), v.end()); }
template<typename T>
T MIN(const vector<T>& v) { return *min_element(v.begin(), v.end()); }
template<typename T>
T SUM(const vector<T>& v) { return accumulate(v.begin(), v.end(), T()); }
template<typename T>
void UNIQUE(vector<T>& v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
}
template<typename T>
T POW(T a, int n) {
    T res = 1;
    for (; n > 0; n >>= 1, a *= a) if (n & 1) res *= a;
    return res;
}
template<typename T>
int lb(const vector<T>& v, T x) {
    return distance(v.begin(), lower_bound(v.begin(), v.end(), x));
}
template<typename T>
int ub(const vector<T>& v, T x) {
    return distance(v.begin(), upper_bound(v.begin(), v.end(), x));
}
/**
 * @brief 多次元 vector の作成
 * @author えびちゃん
 */
namespace detail {
    template<typename T, int N>
    auto make_vec(vector<int>& sizes, T const& x) {
        if constexpr (N == 1) {
            return vector(sizes[0], x);
        } else {
            int size = sizes[N-1];
            sizes.pop_back();
            return vector(size, make_vec<T, N-1>(sizes, x));
        }
    }
}
template<typename T, int N>
auto make_vec(int const(&sizes)[N], T const& x = T()) {
    vector<int> s(N);
    for (int i = 0; i < N; ++i) s[i] = sizes[N-i-1];
    return detail::make_vec<T, N>(s, x);
}
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        if (it == v.begin()) os << *it;
        else os << ' ' << *it;
    }
    return os;
}
template<typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << p.first << ' ' << p.second;
    return os;
}
__attribute__((constructor))
void setup() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
}
// #include <atcoder/all>
// using namespace atcoder;
// using mint = modint1000000007;
// using mint = modint998244353;

const double eps = 1e-9;
using point = complex<double>;

struct line {
    point a, b;
    line() {}
    line(point a, point b) : a(a), b(b) {}
};
struct segment {
    point a, b;
    segment() {}
    segment(point a, point b) : a(a), b(b) {}
};

double dot(const point& a, const point& b) { return a.real() * b.real() + a.imag() * b.imag(); }
double cross(const point& a, const point& b) { return a.real() * b.imag() - a.imag() * b.real(); }

int ccw(const point& a, point b, point c) {
    b -= a; c -= a;
    double cp = cross(b, c);
    if (cp > eps) return 1;
    if (cp < -eps) return -1;
    if (dot(b, c) < -eps) return 2;
    if (norm(b) + eps < norm(c)) return -2;
    return 0;
}

point projection(const line& l, const point& p) { 
    return l.a + ((l.b - l.a) / abs(l.b - l.a)) * dot(((l.b - l.a) / abs(l.b - l.a)), p - l.a);
};

point reflection(const line& l, const point& p) {
    return p + 2.0 * (projection(l, p) - p);
}

bool is_parallel(const line& l, const line& m) { return abs(cross(l.b - l.a, m.b - m.a)) < eps; }
bool is_orthogonal(const line& l, const line& m) { return abs(dot(l.b - l.a, m.b - m.a)) < eps; }

bool is_intersect(const segment& s, const segment& t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

point intersection(const line& s, const line& t) {
    double d1 = cross(s.b - s.a, t.b - t.a);
    double d2 = cross(s.b - s.a, s.b - t.a);
    if (abs(d1) < eps && abs(d2) < eps) return t.a;
    return t.a + (t.b - t.a) * (d2 / d1);
}

double dist(const segment& s, const point& p) {
    if (dot(s.b - s.a, p - s.a) < eps) return abs(p - s.a);
    if (dot(s.a - s.b, p - s.b) < eps) return abs(p - s.b);
    return abs(cross(s.b - s.a, p - s.a)) / abs(s.b - s.a);
}

double dist(const segment& s, const segment& t) {
    if (is_intersect(s, t)) return 0;
    return min({dist(s, t.a), dist(s, t.b), dist(t, s.a), dist(t, s.b)});
}

int main() {
    int n;
    cin >> n;
    vector<int> r(n), sx(n), sy(n), tx(n), ty(n);
    rep(i, n) cin >> r[i] >> sx[i] >> sy[i] >> tx[i] >> ty[i];

    vector<bool> dp(1 << n);
    dp[0] = true;
    rep(bit, 1 << n) {
        if (!dp[bit]) continue;
        rep(i, n) {
            if (bit >> i & 1) continue;
            bool ok = true;
            point a(sx[i], sy[i]), b(tx[i], ty[i]);
            segment s(a, b);
            rep(j, n) {
                if (i == j) continue;
                point p;
                if (bit >> j & 1) {
                    p = point(tx[j], ty[j]);
                } else {
                    p = point(sx[j], sy[j]);
                }
                if (dist(s, p) + eps < r[i] + r[j]) {
                    ok = false;
                    break;
                }
            }
            if (ok) dp[bit | 1 << i] = true;
        }
    }
    int ans = 0;
    rep(bit, 1 << n) if (dp[bit]) chmax(ans, __builtin_popcount(bit));
    cout << ans << '\n';
}
accuracy: 1
time_ms: 70
memory_kb: 3476
final_rank: 6

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

const double EPS=1e-8,PI=acos(-1);
inline bool EQ(double a,double b){return fabs(b-a)<EPS;}

struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
    Point operator+(Point p) const {return Point{x+p.x,y+p.y};}
    Point operator-(Point p) const {return Point{x-p.x,y-p.y};}
    Point operator*(double t) const {return Point{x*t,y*t};}
    Point operator*(Point p) const {return Point{x*p.x-y*p.y,x*p.y+y*p.x};}
    Point operator/(double t) const {return Point{x/t,y/t};}
    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;
    }
    friend istream &operator>>(istream &is,Point &p){
        is >> p.x >> p.y;
        return is;
    }
    friend ostream &operator<<(ostream &os,Point p){
        os << fixed << setprecision(10) << p.x << ' ' << p.y;
        return os;
    }
};

struct Line{
    Point a,b;
    Line(){}
    Line(Point a,Point b):a(a),b(b){}
    friend istream &operator>>(istream &is,Line &l){
        is >> l.a >> l.b;
        return is;
    }
    friend ostream &operator<<(ostream &os,Line l){
        os << l.a << " to " << l.b;
        return os;
    }
};

struct Segment:Line{
    Segment(){}
    Segment(Point a,Point b):Line(a,b){}
};

double dot(const Point &a,const Point &b){
    return a.x*b.x+a.y*b.y;
}
double cross(const Point &a,const Point &b){
    return a.x*b.y-a.y*b.x;
}
double norm(const Point &a){
    return a.x*a.x+a.y*a.y;
}
double abs(const Point &a){
    return sqrt(norm(a));
}

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

static const int COUNTER_CLOCKWISE=1;
static const int CLOCKWISE=-1;
static const int ONLINE_BACK=2;
static const int ONLINE_FRONT=-2;
static const int ON_SEGMENT=0;

int ccw(const Point &a,Point b,Point c){
    b=b-a,c=c-a;
    if (cross(b,c)>EPS) return COUNTER_CLOCKWISE;
    if (cross(b,c)<-EPS) return CLOCKWISE;
    if (dot(b,c)<-EPS) return ONLINE_BACK;
    if (norm(b)<norm(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}

bool intersect(const Segment &s,const Point &p){
    return ccw(s.a,s.b,p)==0;
}
double distance(const Segment &s,const Point &p){
    Point h=proj(s,p);
    return intersect(s,h)?abs(h-p):min(abs(s.a-p),abs(s.b-p));
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N; cin >> N;
    vector<int> r(N);
    vector<Point> s,t;
    for (int i=0;i<N;++i){
        int sx,sy,tx,ty; cin >> r[i] >> sx >> sy >> tx >> ty;
        s.emplace_back(sx,sy);
        t.emplace_back(tx,ty);
    }

    vector<bool> dp(1<<N,false);
    dp[0]=true;
    int ans=0;
    for (int mask=0;mask<(1<<N);++mask){
        if (!dp[mask]) continue;
        for (int i=0;i<N;++i){
            if (mask&1<<i) continue;
            Segment S(s[i],t[i]);
            bool ok=true;
            for (int j=0;j<N;++j){
                if (i==j) continue;
                Point p=(mask&1<<j?t[j]:s[j]);
                if (distance(S,p)<r[i]+r[j]) ok=false;
            }
            if (ok) dp[mask|1<<i]=true;
        }
        ans=max(ans,__builtin_popcount(mask));
    }

    cout << ans << '\n';
}
accuracy: 1
time_ms: 100
memory_kb: 3172
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
const long long MOD=1000000007;
// const long long MOD=998244353;
#define LOCAL
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(),(x).end()
const int INF=1e9;
const long long IINF=1e18;
const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
const char dir[4]={'D','R','U','L'};

template<typename T>
istream &operator>>(istream &is,vector<T> &v){
    for (T &x:v) is >> x;
    return is;
}
template<typename T>
ostream &operator<<(ostream &os,const vector<T> &v){
    for (int i=0;i<v.size();++i){
        os << v[i] << (i+1==v.size()?"": " ");
    }
    return os;
}
template<typename T,typename U>
ostream &operator<<(ostream &os,const pair<T,U> &p){
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template<typename T,typename U,typename V>
ostream&operator<<(ostream &os,const tuple<T,U,V> &t){
    os << '(' << get<0>(t) << ',' << get<1>(t) << ',' << get<2>(t) << ')';
    return os;
}
template<typename T,typename U,typename V,typename W>
ostream&operator<<(ostream &os,const tuple<T,U,V,W> &t){
    os << '(' << get<0>(t) << ',' << get<1>(t) << ',' << get<2>(t) << ',' << get<3>(t) << ')';
    return os;
}
template<typename T,typename U>
ostream &operator<<(ostream &os,const map<T,U> &m){
    os << '{';
    for (auto itr=m.begin();itr!=m.end();){
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr!=m.end()) os << ',';
    }
    os << '}';
    return os;
}
template<typename T,typename U>
ostream &operator<<(ostream &os,const unordered_map<T,U> &m){
    os << '{';
    for (auto itr=m.begin();itr!=m.end();){
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr!=m.end()) os << ',';
    }
    os << '}';
    return os;
}
template<typename T>
ostream &operator<<(ostream &os,const set<T> &s){
    os << '{';
    for (auto itr=s.begin();itr!=s.end();){
        os << *itr;
        if (++itr!=s.end()) os << ',';
    }
    os << '}';
    return os;
}
template<typename T>
ostream &operator<<(ostream &os,const multiset<T> &s){
    os << '{';
    for (auto itr=s.begin();itr!=s.end();){
        os << *itr;
        if (++itr!=s.end()) os << ',';
    }
    os << '}';
    return os;
}
template<typename T>
ostream &operator<<(ostream &os,const unordered_set<T> &s){
    os << '{';
    for (auto itr=s.begin();itr!=s.end();){
        os << *itr;
        if (++itr!=s.end()) os << ',';
    }
    os << '}';
    return os;
}
template<typename T>
ostream &operator<<(ostream &os,const deque<T> &v){
    for (int i=0;i<v.size();++i){
        os << v[i] << (i+1==v.size()?"": " ");
    }
    return os;
}

void debug_out(){cerr << '\n';}
template<class Head,class... Tail>
void debug_out(Head&& head,Tail&&... tail){
    cerr << head;
    if (sizeof...(Tail)>0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...) cerr << " ";\
cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n';\
cerr << " ";\
debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

template<typename T> T gcd(T x,T y){return y!=0?gcd(y,x%y):x;}
template<typename T> T lcm(T x,T y){return x/gcd(x,y)*y;}

template<class T1,class T2> inline bool chmin(T1 &a,T2 b){
    if (a>b){a=b; return true;} return false;
}
template<class T1,class T2> inline bool chmax(T1 &a,T2 b){
    if (a<b){a=b; return true;} return false;
}
#pragma endregion

#pragma region Geometry
const double EPS=1e-8,PI=acos(-1);
inline bool EQ(double a,double b){return fabs(b-a)<EPS;}

struct Point{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
    Point operator+(Point p) const {return Point{x+p.x,y+p.y};}
    Point operator-(Point p) const {return Point{x-p.x,y-p.y};}
    Point operator*(double t) const {return Point{x*t,y*t};}
    Point operator*(Point p) const {return Point{x*p.x-y*p.y,x*p.y+y*p.x};}
    Point operator/(double t) const {return Point{x/t,y/t};}
    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;
    }
    friend istream &operator>>(istream &is,Point &p){
        is >> p.x >> p.y;
        return is;
    }
    friend ostream &operator<<(ostream &os,Point p){
        os << fixed << setprecision(10) << p.x << ' ' << p.y;
        return os;
    }
};

struct Line{
    Point a,b;
    Line(){}
    Line(Point a,Point b):a(a),b(b){}
    friend istream &operator>>(istream &is,Line &l){
        is >> l.a >> l.b;
        return is;
    }
    friend ostream &operator<<(ostream &os,Line l){
        os << l.a << " to " << l.b;
        return os;
    }
};

struct Segment:Line{
    Segment(){}
    Segment(Point a,Point b):Line(a,b){}
};

struct Circle{
    Point c;
    double r;
    Circle(){}
    Circle(Point c,double r):c(c),r(r){}
    friend istream &operator>> (istream &is,Circle &c){
        is >> c.c >> c.r;
        return is;
    }
    friend ostream &operator<<(ostream &os,Circle &c){
        os << c.c << ' ' << c.r;
        return os;
    }
};

typedef vector<Point> Polygon;
istream &operator>>(istream &is,Polygon &p){
    for (int i=0;i<p.size();++i) is >> p[i];
    return is;
}

double dot(const Point &a,const Point &b){
    return a.x*b.x+a.y*b.y;
}
double cross(const Point &a,const Point &b){
    return a.x*b.y-a.y*b.x;
}
double norm(const Point &a){
    return a.x*a.x+a.y*a.y;
}
double abs(const Point &a){
    return sqrt(norm(a));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_A
Point proj(const Line &l,const Point &p){
    double t=dot(p-l.a,l.b-l.a)/norm(l.b-l.a);
    return l.a+(l.b-l.a)*t;
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_B
Point refl(const Line &l,const Point &p){
    return p+(proj(l,p)-p)*2.0;
}

Point rotate(const Point &p,double theta){
    return Point(cos(theta)*p.x-sin(theta)*p.y,sin(theta)*p.x+cos(theta)*p.y);
}
double arg(const Point &p){
    return atan2(p.y,p.x);
}
double get_angle(const Point &a,const Point &b,const Point &c){
    const Point v=b-a,w=c-b;
    double alpha=arg(v),beta=arg(w);
    if (alpha>beta) swap(alpha,beta);
    double theta=beta-alpha;
    return min(theta,2*PI-theta);
}

static const int COUNTER_CLOCKWISE=1;
static const int CLOCKWISE=-1;
static const int ONLINE_BACK=2;
static const int ONLINE_FRONT=-2;
static const int ON_SEGMENT=0;

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_C
int ccw(const Point &a,Point b,Point c){
    b=b-a,c=c-a;
    if (cross(b,c)>EPS) return COUNTER_CLOCKWISE;
    if (cross(b,c)<-EPS) return CLOCKWISE;
    if (dot(b,c)<-EPS) return ONLINE_BACK;
    if (norm(b)<norm(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_A
bool orthogonal(const Point &a,const Point &b){
    return EQ(dot(a,b),0.0);
}
bool orthogonal(const Point &a,const Point &b,const Point &c,const Point &d){
    return orthogonal(b-a,d-c);
}
bool orthogonal(const Line &l,const Line &m){
    return EQ(dot(l.b-l.a,m.b-m.a),0.0);
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_A
bool parallel(const Point &a,const Point &b){
    return EQ(cross(a,b),0.0);
}
bool parallel(const Point &a,const Point &b,const Point &c,const Point &d){
    return parallel(b-a,d-c);
}
bool parallel(const Line &l,const Line &m){
    return EQ(cross(l.b-l.a,m.b-m.a),0.0);
}

bool intersect(const Line &l,const Point &p){
    return abs(ccw(l.a,l.b,p))!=1;
}
bool intersect(const Line &l,const Line &m){
    return abs(cross(l.b-l.a,m.b-m.a)>EPS||abs(cross(l.b-l.a,m.b-m.a))<EPS);
}
bool intersect(const Line &l,const Segment &s){
    return cross(l.b-l.a,s.a-l.a)*cross(l.b-l.a,s.b-l.a)<EPS;
}
bool intersect(const Segment &s,const Point &p){
    return ccw(s.a,s.b,p)==0;
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_B
bool intersect(const Segment &s,const Segment &t){
    return ccw(s.a,s.b,t.a)*ccw(s.a,s.b,t.b)<=0&&ccw(t.a,t.b,s.a)*ccw(t.a,t.b,s.b)<=0;
}
bool intersect(const Circle &c,const Line &l){
    return (norm(proj(l,c.c)-c.c)-c.r*c.r)<=EPS;
}
int intersect(const Circle &c,const Segment &s){
    if (norm(proj(s,c.c)-c.c)-c.r*c.r>EPS) return 0;
    double d1=abs(c.c-s.a),d2=abs(c.c-s.b);
    if (d1<c.r+EPS&&d2<c.r+EPS) return 0;
    if (d1<c.r-EPS&&d2>c.r+EPS||d1>c.r+EPS&&d2<c.r-EPS) return 1;
    const Point h=proj(s,c.c);
    if (dot(s.a-h,s.b-h)<0) return 2;
    return 0;
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_A
int intersect(Circle c,Circle d){
    if (c.r<d.r) swap(c,d);
    double dist=abs(c.c-d.c);
    if (c.r+d.r<dist) return 4;
    if (EQ(c.r+d.r,dist)) return 3;
    if (c.r-d.r<dist) return 2;
    if (EQ(c.r-d.r,dist)) return 1;
    return 0;
}

double distance(const Point &a,const Point &b){
    return abs(b-a);
}
double distance(const Line &l,const Point &p){
    return abs(p-proj(l,p));
}
double distance(const Line &l,const Line &m){
    return intersect(l,m)?0:distance(l,m.a);
}
double distance(const Segment &s,const Point &p){
    Point h=proj(s,p);
    return intersect(s,h)?abs(h-p):min(abs(s.a-p),abs(s.b-p));
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_D
double distance(const Segment &s,const Segment &t){
    if (intersect(s,t)) return 0;
    return min({distance(s,t.a),distance(s,t.b),distance(t,s.a),distance(t,s.b)});
}
double distance(const Line &l,const Segment &s){
    return intersect(l,s)?0:min(distance(l,s.a),distance(l,s.b));
}

Point crosspoint(const Line &l,const Line &m){
    double d1=cross(l.b-l.a,m.b-m.a),d2=cross(l.b-l.a,l.b-m.a);
    if (EQ(abs(d1),0.0)&&EQ(abs(d2),0.0)) return m.a;
    return m.a+(m.b-m.a)*d2/d1;
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_C
Point crosspoint(const Segment &s,const Segment &t){
    assert(intersect(s,t));
    return crosspoint(Line(s),Line(t));
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_D
vector<Point> crosspoint(const Circle &c,const Line &l){
    Point pr=proj(l,c.c);
    Point e=(l.b-l.a)/abs(l.b-l.a);
    if (EQ(distance(l,c.c),c.r)) return {pr};
    double base=sqrt(c.r*c.r-norm(pr-c.c));
    return {pr-e*base,pr+e*base};
}
vector<Point> crosspoint(const Circle &c,const Segment &s){
    Line l=Line(s);
    assert(intersect(c,l));
    auto res=crosspoint(c,l);
    if (intersect(c,l)==2) return res;
    if (dot(l.a-res[0],l.b-res[0])<0) res.emplace_back(res[0]);
    else res.pop_back();
    return res;
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_E
vector<Point> crosspoint(const Circle &c,const Circle &d){
    double dist=abs(c.c-d.c);
    double a=acos((c.r*c.r+dist*dist-d.r*d.r)/(2*c.r*dist));
    double t=arg(d.c-c.c);
    Point p1=c.c+Point(cos(t+a),sin(t+a))*c.r,p2=c.c+Point(cos(t-a),sin(t-a))*c.r;
    return {p1,p2};
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_C
Circle circumcenter(Point a,Point b,const Point &c){
    a=(a-c)*0.5;
    b=(b-c)*0.5;
    Point center=c+crosspoint(Line(a,a*Point{1,1}),Line{b,b*Point{1,1}});
    return Circle{center,abs(c-center)};
}
vector<Point> center_given_radius(const Point &a,const Point &b,const double &r){
    Point m=(b-a)*0.5;
    double d1=abs(m);
    vector<Point> res;
    if (EQ(d1,0.0)||d1>r) return res;
    double d2=sqrt(r*r-d1*d1);
    Point n=m*Point{0.0,1.0}*d2/d1;
    res.emplace_back(a+m+n);
    if (d2>EPS) res.emplace_back(a+m-n);
    return res;
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_B
bool convex(const Polygon &p){
    int n=p.size();
    for (int i=0;i<n;++i){
        if (ccw(p[(i+n-1)%n],p[i],p[(i+1)%n])==-1){
            return false;
        }
    }
    return true;
}
// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_A
Polygon convex_hull(Polygon p){
    int n=p.size(),k=0;
    if (n<=2) return p;
    sort(p.begin(),p.end());
    Polygon ch(2*n);
    for (int i=0;i<n;ch[k++]=p[i++]){
        while(k>=2&&cross(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&&cross(ch[k-1]-ch[k-2],p[i]-ch[k-1])<0) --k;
    }
    ch.resize(k-1);
    return ch;
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_A
double area(const Polygon &p){
    int n=p.size();
    double res=0;
    for (int i=0;i<n;++i) res+=cross(p[i],p[(i+1)%n]);
    return res*0.5;
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_C
static const int OUT=0,ON=1,IN=2;
int contains(const Polygon &P,const Point &p){
    int n=P.size();
    bool res=false;
    for (int i=0;i<n;++i){
        Point a=P[i]-p,b=P[(i+1)%n]-p;
        if (a.y>b.y) swap(a,b);
        if (a.y<=0&&0<b.y&&cross(a,b)<0) res=!res;
        if (cross(a,b)==0&&dot(a,b)<=0) return ON;
    }
    return res?IN:OUT;
}

#pragma endregion

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N; cin >> N;
    vector<int> r(N);
    vector<Point> s,t;
    for (int i=0;i<N;++i){
        int sx,sy,tx,ty; cin >> r[i] >> sx >> sy >> tx >> ty;
        s.emplace_back(sx,sy);
        t.emplace_back(tx,ty);
    }

    vector<bool> dp(1<<N,false);
    dp[0]=true;
    int ans=0;
    for (int mask=0;mask<(1<<N);++mask){
        if (!dp[mask]) continue;
        for (int i=0;i<N;++i){
            if (mask&1<<i) continue;
            Segment S(s[i],t[i]);
            bool ok=true;
            for (int j=0;j<N;++j){
                if (i==j) continue;
                Point p=(mask&1<<j?t[j]:s[j]);
                if (distance(S,p)<r[i]+r[j]) ok=false;
            }
            if (ok) dp[mask|1<<i]=true;
        }
        ans=max(ans,__builtin_popcount(mask));
    }

    cout << ans << '\n';
}
accuracy: 1
time_ms: 100
memory_kb: 3240
final_rank: 9