Problem:
シールの重なり
1 辺の長さが 10 の正方形の折り紙に半径 1 の円形のシールを
n
枚貼ります。シールは重ねて貼ることができます。シールを貼る位置の座標を読み込んで、折り紙上でもっとも多くシールが重なっている場所(シールが１枚だけでも"重なっている"とする)でのシールの枚数を出力するプログラムを作成してください。
折り紙の左下を原点とした
x, y
座標を与えます。この
x, y
を円の中心としてシールを貼ることとします。円の中心が折り紙の外に出ることはありません。また、同一座標に複数のシールが貼られることはありません。
Input
複数のデータセットが与えられます。各データセットは以下のような形式で与えられます。
n
x
1
,
y
1
x
2
,
y
2
:
x
n
,
y
n
１行目にシールの枚数
n
(0 ≤ 100) が与えられます。続く
n
行に、各シールの中心座標が与えられます。
x
i
,
y
i
は
i
枚目のシールの中心の
x
座標と
y
座標を表します。各値は小数点以下最大 6 桁までの数字を含む実数で与えられます。
n
が 0 のとき、入力の最後とします。データセットの数は 50 を超えません。
Output
各データセットに対し、折り紙上で最も多くシールが重なっている場所でのシールの枚数（整数）を出力して下さい。
Sample Input
15
3.14979,8.51743 
2.39506,3.84915 
2.68432,5.39095 
5.61904,9.16332 
7.85653,4.75593 
2.84021,5.41511 
1.79500,8.59211 
7.55389,8.17604 
4.70665,4.66125 
1.63470,4.42538 
7.34959,4.61981 
5.09003,8.11122 
5.24373,1.30066 
0.13517,1.83659 
7.57313,1.58150 
0
Output for the Sample Input
4
Hint
入力例のようにシールを貼った図です。円はシール、数字は入力例の行数を表しています。
点(2.3,4.6)では、入力例の 2 行目、3 行目、6 行目、10 行目の 4 枚のシールが重なっています。
6 と 9 のおのおのの中心の距離は 2.01293 なので、シールは重なっていません。1 と 12 のおのおのの中心の距離は 1.98231 なので、シールは重なっています。
２つの円が接しているとき（おのおのの中心の距離が 2 のとき）は、重なっているものとします。

Submitted solutions:

code_snippet: #pragma region Macros
 
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2")
 
#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;
 
#define pb emplace_back
#define int ll
#define endl '\n'
// #define unordered_map<int, int> gp_hash_table<int, int, custom_hash> 
 
#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl
 
#define next asdnext
#define prev asdprev
 
using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
// const int MOD = 998244353;
const int MOD = 1000000007;
 
const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
 
const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};
 
#define EC int
struct Edge {
    int from, to;
    EC cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, EC cost) : to(to), cost(cost) {}
    Edge(int from, int to, EC cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge& e) { return this->cost < e.cost; }
    bool operator >(const Edge& e) { return this->cost > e.cost; }
};
 
chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}
 
random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;
 
 
__int128_t POW(__int128_t x, int n) {
    __int128_t ret = 1;
    assert(n >= 0);
    if (x == 1 or n == 0) ret = 1;
    else if (x == -1 && n % 2 == 0) ret = 1; 
    else if (x == -1) ret = -1; 
    else if (n % 2 == 0) {
        assert(x < INFL);
        ret = POW(x * x, n / 2);
    } else {
        assert(x < INFL);
        ret = x * POW(x, n - 1);
    }
    return ret;
}
int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
    assert(y != 0);
    if (x >= 0 && y > 0) return x / y;
    if (x >= 0 && y < 0) return x / y - (x % y < 0);
    if (x < 0 && y < 0) return x / y + (x % y < 0);
    return x / y - (x % y < 0); //  (x < 0 && y > 0) 
}
int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
    assert(y != 0);
    if (x >= 0) return x % y;
    __int128_t ret = x % y; // (x < 0)
    ret += (__int128_t)abs(y) * INFL;
    ret %= abs(y);
    return ret;
}
int floor(int x, int y) { // (ld)x / y 以下の最大の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x >= 0 ? x / y : (x + 1) / y - 1;
}
int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x > 0 ? (x - 1) / y + 1 : x / y;
}
int round(int x, int y) {
    assert(y != 0);
    return (x * 2 + y) / (y * 2);
}
int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
    assert(y != 0); // TODO
    return INF;
}
int round2(int x, int y) { // 五捨五超入 // 未verify
    assert(y != 0);
    if (y < 0) y = -y, x = -x;
    int z = x / y;
    if ((z * 2 + 1) * y <= y * 2) z++;
    return z;
}
// int round(ld x, int k) { // xを10^kの位に関して四捨五入
// }
// int floor(ld x, int k) { // xを10^kの位に関してflooring
// }
// int ceil(ld x, int k) { // xを10^kの位に関してceiling
// }
// int kth(int x, int y, int k) { // x / yの10^kの位の桁
// }
int floor(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return floor(x / y);
    // floor(x) = ceil(x - 1) という話も
}
int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
    assert(!equals(y, 0));
    return ceil(x / y);
    // ceil(x) = floor(x + 1)
}
int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
    // 未verify. 誤差対策TODO. EPS外してもいいかも。
    assert(!equals(y, 0));
    if (x >= 0 && y > 0) return floor(x / y)+EPS;
    if (x >= 0 && y < 0) return -floor(x / fabs(y));
    if (x < 0 && y < 0) return floor(x / y) + (x - floor(x/y)*y < -EPS);
    return floor(x / y) - (x - floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
}
ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
    // 未verify. 誤差対策TODO. -0.0が返りうる。
    assert(!equals(y, 0));
    if (x >= 0) return x - fabs(y)*fabs(per(x, y));
    return x - fabs(y)*floor(x, fabs(y));
}
int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
int modf(ld x) {
	if (x < 0) return ceill(x);
	else return floorl(x);
}
// 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
int seisuu(int x, int y) {
    assert(y != 0);
    return x / y;
}
int seisuu(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return (int)(x / y);
}
 
template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
    return b;
}
template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
    return b;
}
 
template <class T> bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; } return false;
}
template <class T> bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; } return false;
}
template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
    return a + b + c - max({a, b, c}) - min({a, b, c});
}
template <class T> void Sort(T &a, T &b, bool rev = false) { 
    if (rev == false) {  // TODO テンプレート引数
        if (a > b) swap(a, b);
    } else {
        if (b > a) swap(b, a);
    }
}
template <class T> void Sort(T &a, T &b, T &c, bool rev = false) {
    if (rev == false) { 
        if (a > b) swap(a, b); if (a > c) swap(a, c); if (b > c) swap(b, c);
    } else {
        if (c > b) swap(c, b); if (c > a) swap(c, a); if (b > a) swap(b, a);
    }
}
template <class T> void Sort(T &a, T &b, T &c, T &d, bool rev = false) {
    if (rev == false) { 
        if (a > b) swap(a, b); if (a > c) swap(a, c);  if (a > d) swap(a, d);
        if (b > c) swap(b, c); if (b > d) swap(b, d); if (c > d) swap(c, d);
    } else {
        if (d > c) swap(d, c); if (d > b) swap(d, b); if (d > a) swap(d, a);
        if (c > b) swap(c, b); if (c > a) swap(c, a); if (b > a) swap(b, a);
    }
}
 
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
 
class Compress {
public:
    int sz = 0;
    // gp_hash_table<int, int, custom_hash> Z, UZ;
    unordered_map<int, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, int> UZ;   // 圧縮した値 -> 元の値
 
    Compress(const vector<int> &V, int base = 0) {
        this->sz = base;
        set<int> s(V.begin(), V.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<int> &V1, const vector<int> &V2, int base = 0) {
        this->sz = base;
        vector<int> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<int> s(V3.begin(), V3.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2, const vector<int> &V3, int base = 0) {
        this->sz = base;
        vector<int> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<int> s(V4.begin(), V4.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2,
            const vector<int> &V3, const vector<int> &V4, int base = 0) {
        this->sz = base;
        vector<int> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<int> s(V5.begin(), V5.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    vector<int> zip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[ret[i]];
        }
        return ret;
    }
 
    vector<int> unzip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[ret[i]];
        }
        return ret;
    }
 
    int size() { return sz; }
 
    int encode(int x) { return Z[x]; }
    int decode(int x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};
 
class UnionFind {
public:
	UnionFind() = default;
    UnionFind(int N) : par(N), sz(N, 1) {
        iota(par.begin(), par.end(), 0);
    }
	int root(int x) {
		if (par[x] == x) return x;
		return (par[x] = root(par[x]));
	}
	bool unite(int x, int y) {
		int rx = root(x);
		int ry = root(y);
        if (rx == ry) return false;
		if (sz[rx] < sz[ry]) swap(rx, ry);
		sz[rx] += sz[ry];
		par[ry] = rx;
        return true;
	}
	bool issame(int x, int y) { return (root(x) == root(y)); }
	int size(int x) { return sz[root(x)]; }
    vector<vector<int>> groups(int N) {
        vector<vector<int>> G(N);
        for (int x = 0; x < N; x++) {
            G[root(x)].push_back(x);
        }
		G.erase( remove_if(G.begin(), G.end(),
            [&](const vector<int>& V) { return V.empty(); }), G.end());
        return G;
    }
private:
	vector<int> par, sz;
};
 
template<typename T>
struct BIT {
    int N;             
    vector<T> bit[2]; 
    BIT(int N_, int x = 0) {
        N = N_ + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        if (x != 0) {
            for (int i = 0; i < N; i++) add(i, x);
        }
    }
    BIT(const vector<T> &A) {
        N = A.size() + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        for (int i = 0; i < (int)A.size(); i++) add(i, A[i]);
    }
    void add_sub(int p, int i, T x) {
        while (i < N) { bit[p][i] += x; i += (i & -i); }
    }
    void add(int l, int r, T x) {
        add_sub(0, l + 1, -x * l); add_sub(0, r + 1, x * r);
        add_sub(1, l + 1, x); add_sub(1, r + 1, -x);
    }
    void add(int i, T x) { add(i, i + 1, x); }
    T sum_sub(int p, int i) {
        T ret = 0;
        while (i > 0) { ret += bit[p][i]; i -= (i & -i); }
        return ret;
    }
    T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }
    T sum(int l, int r) { return sum(r) - sum(l); }
    T get(int i) { return sum(i, i + 1); }
    void set(int i, T x) { T s = get(i); add(i, -s + x); }
};
 
template<int mod> class Modint {
public:
    int val = 0;
    Modint(int x = 0) { while (x < 0) x += mod; val = x % mod; }
    Modint(const Modint &r) { val = r.val; }
 
    Modint operator -() { return Modint(-val); } // 単項
    Modint operator +(const Modint &r) { return Modint(*this) += r; }
    Modint operator +(const int &q) { Modint r(q); return Modint(*this) += r; }
    Modint operator -(const Modint &r) { return Modint(*this) -= r; }
    Modint operator -(const int &q) { Modint r(q); return Modint(*this) -= r; }
    Modint operator *(const Modint &r) { return Modint(*this) *= r; }
    Modint operator *(const int &q) { Modint r(q); return Modint(*this) *= r; }
    Modint operator /(const Modint &r) { return Modint(*this) /= r; }
    Modint operator /(const int &q) { Modint r(q); return Modint(*this) /= r; }
    
    Modint& operator ++() { val++; if (val >= mod) val -= mod; return *this; } // 前置
    Modint operator ++(signed) { ++*this; return *this; } // 後置
    Modint& operator --() { val--; if (val < 0) val += mod; return *this; }
    Modint operator --(signed) { --*this; return *this; }
    Modint &operator +=(const Modint &r) { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator +=(const int &q) { Modint r(q); val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator -=(const Modint &r) { if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator -=(const int &q) { Modint r(q);  if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator *=(const Modint &r) { val = val * r.val % mod; return *this; }
    Modint &operator *=(const int &q) { Modint r(q); val = val * r.val % mod; return *this; }
    Modint &operator /=(const Modint &r) {
        int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    Modint &operator /=(const int &q) {
        Modint r(q); int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    bool operator ==(const Modint& r) { return this -> val == r.val; }
    bool operator <(const Modint& r) { return this -> val < r.val; }
    bool operator >(const Modint& r) { return this -> val > r.val; }
    bool operator !=(const Modint& r) { return this -> val != r.val; }
};
 
using mint = Modint<MOD>;
 
istream &operator >>(istream &is, mint& x) {
    int t; is >> t; x = t; return (is);
}
ostream &operator <<(ostream &os, const mint& x) {
    return os << x.val;
}
mint modpow(const mint &x, int n) {
    if (n < 0) return (mint)1 / modpow(x, -n); // 未verify
    assert(n >= 0);
    if (n == 0) return 1;
    mint t = modpow(x, n / 2);
    t = t * t;
    if (n & 1) t = t * x;
    return t;
}
 
int modpow(__int128_t x, int n, int mod) {
    assert(n >= 0 && mod > 0); // TODO: n <= -1
    __int128_t ret = 1;
    while (n > 0) {
        if (n % 2 == 1) ret = ret * x % mod;
        x = x * x % mod;
        n /= 2;
    }
    return ret;
}
int modinv(__int128_t x, int mod) {
    assert(mod > 0);
    // assert(x > 0);
    if (x == 1 or x == 0) return 1;
    return mod - modinv(mod % x, mod) * (mod / x) % mod;
}
 
istream &operator >>(istream &is, __int128_t& x) {
    string S; is >> S;
    __int128_t ret = 0;
    int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9')
            ret = ret * 10 + S[i] - '0';
    x = ret * f;
    return (is);
}
ostream &operator <<(ostream &os, __int128_t x) {
    ostream::sentry s(os);
    if (s) {
        __uint128_t tmp = x < 0 ? -x : x;
        char buffer[128]; char *d = end(buffer);
        do {
            --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
        } while (tmp != 0);
        if (x < 0) { --d; *d = '-'; }
        int len = end(buffer) - d;
        if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
    }
    return os;
}
 
__int128_t stoll(string &S) {
    __int128_t ret = 0; int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
    return ret * f;
}
__int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
__int128_t lcm(__int128_t a, __int128_t b) {
    return a / gcd(a, b) * b;
    // lcmが__int128_tに収まる必要あり
}
 
string to_string(ld x, int k) { // xの小数第k位までをstring化する
    assert(k >= 0);
    stringstream ss;
    ss << setprecision(k + 2) << x;
    string s = ss.str();
    if (s.find('.') == string::npos) s += '.';
    int pos = s.find('.');
    for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
    s.pop_back();
    if (s.back() == '.') s.pop_back();
    return s;
 
    // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
    // ss << setprecision(k + 1) << x;
    // string s = ss.str();
    // if (s.find('.') == string::npos) s += '.';
    // int pos = s.find('.');
    // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
    // if (s.back() == '.') s.pop_back();
    // return s;
}
string to_string(__int128_t x) {
    string ret = "";
    if (x < 0) { ret += "-"; x *= -1; }
    while (x) { ret += (char)('0' + x % 10); x /= 10; }
    reverse(ret.begin(), ret.end());
    return ret;
}
string to_string(char c) { string s = ""; s += c; return s; }
 
 
#pragma endregion

struct Point {
	double x, y;

	Point() {}
	Point(double x, double y) : x(x), y(y) {}

	Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
	Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
	Point operator*(const double& k) const { return Point(x * k, y * k); }
	Point operator/(const double& k) const { return Point(x / k, y / k); }

	friend istream& operator>>(istream& is, Point& p) {
		is >> p.x >> p.y;
		return is;
	}
	friend ostream& operator<<(ostream& os, Point& p) {
		os << p.x << " " << p.y;
		return os;
	}

	bool operator==(const Point& p) const { return (fabs(x - p.x) < EPS && fabs(y - p.y) < EPS); }
	// bool operator!=(const Point& p) const { return (fabs(x - p.x) > EPS or fabs(y - p.y) > EPS); }
	bool operator<(const Point& p) const { return (x != p.x ? x < p.x : y < p.y); }
	// (x, y) の辞書順比較

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

typedef Point Vector;

double radToDeg(double radian) { return radian * 180.0 / PI; }
double degToRad(double degree) { return degree * PI / 180.0; }

int sign(double x) { return x < -EPS ? -1 : x > EPS; } // -1(負)/0/1(正)

double norm(Vector a) { return a.x * a.x + a.y * a.y; }
double abs(Vector a) { return sqrt(norm(a)); }
double dist(Point a, Point b) { return sqrt(norm(a - b)); }
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; } // 内積
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; } // 外積

Vector orth(Vector p) { return {-p.y, p.x}; }

double arg(Vector p) { return atan2(p.y, p.x); } // 偏角
Point polar(double r, double a) { return Point(cos(a) * r, sin(a) * r); } // 極座標から直交座標への変換

bool isParallel(Vector a, Vector b) { return equals(cross(a, b), 0.0); }
bool isOrthogonal(Vector a, Vector b) { return equals(dot(a, b), 0.0); }
// bool isSameLine(Vector a, Vector b) { return equals(); }

struct EndPoint { // 端点の構造体(マンハッタン幾何)
	Point p;
	int seg, st; // 点のid, 点の種別

	EndPoint() {}
	EndPoint(Point p, int seg, int st) : p(p), seg(seg), st(st) {}

	bool operator<(const EndPoint& ep) const {
		if (p.y == ep.p.y) return st < ep.st;
		return p.y < ep.p.y;
	}
};

struct Segment {
	Point p1, p2;

	Segment() {}
	Segment(Point p1, Point p2) : p1(p1), p2(p2) {}

	friend istream& operator>>(istream& is, Segment& s) {
		is >> s.p1 >> s.p2;
		return is;
	}

	// 未verify
    bool operator==(const Segment& s) const { return (abs(p1 - s.p1) < EPS && abs(p2 - s.p2) < EPS); }
	bool operator!=(const Segment& s) const { return (abs(p1 - s.p1) > EPS or abs(p2 - s.p2) > EPS); }
};

struct Line {
	Point p1, p2;

	Line() {}
	Line(Point p1, Point p2) : p1(p1), p2(p2) {}
	// Ax + By = C
    Line(double A, double B, double C) {
        if (equals(A, 0)) {
            p1 = Point(0, C / B), p2 = Point(1, C / B);
        } else if (equals(B, 0)) {
            p2 = Point(C / A, 0), p2 = Point(C / A, 1);
        } else {
            p1 = Point(0, C / B), p2 = Point(C / A, 0);
        }
    }

	friend istream& operator>>(istream& is, Line& l) {
		is >> l.p1 >> l.p2;
		return is;
	}

	bool operator==(const Line& l) const { 
        if (abs(cross(p1 - l.p1, l.p2 - l.p1)) > EPS) return false;
        if (abs(cross(p2 - l.p1, l.p2 - l.p1)) > EPS) return false;
        return true;
    }
	// bool operator<(const Line& l) const { return (l.p2.y - l.p1.y) * (p2.x - p1.x) < (l.p2.x - l.p1.x) * (p2.y - p1.y); }
};


bool isParallel(Segment S1, Segment S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isParallel(Line S1, Line S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isParallel(Line S1, Segment S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isParallel(Segment S1, Line S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }

bool isOrthogonal(Segment S1, Segment S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isOrthogonal(Line S1, Line S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isOrthogonal(Line S1, Segment S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isOrthogonal(Segment S1, Line S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }

// bool isSameLine(Segment S1, Segment S2) { return isSameLine(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isSameLine(Line L1, Line L2) { 
    if (abs(cross(L1.p1 - L2.p1, L2.p2 - L2.p1)) > EPS) return false;
    if (abs(cross(L1.p2 - L2.p1, L2.p2 - L2.p1)) > EPS) return false;
    return true;
}
// bool isSameLine(Line L1, Segment S2) { return isSameLine(L1.p2 - L1.p1, S2.p2 - S2.p1); }
// bool isSameLine(Segment S1, Line S2) { return isSameLine(S1.p2 - S1.p1, S2.p2 - S2.p1); }

bool onSegment(Segment S, Point p) {
	if (sign(cross(S.p1-p, S.p2-p)) != 0) return false;
  	if (sign(  dot(S.p1-p, S.p2-p))  > 0) return false;
	return true;
}
bool onLine(Line L, Point p) {
	if (sign(cross(L.p1-p, L.p2-p)) != 0) return false;
	return true;
}

Point project(Segment s, Point p) { // 点の射影
	Vector base = s.p2 - s.p1;
	double r = dot(p - s.p1, base) / base.norm();
	return s.p1 + base * r;
}

Point reflect(Segment s, Point p) { // 点の反射
	return p + (project(s, p) - p) * 2.0;
}

Point projectL(Line s, Point p) { // 点の射影
	Vector base = s.p2 - s.p1;
	double r = dot(p - s.p1, base) / base.norm();
	return s.p1 + base * r;
}

Point reflectL(Line l, Point p) { // 点の反射
	return p + (project(Segment(l.p1, l.p2), p) - p) * 2.0;
}

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;
	}
};

typedef vector<Point> Polygon;

vector<Point> getCrossPointCC(Circle c1, Circle c2) {
	double d = abs(c1.c - c2.c);
	double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
	double t = arg(c2.c - c1.c);
	vector<Point> ps;
	ps.push_back(c1.c + polar(c1.r, t + a)); ps.push_back(c1.c + polar(c1.r, t - a));
	return ps;
}

int contain(Circle C, Point p) {
    if (equals(abs(C.c - p), C.r)) return 1; // ON
    if (abs(C.c - p) <= C.r + EPS) return 2; // IN
    return 0; // OUT
}

double getDistanceLP(Line l, Point p) {
	return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

double getDistanceSP(Segment s, Point p) {
	if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return abs(p - s.p1);
	if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return abs(p - s.p2);
	return getDistanceLP(Line{s.p1, s.p2}, p);
}

int intersectCS(Circle C, Segment S) {
	// SがCの外側
	if (norm(project(S, C.c) - C.c) - C.r * C.r > EPS) return 0;

	double d1 = abs(C.c - S.p1), d2 = abs(C.c - S.p2);
	// SがCに内包される
	if (d1 < C.r - EPS && d2 < C.r - EPS) return 0;
	// 線分のどちらかの端点が円の内部に、もう片方の端点が円の外部にある場合
	if ((d1 < C.r - EPS && d2 > C.r + EPS) or (d1 > C.r + EPS && d2 < C.r - EPS)) return 1;
	
	Point h = project(S, C.c);
	if (dot(S.p1 - h, S.p2 - h) < -EPS) return 2; // 2回交差
	return 0; // その他?
}

vector<Point> getCrossPointCL(Circle C, Line L) {
	vector<Point> ps;
	Vector pr = projectL(L, C.c);
	Vector e = (L.p2 - L.p1) / abs(L.p2 - L.p1);
	if (equals(getDistanceLP(L, C.c), C.r)) return vector<Point>{pr, pr};
	double base = sqrt(C.r * C.r - norm(pr - C.c));
	ps.push_back(pr + e * base); ps.push_back(pr - e * base);
	return ps;
}

vector<Point> getCrossPointCS(Circle C, Segment S) {
	Line L = {S.p1, S.p2};
	vector<Point> ps = getCrossPointCL(C, L);
	if (intersectCS(C, S) == 2) return ps;
	if (dot(L.p1 - ps[0], L.p2 - ps[0]) < 0) ps[1] = ps[0];
	else ps[0] = ps[1];
	return ps;
}

signed main() {
    int N;
    while (cin >> N, N) {
        vector<Circle> C(N);
        for (int i = 0; i < N; i++) {
            double x, y;
            char c;
            cin >> x >> c >> y;
            C[i] = Circle(Point(x, y), 1);
        }

        vector<Segment> S = {{Point(0, 0), Point(0, 10)},
                             {Point(0, 10), Point(10, 10)},
                             {Point(10, 10), Point(10, 0)},
                             {Point(10, 0), Point(0, 0)}};

        vector<Point> P; // 交点の集合
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                vector<Point> CP = getCrossPointCC(C[i], C[j]);
                for (int k = 0; k < CP.size(); k++) {
                    // if (CP[k].x > 10. + EPS or CP[k].x < 0. - EPS) continue;
                    // if (CP[k].y > 10. + EPS or CP[k].y < 0. - EPS) continue;
                    P.pb(CP[k]);
                }
            }
            for (int j = 0; j < 4; j++) {
                vector<Point> CP = getCrossPointCS(C[i], S[j]);
                for (int k = 0; k < CP.size(); k++) {
                    P.pb(CP[k]);
                }
            }
        }
        // sort(P.begin(), P.end());
        // P.erase(unique(P.begin(), P.end()), P.end());

        int ans = 0;
        for (int i = 0; i < P.size(); i++) {
            int cnt = 0;
            for (int j = 0; j < N; j++) {
                if (contain(C[j], P[i])) cnt++;
            }
            ans = max(ans, cnt);
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 690
memory_kb: 4232
final_rank: 19

code_snippet: #pragma region Macros
 
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2")
 
#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;
 
#define pb emplace_back
#define int ll
#define endl '\n'
// #define unordered_map<int, int> gp_hash_table<int, int, custom_hash> 
 
#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl
 
#define next asdnext
#define prev asdprev
 
using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
// const int MOD = 998244353;
const int MOD = 1000000007;
 
const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
 
const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};
 
#define EC int
struct Edge {
    int from, to;
    EC cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, EC cost) : to(to), cost(cost) {}
    Edge(int from, int to, EC cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge& e) { return this->cost < e.cost; }
    bool operator >(const Edge& e) { return this->cost > e.cost; }
};
 
chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}
 
random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;
 
 
__int128_t POW(__int128_t x, int n) {
    __int128_t ret = 1;
    assert(n >= 0);
    if (x == 1 or n == 0) ret = 1;
    else if (x == -1 && n % 2 == 0) ret = 1; 
    else if (x == -1) ret = -1; 
    else if (n % 2 == 0) {
        assert(x < INFL);
        ret = POW(x * x, n / 2);
    } else {
        assert(x < INFL);
        ret = x * POW(x, n - 1);
    }
    return ret;
}
int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
    assert(y != 0);
    if (x >= 0 && y > 0) return x / y;
    if (x >= 0 && y < 0) return x / y - (x % y < 0);
    if (x < 0 && y < 0) return x / y + (x % y < 0);
    return x / y - (x % y < 0); //  (x < 0 && y > 0) 
}
int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
    assert(y != 0);
    if (x >= 0) return x % y;
    __int128_t ret = x % y; // (x < 0)
    ret += (__int128_t)abs(y) * INFL;
    ret %= abs(y);
    return ret;
}
int floor(int x, int y) { // (ld)x / y 以下の最大の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x >= 0 ? x / y : (x + 1) / y - 1;
}
int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x > 0 ? (x - 1) / y + 1 : x / y;
}
int round(int x, int y) {
    assert(y != 0);
    return (x * 2 + y) / (y * 2);
}
int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
    assert(y != 0); // TODO
    return INF;
}
int round2(int x, int y) { // 五捨五超入 // 未verify
    assert(y != 0);
    if (y < 0) y = -y, x = -x;
    int z = x / y;
    if ((z * 2 + 1) * y <= y * 2) z++;
    return z;
}
// int round(ld x, int k) { // xを10^kの位に関して四捨五入
// }
// int floor(ld x, int k) { // xを10^kの位に関してflooring
// }
// int ceil(ld x, int k) { // xを10^kの位に関してceiling
// }
// int kth(int x, int y, int k) { // x / yの10^kの位の桁
// }
int floor(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return floor(x / y);
    // floor(x) = ceil(x - 1) という話も
}
int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
    assert(!equals(y, 0));
    return ceil(x / y);
    // ceil(x) = floor(x + 1)
}
int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
    // 未verify. 誤差対策TODO. EPS外してもいいかも。
    assert(!equals(y, 0));
    if (x >= 0 && y > 0) return floor(x / y)+EPS;
    if (x >= 0 && y < 0) return -floor(x / fabs(y));
    if (x < 0 && y < 0) return floor(x / y) + (x - floor(x/y)*y < -EPS);
    return floor(x / y) - (x - floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
}
ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
    // 未verify. 誤差対策TODO. -0.0が返りうる。
    assert(!equals(y, 0));
    if (x >= 0) return x - fabs(y)*fabs(per(x, y));
    return x - fabs(y)*floor(x, fabs(y));
}
int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
int modf(ld x) {
	if (x < 0) return ceill(x);
	else return floorl(x);
}
// 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
int seisuu(int x, int y) {
    assert(y != 0);
    return x / y;
}
int seisuu(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return (int)(x / y);
}
 
template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
    return b;
}
template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
    return b;
}
 
template <class T> bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; } return false;
}
template <class T> bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; } return false;
}
template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
    return a + b + c - max({a, b, c}) - min({a, b, c});
}
template <class T> void Sort(T &a, T &b, bool rev = false) { 
    if (rev == false) {  // TODO テンプレート引数
        if (a > b) swap(a, b);
    } else {
        if (b > a) swap(b, a);
    }
}
template <class T> void Sort(T &a, T &b, T &c, bool rev = false) {
    if (rev == false) { 
        if (a > b) swap(a, b); if (a > c) swap(a, c); if (b > c) swap(b, c);
    } else {
        if (c > b) swap(c, b); if (c > a) swap(c, a); if (b > a) swap(b, a);
    }
}
template <class T> void Sort(T &a, T &b, T &c, T &d, bool rev = false) {
    if (rev == false) { 
        if (a > b) swap(a, b); if (a > c) swap(a, c);  if (a > d) swap(a, d);
        if (b > c) swap(b, c); if (b > d) swap(b, d); if (c > d) swap(c, d);
    } else {
        if (d > c) swap(d, c); if (d > b) swap(d, b); if (d > a) swap(d, a);
        if (c > b) swap(c, b); if (c > a) swap(c, a); if (b > a) swap(b, a);
    }
}
 
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
 
class Compress {
public:
    int sz = 0;
    // gp_hash_table<int, int, custom_hash> Z, UZ;
    unordered_map<int, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, int> UZ;   // 圧縮した値 -> 元の値
 
    Compress(const vector<int> &V, int base = 0) {
        this->sz = base;
        set<int> s(V.begin(), V.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<int> &V1, const vector<int> &V2, int base = 0) {
        this->sz = base;
        vector<int> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<int> s(V3.begin(), V3.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2, const vector<int> &V3, int base = 0) {
        this->sz = base;
        vector<int> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<int> s(V4.begin(), V4.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2,
            const vector<int> &V3, const vector<int> &V4, int base = 0) {
        this->sz = base;
        vector<int> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<int> s(V5.begin(), V5.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    vector<int> zip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[ret[i]];
        }
        return ret;
    }
 
    vector<int> unzip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[ret[i]];
        }
        return ret;
    }
 
    int size() { return sz; }
 
    int encode(int x) { return Z[x]; }
    int decode(int x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};
 
class UnionFind {
public:
	UnionFind() = default;
    UnionFind(int N) : par(N), sz(N, 1) {
        iota(par.begin(), par.end(), 0);
    }
	int root(int x) {
		if (par[x] == x) return x;
		return (par[x] = root(par[x]));
	}
	bool unite(int x, int y) {
		int rx = root(x);
		int ry = root(y);
        if (rx == ry) return false;
		if (sz[rx] < sz[ry]) swap(rx, ry);
		sz[rx] += sz[ry];
		par[ry] = rx;
        return true;
	}
	bool issame(int x, int y) { return (root(x) == root(y)); }
	int size(int x) { return sz[root(x)]; }
    vector<vector<int>> groups(int N) {
        vector<vector<int>> G(N);
        for (int x = 0; x < N; x++) {
            G[root(x)].push_back(x);
        }
		G.erase( remove_if(G.begin(), G.end(),
            [&](const vector<int>& V) { return V.empty(); }), G.end());
        return G;
    }
private:
	vector<int> par, sz;
};
 
template<typename T>
struct BIT {
    int N;             
    vector<T> bit[2]; 
    BIT(int N_, int x = 0) {
        N = N_ + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        if (x != 0) {
            for (int i = 0; i < N; i++) add(i, x);
        }
    }
    BIT(const vector<T> &A) {
        N = A.size() + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        for (int i = 0; i < (int)A.size(); i++) add(i, A[i]);
    }
    void add_sub(int p, int i, T x) {
        while (i < N) { bit[p][i] += x; i += (i & -i); }
    }
    void add(int l, int r, T x) {
        add_sub(0, l + 1, -x * l); add_sub(0, r + 1, x * r);
        add_sub(1, l + 1, x); add_sub(1, r + 1, -x);
    }
    void add(int i, T x) { add(i, i + 1, x); }
    T sum_sub(int p, int i) {
        T ret = 0;
        while (i > 0) { ret += bit[p][i]; i -= (i & -i); }
        return ret;
    }
    T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }
    T sum(int l, int r) { return sum(r) - sum(l); }
    T get(int i) { return sum(i, i + 1); }
    void set(int i, T x) { T s = get(i); add(i, -s + x); }
};
 
template<int mod> class Modint {
public:
    int val = 0;
    Modint(int x = 0) { while (x < 0) x += mod; val = x % mod; }
    Modint(const Modint &r) { val = r.val; }
 
    Modint operator -() { return Modint(-val); } // 単項
    Modint operator +(const Modint &r) { return Modint(*this) += r; }
    Modint operator +(const int &q) { Modint r(q); return Modint(*this) += r; }
    Modint operator -(const Modint &r) { return Modint(*this) -= r; }
    Modint operator -(const int &q) { Modint r(q); return Modint(*this) -= r; }
    Modint operator *(const Modint &r) { return Modint(*this) *= r; }
    Modint operator *(const int &q) { Modint r(q); return Modint(*this) *= r; }
    Modint operator /(const Modint &r) { return Modint(*this) /= r; }
    Modint operator /(const int &q) { Modint r(q); return Modint(*this) /= r; }
    
    Modint& operator ++() { val++; if (val >= mod) val -= mod; return *this; } // 前置
    Modint operator ++(signed) { ++*this; return *this; } // 後置
    Modint& operator --() { val--; if (val < 0) val += mod; return *this; }
    Modint operator --(signed) { --*this; return *this; }
    Modint &operator +=(const Modint &r) { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator +=(const int &q) { Modint r(q); val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator -=(const Modint &r) { if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator -=(const int &q) { Modint r(q);  if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator *=(const Modint &r) { val = val * r.val % mod; return *this; }
    Modint &operator *=(const int &q) { Modint r(q); val = val * r.val % mod; return *this; }
    Modint &operator /=(const Modint &r) {
        int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    Modint &operator /=(const int &q) {
        Modint r(q); int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    bool operator ==(const Modint& r) { return this -> val == r.val; }
    bool operator <(const Modint& r) { return this -> val < r.val; }
    bool operator >(const Modint& r) { return this -> val > r.val; }
    bool operator !=(const Modint& r) { return this -> val != r.val; }
};
 
using mint = Modint<MOD>;
 
istream &operator >>(istream &is, mint& x) {
    int t; is >> t; x = t; return (is);
}
ostream &operator <<(ostream &os, const mint& x) {
    return os << x.val;
}
mint modpow(const mint &x, int n) {
    if (n < 0) return (mint)1 / modpow(x, -n); // 未verify
    assert(n >= 0);
    if (n == 0) return 1;
    mint t = modpow(x, n / 2);
    t = t * t;
    if (n & 1) t = t * x;
    return t;
}
 
int modpow(__int128_t x, int n, int mod) {
    assert(n >= 0 && mod > 0); // TODO: n <= -1
    __int128_t ret = 1;
    while (n > 0) {
        if (n % 2 == 1) ret = ret * x % mod;
        x = x * x % mod;
        n /= 2;
    }
    return ret;
}
int modinv(__int128_t x, int mod) {
    assert(mod > 0);
    // assert(x > 0);
    if (x == 1 or x == 0) return 1;
    return mod - modinv(mod % x, mod) * (mod / x) % mod;
}
 
istream &operator >>(istream &is, __int128_t& x) {
    string S; is >> S;
    __int128_t ret = 0;
    int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9')
            ret = ret * 10 + S[i] - '0';
    x = ret * f;
    return (is);
}
ostream &operator <<(ostream &os, __int128_t x) {
    ostream::sentry s(os);
    if (s) {
        __uint128_t tmp = x < 0 ? -x : x;
        char buffer[128]; char *d = end(buffer);
        do {
            --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
        } while (tmp != 0);
        if (x < 0) { --d; *d = '-'; }
        int len = end(buffer) - d;
        if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
    }
    return os;
}
 
__int128_t stoll(string &S) {
    __int128_t ret = 0; int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
    return ret * f;
}
__int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
__int128_t lcm(__int128_t a, __int128_t b) {
    return a / gcd(a, b) * b;
    // lcmが__int128_tに収まる必要あり
}
 
string to_string(ld x, int k) { // xの小数第k位までをstring化する
    assert(k >= 0);
    stringstream ss;
    ss << setprecision(k + 2) << x;
    string s = ss.str();
    if (s.find('.') == string::npos) s += '.';
    int pos = s.find('.');
    for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
    s.pop_back();
    if (s.back() == '.') s.pop_back();
    return s;
 
    // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
    // ss << setprecision(k + 1) << x;
    // string s = ss.str();
    // if (s.find('.') == string::npos) s += '.';
    // int pos = s.find('.');
    // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
    // if (s.back() == '.') s.pop_back();
    // return s;
}
string to_string(__int128_t x) {
    string ret = "";
    if (x < 0) { ret += "-"; x *= -1; }
    while (x) { ret += (char)('0' + x % 10); x /= 10; }
    reverse(ret.begin(), ret.end());
    return ret;
}
string to_string(char c) { string s = ""; s += c; return s; }
 
 
#pragma endregion

struct Point {
	double x, y;

	Point() {}
	Point(double x, double y) : x(x), y(y) {}

	Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
	Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
	Point operator*(const double& k) const { return Point(x * k, y * k); }
	Point operator/(const double& k) const { return Point(x / k, y / k); }

	friend istream& operator>>(istream& is, Point& p) {
		is >> p.x >> p.y;
		return is;
	}
	friend ostream& operator<<(ostream& os, Point& p) {
		os << p.x << " " << p.y;
		return os;
	}

	bool operator==(const Point& p) const { return (fabs(x - p.x) < EPS && fabs(y - p.y) < EPS); }
	// bool operator!=(const Point& p) const { return (fabs(x - p.x) > EPS or fabs(y - p.y) > EPS); }
	bool operator<(const Point& p) const { return (x != p.x ? x < p.x : y < p.y); }
	// (x, y) の辞書順比較

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

typedef Point Vector;

double radToDeg(double radian) { return radian * 180.0 / PI; }
double degToRad(double degree) { return degree * PI / 180.0; }

int sign(double x) { return x < -EPS ? -1 : x > EPS; } // -1(負)/0/1(正)

double norm(Vector a) { return a.x * a.x + a.y * a.y; }
double abs(Vector a) { return sqrt(norm(a)); }
double dist(Point a, Point b) { return sqrt(norm(a - b)); }
double dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; } // 内積
double cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; } // 外積

Vector orth(Vector p) { return {-p.y, p.x}; }

double arg(Vector p) { return atan2(p.y, p.x); } // 偏角
Point polar(double r, double a) { return Point(cos(a) * r, sin(a) * r); } // 極座標から直交座標への変換

bool isParallel(Vector a, Vector b) { return equals(cross(a, b), 0.0); }
bool isOrthogonal(Vector a, Vector b) { return equals(dot(a, b), 0.0); }
// bool isSameLine(Vector a, Vector b) { return equals(); }

struct EndPoint { // 端点の構造体(マンハッタン幾何)
	Point p;
	int seg, st; // 点のid, 点の種別

	EndPoint() {}
	EndPoint(Point p, int seg, int st) : p(p), seg(seg), st(st) {}

	bool operator<(const EndPoint& ep) const {
		if (p.y == ep.p.y) return st < ep.st;
		return p.y < ep.p.y;
	}
};

struct Segment {
	Point p1, p2;

	Segment() {}
	Segment(Point p1, Point p2) : p1(p1), p2(p2) {}

	friend istream& operator>>(istream& is, Segment& s) {
		is >> s.p1 >> s.p2;
		return is;
	}

	// 未verify
    bool operator==(const Segment& s) const { return (abs(p1 - s.p1) < EPS && abs(p2 - s.p2) < EPS); }
	bool operator!=(const Segment& s) const { return (abs(p1 - s.p1) > EPS or abs(p2 - s.p2) > EPS); }
};

struct Line {
	Point p1, p2;

	Line() {}
	Line(Point p1, Point p2) : p1(p1), p2(p2) {}
	// Ax + By = C
    Line(double A, double B, double C) {
        if (equals(A, 0)) {
            p1 = Point(0, C / B), p2 = Point(1, C / B);
        } else if (equals(B, 0)) {
            p2 = Point(C / A, 0), p2 = Point(C / A, 1);
        } else {
            p1 = Point(0, C / B), p2 = Point(C / A, 0);
        }
    }

	friend istream& operator>>(istream& is, Line& l) {
		is >> l.p1 >> l.p2;
		return is;
	}

	bool operator==(const Line& l) const { 
        if (abs(cross(p1 - l.p1, l.p2 - l.p1)) > EPS) return false;
        if (abs(cross(p2 - l.p1, l.p2 - l.p1)) > EPS) return false;
        return true;
    }
	// bool operator<(const Line& l) const { return (l.p2.y - l.p1.y) * (p2.x - p1.x) < (l.p2.x - l.p1.x) * (p2.y - p1.y); }
};


bool isParallel(Segment S1, Segment S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isParallel(Line S1, Line S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isParallel(Line S1, Segment S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isParallel(Segment S1, Line S2) { return isParallel(S1.p2 - S1.p1, S2.p2 - S2.p1); }

bool isOrthogonal(Segment S1, Segment S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isOrthogonal(Line S1, Line S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isOrthogonal(Line S1, Segment S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isOrthogonal(Segment S1, Line S2) { return isOrthogonal(S1.p2 - S1.p1, S2.p2 - S2.p1); }

// bool isSameLine(Segment S1, Segment S2) { return isSameLine(S1.p2 - S1.p1, S2.p2 - S2.p1); }
bool isSameLine(Line L1, Line L2) { 
    if (abs(cross(L1.p1 - L2.p1, L2.p2 - L2.p1)) > EPS) return false;
    if (abs(cross(L1.p2 - L2.p1, L2.p2 - L2.p1)) > EPS) return false;
    return true;
}
// bool isSameLine(Line L1, Segment S2) { return isSameLine(L1.p2 - L1.p1, S2.p2 - S2.p1); }
// bool isSameLine(Segment S1, Line S2) { return isSameLine(S1.p2 - S1.p1, S2.p2 - S2.p1); }

bool onSegment(Segment S, Point p) {
	if (sign(cross(S.p1-p, S.p2-p)) != 0) return false;
  	if (sign(  dot(S.p1-p, S.p2-p))  > 0) return false;
	return true;
}
bool onLine(Line L, Point p) {
	if (sign(cross(L.p1-p, L.p2-p)) != 0) return false;
	return true;
}

Point project(Segment s, Point p) { // 点の射影
	Vector base = s.p2 - s.p1;
	double r = dot(p - s.p1, base) / base.norm();
	return s.p1 + base * r;
}

Point reflect(Segment s, Point p) { // 点の反射
	return p + (project(s, p) - p) * 2.0;
}

Point projectL(Line s, Point p) { // 点の射影
	Vector base = s.p2 - s.p1;
	double r = dot(p - s.p1, base) / base.norm();
	return s.p1 + base * r;
}

Point reflectL(Line l, Point p) { // 点の反射
	return p + (project(Segment(l.p1, l.p2), p) - p) * 2.0;
}

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;
	}
};

typedef vector<Point> Polygon;

vector<Point> getCrossPointCC(Circle c1, Circle c2) {
	double d = abs(c1.c - c2.c);
	double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
	double t = arg(c2.c - c1.c);
	vector<Point> ps;
	ps.push_back(c1.c + polar(c1.r, t + a)); ps.push_back(c1.c + polar(c1.r, t - a));
	return ps;
}

int contain(Circle C, Point p) {
    if (equals(abs(C.c - p), C.r)) return 1; // ON
    if (abs(C.c - p) <= C.r + EPS) return 2; // IN
    return 0; // OUT
}

double getDistanceLP(Line l, Point p) {
	return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

double getDistanceSP(Segment s, Point p) {
	if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return abs(p - s.p1);
	if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return abs(p - s.p2);
	return getDistanceLP(Line{s.p1, s.p2}, p);
}

int intersectCS(Circle C, Segment S) {
	// SがCの外側
	if (norm(project(S, C.c) - C.c) - C.r * C.r > EPS) return 0;

	double d1 = abs(C.c - S.p1), d2 = abs(C.c - S.p2);
	// SがCに内包される
	if (d1 < C.r - EPS && d2 < C.r - EPS) return 0;
	// 線分のどちらかの端点が円の内部に、もう片方の端点が円の外部にある場合
	if ((d1 < C.r - EPS && d2 > C.r + EPS) or (d1 > C.r + EPS && d2 < C.r - EPS)) return 1;
	
	Point h = project(S, C.c);
	if (dot(S.p1 - h, S.p2 - h) < -EPS) return 2; // 2回交差
	return 0; // その他?
}

vector<Point> getCrossPointCL(Circle C, Line L) {
	vector<Point> ps;
	Vector pr = projectL(L, C.c);
	Vector e = (L.p2 - L.p1) / abs(L.p2 - L.p1);
	if (equals(getDistanceLP(L, C.c), C.r)) return vector<Point>{pr, pr};
	double base = sqrt(C.r * C.r - norm(pr - C.c));
	ps.push_back(pr + e * base); ps.push_back(pr - e * base);
	return ps;
}

vector<Point> getCrossPointCS(Circle C, Segment S) {
	Line L = {S.p1, S.p2};
	vector<Point> ps = getCrossPointCL(C, L);
	if (intersectCS(C, S) == 2) return ps;
	if (dot(L.p1 - ps[0], L.p2 - ps[0]) < 0) ps[1] = ps[0];
	else ps[0] = ps[1];
	return ps;
}

signed main() {
    int N;
    while (cin >> N, N) {
        vector<Circle> C(N);
        for (int i = 0; i < N; i++) {
            double x, y;
            char c;
            cin >> x >> c >> y;
            C[i] = Circle(Point(x, y), 1);
        }

        vector<Segment> S = {{Point(0, 0), Point(0, 10)},
                             {Point(0, 10), Point(10, 10)},
                             {Point(10, 10), Point(10, 1)},
                             {Point(10, 0), Point(0, 0)}};

        vector<Point> P; // 交点の集合
        for (int i = 0; i < N; i++) {
            for (int j = i + 1; j < N; j++) {
                vector<Point> CP = getCrossPointCC(C[i], C[j]);
                for (int k = 0; k < CP.size(); k++) {
                    if (CP[k].x > 10. + EPS or CP[k].x < 0. - EPS) continue;
                    if (CP[k].y > 10. + EPS or CP[k].y < 0. - EPS) continue;
                    P.pb(CP[k]);
                }
            }
            for (int j = 0; j < 4; j++) {
                vector<Point> CP = getCrossPointCS(C[i], S[j]);
                for (int k = 0; k < CP.size(); k++) {
                    P.pb(CP[k]);
                }
            }
        }
        int sz = P.size();
        // for (int i = 0; i < sz; i++) {
        //     Point p1 = Point(P[i].x + EPS, P[i].y + EPS);
        //     // Point p2 = Point(P[i].x + EPS, P[i].y - EPS);
        //     // Point p3 = Point(P[i].x - EPS, P[i].y + EPS);
        //     Point p4 = Point(P[i].x - EPS, P[i].y - EPS);
        //     P.pb(p1);
        //     // P.pb(p2);
        //     // P.pb(p3);
        //     P.pb(p4);
        // }
        // sort(P.begin(), P.end());
        // P.erase(unique(P.begin(), P.end()), P.end());


        int ans = 0;
        for (int i = 0; i < P.size(); i++) {
            int cnt = 0;
            for (int j = 0; j < N; j++) {
                if (contain(C[j], P[i])) cnt++;
            }
            ans = max(ans, cnt);
        }
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 700
memory_kb: 4332
final_rank: 20

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

int main(){
    int n;
    while(cin >> n, n){
        vector<pair<double,double>> a(n);
        vector<pair<ll,ll>> b(n);
        for(int i = 0; i < n; i++){
            scanf("%lf,%lf",&a[i].first,&a[i].second);
            b[i].first = a[i].first * 100000;
            b[i].second = a[i].second * 100000;
        }
        auto f = [&](ll x, ll y){
            int res = 0;
            for(int i = 0; i < n; i++){
                res += ((x - b[i].first) * (x - b[i].first) + (y - b[i].second) * (y - b[i].second) 
                        <= 10000000000);
            }
            return res;
        };
        int ans = 0;
        for(ll x = 0; x <= 1000000; x += 1000){
            for(ll y = 0; y <= 1000000; y += 1000){
                ans = max(ans, f(x, y));
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 310
memory_kb: 3516
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
#include <iomanip>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

using real = double;
static constexpr real EPS = 1e-10;
struct Point {
    real x, y;
    Point& operator+=(const Point a) { x += a.x; y += a.y;  return *this; }
    Point& operator-=(const Point a) { x -= a.x; y -= a.y;  return *this; }
    Point& operator*=(const real k) { x *= k; y *= k;  return *this; }
    Point& operator/=(const real k) { x /= k; y /= k;  return *this; }
    Point operator+(const Point a) const {return Point(*this) += a; }
    Point operator-(const Point a) const {return Point(*this) -= a; }
    Point operator*(const real k) const {return Point(*this) *= k; }
    Point operator/(const real k) const {return Point(*this) /= k; }
    bool operator<(const Point &a) const { return (x != a.x ? x < a.x : y < a.y); }
    explicit Point(real a = 0, real b = 0) : x(a), y(b) {};
};

bool sorty(Point a, Point b){
    return (a.y != b.y ? a.y < b.y : a.x < b.x);
}

istream& operator>> (istream& s, Point& P){
    s >> P.x >> P.y;
    return s;
}

inline real dot(Point a, Point b){ return a.x*b.x + a.y*b.y; }
inline real cross(Point a, Point b){ return a.x*b.y - a.y*b.x; }
inline real abs(Point a){ return sqrt(dot(a, a)); }


real angle(Point A, Point B){
    return acos(dot(A, B)/abs(A)/abs(B));
}



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

int ccw(Point a, Point b, Point c){
    b -= a; c -= a;
    if(cross(b, c) > EPS) return COUNTER_CLOCKWISE;
    if(cross(b, c) < -EPS) return CLOCKWISE;
    if(dot(b, c) < 0) return ONLINE_BACK;
    if(abs(b) < abs(c)) return ONLINE_FRONT;
    return ON_SEGMENT;
}
struct Segment {
    Point a, b;
    Segment(Point x, Point y) : a(x), b(y) {};
};

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

struct Circle{
    Point c; real r;
    Circle(Point c, real r): c(c), r(r) {};
};

using Polygon = vector<Point>;

bool intersect(Segment s, 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(Segment s, Line t){
    int a = ccw(t.a, t.b, s.a), b = ccw(t.a, t.b, s.b);
    return (!(a&1) || !(b&1) || a != b);
}

Point polar(double r, double t){
    return Point(r*cos(t), r*sin(t));
}

double arg(Point p){
    return atan2(p.y, p.x);
}

static constexpr int CONTAIN = 0;
static constexpr int INSCRIBE = 1;
static constexpr int INTERSECT = 2;
static constexpr int CIRCUMSCRIBED = 3;
static constexpr int SEPARATE = 4;

int intersect(Circle c1, Circle c2){
    if(c1.r < c2.r) swap(c1, c2);
    real d = abs(c1.c-c2.c);
    real r = c1.r + c2.r;
    if(fabs(d-r) < EPS) return CIRCUMSCRIBED;
    if(d > r) return SEPARATE;
    if(fabs(d+c2.r-c1.r) < EPS) return INSCRIBE;
    if(d+c2.r < c1.r) return CONTAIN;
    return INTERSECT;
}

real distance(Line l, Point c){
    return abs(cross(l.b-l.a, c-l.a)/abs(l.b-l.a));
}


real distance(Segment s, Point c){
    if(dot(s.b-s.a, c-s.a) < EPS) return abs(c-s.a);
    if(dot(s.a-s.b, c-s.b) < EPS) return abs(c-s.b);
    return abs(cross(s.b-s.a, c-s.a)) / abs(s.a-s.b);
}

real distance(Segment s, Segment t){
    if(intersect(s, t)) return 0.0;
    return min({distance(s, t.a), distance(s, t.b),
                distance(t, s.a), distance(t, s.b)});
}


Point project(Line l, Point p){
    Point Q = l.b-l.a;
    return l.a + Q*(dot(p-l.a, Q) / dot(Q, Q));
}


Point project(Segment s, Point p){
    Point Q = s.b-s.a;
    return s.a + Q*(dot(p-s.a, Q) / dot(Q, Q));
}

Point refrect(Segment s, Point p){
    Point Q = project(s, p);
    return Q*2-p;
}

bool isOrthogonal(Segment s, Segment t){
    return fabs(dot(s.b-s.a, t.b-t.a)) < EPS;
}

bool isparallel(Segment s, Segment t){
    return fabs(cross(s.b-s.a, t.b-t.a)) < EPS;
}


Point crossPoint(Segment s, Segment t){
    real d1 = cross(s.b-s.a, t.b-t.a);
    real d2 = cross(s.b-s.a, s.b-t.a);
    if(fabs(d1) < EPS && fabs(d2) < EPS) return t.a;
    return t.a+(t.b-t.a)*d2/d1;
}

Point crossPoint(Line s, Line t){
    real d1 = cross(s.b-s.a, t.b-t.a);
    real d2 = cross(s.b-s.a, s.b-t.a);
    if(fabs(d1) < EPS && fabs(d2) < EPS) return t.a;
    return t.a+(t.b-t.a)*d2/d1;
}

Polygon crossPoint(Circle c, Line l){
    Point p = project(l, c.c), q = (l.b-l.a)/abs(l.b-l.a);
    if(abs(distance(l, c.c)-c.r) < EPS){
        return {p};
    }
    double k = sqrt(c.r*c.r-dot(p-c.c, p-c.c));
    return {p-q*k, p+q*k};
}

Polygon crossPoint(Circle c, Segment s){
    auto tmp = crossPoint(c, Line(s.a, s.b));
    Polygon ret;
    for (auto &&i : tmp) {
        if(distance(s, i) < EPS) ret.emplace_back(i);
    }
    return ret;
}


Polygon crossPoint(Circle c1, Circle c2){
    double d = abs(c1.c-c2.c);
    double a = acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t = arg(c2.c-c1.c);
    return {c1.c+polar(c1.r, t+a), c1.c+polar(c1.r, t-a)};
}

Polygon tangent(Circle c1, Point p){
    Circle c2 = Circle(p, sqrt(dot(c1.c-p, c1.c-p)-c1.r*c1.r));
    return crossPoint(c1, c2);
}
vector<Line> tangent(Circle c1, Circle c2){
    vector<Line> ret;
    if(c1.r < c2.r) swap(c1, c2);
    double k = dot(c1.c-c2.c, c1.c-c2.c);
    if(abs(k) < EPS) return {};
    Point u = (c2.c-c1.c)/sqrt(k);
    Point v(-u.y, u.x);
    for (auto &&i : {-1, 1}) {
        double h = (c1.r+i*c2.r)/sqrt(k);
        if(abs(h*h-1) < EPS){
            ret.emplace_back(c1.c+u*c1.r, c1.c+(u+v)*c1.r);
        }else if(h*h < 1){
            Point u2 = u*h, v2 = v*sqrt(1-h*h);
            ret.emplace_back(c1.c+(u2+v2)*c1.r, c2.c-(u2+v2)*c2.r*i);
            ret.emplace_back(c1.c+(u2-v2)*c1.r, c2.c-(u2-v2)*c2.r*i);
        }
    }
    return ret;
}

real area(Polygon v){
    if(v.size() < 3) return 0.0;
    real ans = 0.0;
    for (int i = 0; i < v.size(); ++i) {
        ans += cross(v[i], v[(i+1)%v.size()]);
    }
    return ans/2;
}

real area(Circle c, Polygon &v){
    int n = v.size();
    real ans = 0.0;
    Polygon u;
    for (int i = 0; i < n; ++i) {
        u.emplace_back(v[i]);
        auto q = crossPoint(c, Segment(v[i], v[(i+1)%n]));
        for (auto &&j : q) {
            u.emplace_back(j);
        }
    }
    for (int i = 0; i < u.size(); ++i) {
        Point A = u[i]-c.c, B = u[(i+1)%u.size()]-c.c;
        if(abs(A) >= c.r+EPS || abs(B) >= c.r+EPS){
            Point C = polar(1, arg(B)-arg(A));
            ans += c.r*c.r*arg(C)/2;
        }else {
            ans += cross(A, B)/2;
        }
    }
    return ans;
}

Polygon convex_hull(Polygon v){
    int n = v.size();
    sort(v.begin(),v.end(), sorty);
    int k = 0;
    Polygon ret(n*2);
    for (int i = 0; i < n; ++i) {
        while(k > 1 && cross(ret[k-1]-ret[k-2], v[i]-ret[k-1]) < 0) k--;
        ret[k++] = v[i];
    }
    for(int i = n-2, t=k; i >= 0; i--){
        while(k > t && cross(ret[k-1]-ret[k-2], v[i]-ret[k-1]) < 0) k--;
        ret[k++] = v[i];
    }
    ret.resize(k-1);
    return ret;
}

bool isconvex(Polygon v){
    int n = v.size();
    for (int i = 0; i < n; ++i) {
        if(ccw(v[(i+n-1)%n], v[i], v[(i+1)%n]) == CLOCKWISE) return false;
    }
    return true;
}

int contains(Polygon v, Point p){
    int n = v.size();
    bool x = false;
    static constexpr int IN = 2;
    static constexpr int ON = 1;
    static constexpr int OUT = 0;
    for (int i = 0; i < n; ++i) {
        Point a = v[i]-p, b = v[(i+1)%n]-p;
        if(fabs(cross(a, b)) < EPS && dot(a, b) < EPS) return ON;
        if(a.y > b.y) swap(a, b);
        if(a.y < EPS && EPS < b.y && cross(a, b) > EPS) x = !x;
    }
    return (x?IN:OUT);
}

real diameter(Polygon v){
    int n = v.size();
    if(n == 2) return abs(v[0]-v[1]);
    int i = 0, j = 0;
    for (int k = 0; k < n; ++k) {
        if(v[i] < v[k]) i = k;
        if(!(v[j] < v[k])) j = k;
    }
    real ret = 0;
    int si = i, sj = j;
    while(i != sj || j != si){
        ret = max(ret, abs(v[i]-v[j]));
        if(cross(v[(i+1)%n]-v[i], v[(j+1)%n]-v[j]) < 0.0) i = (i+1)%n;
        else j = (j+1)%n;
    }
    return ret;
}

Polygon convexCut(Polygon v, Line l){
    Polygon q;
    int n = v.size();
    for (int i = 0; i < n; ++i) {
        Point a = v[i], b = v[(i+1)%n];
        if(ccw(l.a, l.b, a) != -1) q.push_back(a);
        if(ccw(l.a, l.b, a)*ccw(l.a, l.b, b) < 0){
            q.push_back(crossPoint(Line(a, b), l));
        }
    }
    return q;
}

real closest_pair(Polygon &v, int l = 0, int r = -1){
    if(!(~r)){
        r = v.size();
        sort(v.begin(),v.end());
    }
    if(r - l < 2) {
        return abs(v.front()-v.back());
    }
    int mid = (l+r)/2;
    real p = v[mid].x;
    real d = min(closest_pair(v, l, mid), closest_pair(v, mid, r));
    inplace_merge(v.begin()+l, v.begin()+mid, v.begin()+r, sorty);
    Polygon u;
    for (int i = l; i < r; ++i) {
        if(fabs(v[i].x-p) >= d) continue;
        for (int j = 0; j < u.size(); ++j) {
            real dy = v[i].y-next(u.rbegin(), j)->y;
            if(dy >= d) break;
            d = min(d, abs(v[i]-*next(u.rbegin(), j)));
        }
        u.emplace_back(v[i]);
    }
    return d;
}

int main() {
    int n;
    while(cin >> n, n){
        vector<Point> ps(n);
        for (int i = 0; i < n; ++i) {
            scanf("%lg,%lg", &ps[i].x, &ps[i].y);
        }
        vector<Circle> v;
        v.reserve(n);
        for (int i = 0; i < n; ++i) {
            v.emplace_back(ps[i], 1);
        }
        vector<Point> kouten;
        for (int i = 0; i < n; ++i) {
            for (int j = 1; j < n; ++j) {
                auto p = crossPoint(v[i], v[j]);
                for (auto &&l : p) {
                    kouten.emplace_back(l);
                }
            }
            kouten.emplace_back(v[i].c);
        }
        int ans = 0;
        for (auto &&p : kouten) {
            int val = 0;
            for (int i = 0; i < n; ++i) {
                if(abs(v[i].c-p) <= v[i].r + EPS) val++;
            }
            ans = max(ans, val);
        }
        printf("%d\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4272
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
constexpr ll MOD = 1e9 + 7;
constexpr ll INF = 1e+18;
constexpr ld EPS = 1e-12L;
constexpr ld PI = 3.14159265358979323846L;

// https://prefield.com/algorithm/geometry

// point
using P = complex<ld>;

// two points: line
using L = array<P, 2>;

// points
using VP = vector<P>;

// circle
struct C {
  P c;
  ld r;
  C(const P &c_, ld r_) : c(c_), r(r_) {}
  C(ld x_, ld y_, ld r_) : c({x_, y_}), r(r_) {}
};

using VC = vector<C>;

// input
void Pin(P &a) {
  ld tmp;
  cin >> tmp;
  a.real(tmp);
  cin >> tmp;
  a.imag(tmp);
}

// output
void Pout(const P &a) {
  cout << a.real() << " " << a.imag();
}

namespace std {
  /*
  bool operator<(const P& a, const P& b) {
    return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
  }
  /*/
  bool operator<(const P &a, const P &b) {
    return arg(a) < arg(b);
  }
  //*/
} // namespace std

ld cross(const P &a, const P &b) {
  return imag(conj(a) * b);
}

ld dot(const P &a, const P &b) {
  return real(conj(a) * b);
}

// a->b->cの進行方向
int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)   return  1; // counterclockwise a--b\\c
  if (cross(b, c) < 0)   return -1; // clockwise        a--b//c
  if (dot(b, c) < 0)     return  2; // c--a--b on line
  if (norm(b) < norm(c)) return -2; // a--b--c on line
  return 0;                         // a--c--b on line
}

// 直線-直線交差判定
bool intersectLL(const L& l, const L& m) {
  return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS // non-parallel
  || abs(cross(l[1] - l[0], m[1] - l[0])) < EPS;    // same line
}

// 直線-線分交差判定
bool intersectLS(const L& l, const L& s) {
  return cross(l[1] - l[0], s[0] - l[0]) * // s[0] is left of l
  cross(l[1] - l[0], s[1] - l[0]) < EPS;   // s[1] is right of l
}

// 線分-線分交差判定
bool intersectSS(const L& s, const L& t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0
  && ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}

// 点∈直線の判定
bool intersectLP(const L& l, const P& p) {
  return abs(cross(l[1] - p, l[0] - p)) < EPS;
}

// 点∈線分の判定
bool intersectSP(const L& s, const P& p) {
  // triangle inequality
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}

// 点の直線への射影
P projection(const L& l, const P& p) {
  ld t = dot(p - l[0], l[1] - l[0]) / norm(l[1] - l[0]);
  return l[0] + t * (l[1] - l[0]);
}

// 点の直線に対する鏡映
P reflection(const L& l, const P& p) {
  return p + (projection(l, p) - p) * 2.L;
}

// 点-直線の距離
ld distanceLP(const L &l, const P &p) {
  return abs(p - projection(l, p));
}

// 直線-直線の距離 非平行か同一なら0
ld distanceLP(const L &l, const L &m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}

// 直線-線分の距離
ld distanceLS(const L& l, const L& s) {
  return intersectLS(l, s) ? 0 : min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}

// 点-線分の距離
ld 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[0] - p), abs(s[1] - p));
}

// 線分-線分の距離
ld distanceSS(const L& s, const L& t) {
  if (intersectSS(s, t)) return 0;
  return min({distanceSP(s, t[0]),
              distanceSP(s, t[1]),
              distanceSP(t, s[0]),
              distanceSP(t, s[1])});
}

// 2直線の交点 平行な場合は例外
P crosspoint(const L &l, const L &m) {
  ld A = cross(l[1] - l[0], m[1] - m[0]);
  ld B = cross(l[1] - l[0], l[1] - m[0]);
  assert(abs(A) >= EPS);
  return m[0] + B / A * (m[1] - m[0]);
}

// 2円の交点 一致する場合は例外
VP crosspoint(C a, C b) {
  ld dist = abs(a.c - b.c);
  ld rdist = abs(a.r - b.r);
  assert(dist >= EPS || rdist >= EPS);
  // 外接する
  if(abs(dist - (a.r + b.r)) < EPS){
    return {(b.r*a.c + a.r*b.c) / (a.r + b.r)};
  }
  // 内接する
  if(abs(dist - rdist) < EPS){
    return {(-b.r*a.c + a.r*b.c) / (a.r - b.r)};
  }
  // 離れている、内包する
  if(dist > a.r + b.r || dist < rdist){
    return {};
  }
  // 交わる 中心を0と1に規格化
  // 最後に足す
  P movp = a.c;
  a.c = {0.L, 0.L};
  b.c -= movp;
  // 最後に掛ける
  P movm = b.c;
  b.c = {1.L, 0.L};
  a.r /= abs(movm);
  b.r /= abs(movm);
  ld x = (a.r*a.r - b.r*b.r + 1)/2;
  ld y = sqrt(a.r*a.r - x*x);
  P cr1 = {x, y};
  P cr2 = {x, -y};
  cr1 = cr1 * movm + movp;
  cr2 = cr2 * movm + movp;
  // 元に戻す
  return {cr1, cr2};
}

// 円盤の最大の重なり O(n^3)
ll maxOverlap(const VC &vc){
  ll n = vc.size();
  if(!n) return 0;
  ll ret = 1;
  VP pts;
  for(auto&& e: vc){
    pts.emplace_back(e.c);
  }
  for(int i = 0; i < n; i++){
    for(int j = 0; j < i; j++){
      VP cp = crosspoint(vc[i], vc[j]);
      pts.insert(pts.end(), cp.begin(), cp.end());
    }
  }
  for(auto&& e: pts){
    ll tmp = 0;
    for(auto&& ee: vc){
      tmp += (abs(e - ee.c) < ee.r + EPS);
    }
    if(ret < tmp) ret = tmp;
  }
  return ret;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);
  ll n;
  while(cin >> n, n){
    VC vc;
    for(int i = 0; i < n; i++){
      ld x, y;
      char ch;
      cin >> x >> ch >> y;
      vc.emplace_back(x, y, 1.L);
    }
    cout << maxOverlap(vc) << "\n";
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3364
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

struct point {
  double x, y;
};

int main() {
  int n;
  while (cin >> n, n) {
    vector<point> ps(n);
    for (int i = 0; i < n; ++i)
      scanf("%lf,%lf", &ps[i].x, &ps[i].y);

    int cntmax = 0;
    for (int i = 0; i < 1000; ++i) {
      for (int j = 0; j < 1000; ++j) {
        double x = i * 0.01;
        double y = j * 0.01;
        int cnt = 0;
        auto f = [&](auto &v) { cnt += pow(v.x - x, 2) + pow(v.y - y, 2) <= 1; };
        for_each(ps.begin(), ps.end(), f);
        cntmax = (cntmax < cnt) ? cnt : cntmax;
      }
    }
    cout << cntmax << endl;
  }
}
accuracy: 1
time_ms: 410
memory_kb: 3224
final_rank: 10

code_snippet: #include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

struct Point{
	double x,y;
};

int main(){
	
	int n, ans, count;
	Point seal[100];
	
	while(cin >> n){
		if(n == 0) break;
		
		for(int i = 0; i < n; i++){
			scanf("%lf,%lf",&seal[i].x,&seal[i].y);
		}
		
		ans = -1;
		for(double i = 0; i <= 10; i += 0.1){
			for(double j = 0; j <= 10; j +=0.1){
				count = 0;
				for(int s = 0; s < n; s++){
					if(sqrt((i-seal[s].x)*(i-seal[s].x)+(j-seal[s].y)*(j-seal[s].y)) < 1 ||
							fabs(sqrt((i-seal[s].x)*(i-seal[s].x)+(j-seal[s].y)*(j-seal[s].y)) - 1) < 0.00000001){
						count++;
					}
				}
				if(ans < count) ans = count;
			}
		}
	
		cout << ans << endl;
	
	}
	
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3156
final_rank: 2

code_snippet: #include <stdio.h>
#include <vector>
#include <algorithm>
#include <math.h>
#include <queue>

using namespace std;

struct Point{
	double x,y;
};

int main(){

	int n,max,count;
	Point point[100];

	while(true){
		scanf("%d",&n);
		if(n == 0)break;

		max = 0;

		for(int i = 0; i < n; i++){
			scanf("%lf,%lf",&point[i].x,&point[i].y);
		}

		for(double i = 0; i <= 10; i += 0.1){
			for(double k = 0; k <= 10; k+=0.1){
				count = 0;
				for(int p = 0; p < n; p++){
					if(sqrt((i-point[p].x)*(i-point[p].x)+(k-point[p].y)*(k-point[p].y)) < 1 ||
							fabs(sqrt((i-point[p].x)*(i-point[p].x)+(k-point[p].y)*(k-point[p].y))-1) < 0.00000001){
						count++;
					}
				}
				max = (max >= count)?max:count;
			}
		}

		printf("%d\n",max);

	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2632
final_rank: 1

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

using namespace std;

int mapData[10][10];

int main() {
	int n,tmp,sum;
	double x[100], y[100];
	char c;

	ios::sync_with_stdio(false);
	cin.tie(0);
	while (cin >> n, n) {
		for (int i = 0; i < n; i++) {
			cin >> x[i] >> c >> y[i];
		}

		sum = 0;
		for (double a = 0; (a-10) < 0.0001; a += 0.01) {
			for (double b = 0; (b-10) < 0.0001; b += 0.01) {
				tmp = 0;
				for (int i = 0; i < n; i++) {
					if( pow((a - x[i]), 2) + pow((b - y[i]), 2) - 1 < 0.0001) {
						tmp++;
					}
				}
				sum = max(sum, tmp);
			}
		}
		cout << sum << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 3168
final_rank: 18

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

using namespace std;

int mapData[10][10];

int main() {
	int n,tmp,sum;
	double x[100], y[100];
	char c;

	ios::sync_with_stdio(false);
	cin.tie(0);
	while (cin >> n, n) {
		for (int i = 0; i < n; i++) {
			cin >> x[i] >> c >> y[i];
		}

		sum = 0;
		for (double a = 0.0; a < 10; a += 0.01) {
			for (double b = 0.0; b < 10; b += 0.01) {
				tmp = 0;
				for (int i = 0; i < n; i++) {
					if (pow((a - x[i]), 2) + pow((b - y[i]), 2) < 1.0001) {
						tmp++;
					}
				}
				sum = max(sum, tmp);
			}
		}
		cout << sum << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 3180
final_rank: 17

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

using namespace std;

int mapData[10][10];

int main() {
	int n,tmp,sum;
	double x[100], y[100];
	char c;

	ios::sync_with_stdio(false);
	cin.tie(0);
	while (cin >> n, n) {
		for (int i = 0; i < n; i++) {
			cin >> x[i] >> c >> y[i];
		}

		sum = 0;
		for (double a = 0.0; a < 10; a += 0.01) {
			for (double b = 0.0; b < 10; b += 0.01) {
				tmp = 0;
				for (int i = 0; i < n; i++) {
					if (pow((a - x[i]), 2) + pow((b - y[i]), 2) < 1.01) {
						tmp++;
					}
				}
				sum = max(sum, tmp);
			}
		}
		cout << sum << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 3088
final_rank: 12

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

#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for (int i = x; i < n; i++)
#define OP(m) cout << m << endl
typedef long long ll;
typedef unsigned long long ull;

typedef struct circle
{
    double x, y;
} cir;

int main()
{
    int n;
    while (cin >> n, n)
    {
        cir c[n];
        char ch;
        rep(i, n) cin >> c[i].x >> ch >> c[i].y;

        int maxv = 0;

        for (double i = 0; i <= 10; i += 0.1)
        {
            for (double j = 0; j <= 10; j += 0.01)
            {
                int cnt = 0;
                rep(k, n)
                {
                    if (sqrt(pow(i - c[k].x, 2) + (pow(j - c[k].y, 2)) <= 1.001))
                        cnt++;
                }
                maxv = max(maxv, cnt);
            }
        }
        OP(maxv);
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3056
final_rank: 4

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

#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for (int i = x; i < n; i++)
#define OP(m) cout << m << endl
typedef long long ll;
typedef unsigned long long ull;

typedef struct circle
{
    double x, y;
} cir;

int main()
{
    int n;
    while (cin >> n, n)
    {
        cir c[n];
        char ch;
        rep(i, n) cin >> c[i].x >> ch >> c[i].y;

        int maxv = 0;

        for (double i = 0; i <= 10; i += 0.05)
        {
            for (double j = 0; j <= 10; j += 0.05)
            {
                int cnt = 0;
                rep(k, n)
                {
                    if (sqrt(pow(i - c[k].x, 2) + (pow(j - c[k].y, 2)) <= 1.001))
                        cnt++;
                }
                maxv = max(maxv, cnt);
            }
        }
        OP(maxv);
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3184
final_rank: 3

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
double x[100],y[100];
int main(){
    int n;
    while(1){
        scanf("%d",&n);
        if(n==0)    break;
        for(int i=0;i<n;i++)
            scanf("%lf,%lf\n",&x[i],&y[i]);
        int ans=0;
        for(double a=0;a<=10.1;a+=0.01)
            for(double b=0;b<=10.1;b+=0.01){
                int t=0;
                for(int i=0;i<n;i++)
                    if((a-x[i])*(a-x[i])+(b-y[i])*(b-y[i])<=1.001)
                        t++;
                ans=max(ans,t);
            }
        printf("%d\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 3168
final_rank: 9

code_snippet: #include<iostream>
using namespace std;
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<iomanip>
const double EPS=1e-10;
bool eq(double a,double b){return abs(a-b)<EPS;}
struct Point{
	double x,y;
	Point(double x_=0,double y_=0):x(x_),y(y_){}
	Point operator-()const{return Point(-x,-y);}
	Point operator+(const Point&p)const{return Point(x+p.x,y+p.y);}
	Point operator-(const Point&p)const{return Point(x-p.x,y-p.y);}
	Point operator*(const double k)const{return Point(x*k,y*k);}
	Point operator/(const double k)const{return Point(x/k,y/k);}
	bool operator<(const Point&p)const{return eq(x,p.x)?y<p.y:x<p.x;}
	bool operator==(const Point&p)const{return eq(x,p.x)&&eq(y,p.y);}
};
istream&operator>>(istream&is,Point&p){return is>>p.x>>p.y;}
ostream&operator<<(ostream&os,const Point&p){return os<<fixed<<setprecision(9)<<p.x<<' '<<p.y;}
struct Line{
	Point p1,p2;
	Line(Point p1_=Point(),Point p2_=Point()):p1(p1_),p2(p2_){}
};
struct Segment:Line{
	Segment(Point p1_=Point(),Point p2_=Point()):Line(p1_,p2_){}
};
struct Circle{
	Point o;
	double r;
	Circle(Point o_=Point(),double r_=0):o(o_),r(r_){}
};
using Polygon=vector<Point>;
//function list begin
Point vec(const Line&);
double norm(const Point&);
double norm(const Line&);
double abs(const Point&);
double abs(const Line&);
double arg(const Point&);
double arg(const Line&);
double arg(const Point&,const Point&,const Point&);//a->b->c
double dot(const Point&,const Point&);
double cross(const Point&,const Point&);
Point polar(const double,const double);
Point rotate(const Point&,const double);
enum{ONLINE_FRONT=-2,CLOCKWISE=-1,ON_SEGMENT=0,COUNTER_CLOCKWISE=1,ONLINE_BACK=2};
int ccw(const Point&,const Point&,const Point&);
int ccw(const Line&,const Point&);
bool orthogonal(const Point&,const Point&);
bool orthogonal(const Line&,const Line&);
bool parallel(const Point&,const Point&);
bool parallel(const Line&,const Line&);
bool intersect(const Line&,const Point&);
bool intersect(const Line&,const Line&);
bool intersect(const Segment&,const Point&);
bool intersect(const Segment&,const Segment&);
bool intersect(const Line&,const Segment&);
bool intersect(const Segment&,const Line&);
bool intersect(const Circle&,const Point&);
int intersect(const Circle&,const Line&);//count contacts
int intersect(const Circle&,const Segment&);
int intersect(const Circle&,const Circle&);//count common tangents
double distance(const Point&,const Point&);
double distance(const Line&,const Point&);
double distance(const Line&,const Line&);
double distance(const Segment&,const Point&);
double distance(const Segment&,const Segment&);
double distance(const Line&,const Segment&);
double distance(const Segment&,const Line&);
double distance(const Circle&,const Point&);
double distance(const Circle&,const Line&);
double distance(const Circle&,const Segment&);
double distance(const Circle&,const Circle&);
Point projection(const Line&,const Point&);
Point reflection(const Line&,const Point&);
Point crosspoint(const Line&,const Line&);
pair<Point,Point>crosspoint(const Circle&,const Line&);
pair<Point,Point>crosspoint(const Circle&,const Segment&);
pair<Point,Point>crosspoint(const Circle&,const Circle&);
pair<Point,Point>tangent(const Circle&,const Point&);
vector<Line>tangent(const Circle&,const Circle&);
bool is_convex(const Polygon&);
Polygon convex_full(Polygon,bool=false);
enum{OUT,ON,IN};
int contain(const Polygon&,const Point&);
int contain(const Circle&,const Point&);
int contain(const Circle&,const Segment&);
Polygon convex_cut(const Polygon&,const Line&);
double diameter(Polygon);
double area(const Polygon&);
double area(const Polygon&,const Line&);
double area(const Polygon&,const Circle&);
//function list end
Point vec(const Line&s){return s.p2-s.p1;}
double norm(const Point&p){return p.x*p.x+p.y*p.y;}
double norm(const Line&s){return norm(vec(s));}
double abs(const Point&p){return hypot(p.x,p.y);}
double abs(const Line&s){return abs(vec(s));}
double arg(const Point&p){return atan2(p.y,p.x);}
double arg(const Line&s){return arg(vec(s));}
double arg(const Point&a,const Point&b,const Point&c){
	double A=arg(b-a),B=arg(c-b);
	double theta=abs(A-B);
	return min(theta,2*M_PI-theta);
}
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;}
Point polar(const double r,const double theta){return Point(cos(theta),sin(theta))*r;}
Point rotate(const Point&p,const double theta){
	return Point(p.x*cos(theta)-p.y*sin(theta),p.x*sin(theta)+p.y*cos(theta));
}
int ccw(const Point&a,const Point&b,const Point&c){
	Point p=b-a,q=c-a;
	return cross(p,q)>EPS?COUNTER_CLOCKWISE
		:cross(p,q)<-EPS?CLOCKWISE
		:dot(p,q)<0?ONLINE_BACK
		:norm(p)<norm(q)?ONLINE_FRONT
		:ON_SEGMENT;
}
int ccw(const Line&s,const Point&p){return ccw(s.p1,s.p2,p);}
bool orthogonal(const Point&a,const Point&b){return eq(dot(a,b),0);}
bool orthogonal(const Line&s,const Line&t){return orthogonal(vec(s),vec(t));}
bool parallel(const Point&a,const Point&b){return eq(cross(a,b),0);}
bool parallel(const Line&s,const Line&t){return parallel(vec(s),vec(t));}
bool intersect(const Line&s,const Point&p){return eq(cross(vec(s),p-s.p1),0);}
bool intersect(const Line&s,const Line&t){return !parallel(s,t)||intersect(s,t.p1);}
bool intersect(const Segment&s,const Point&p){return ccw(s,p)==ON_SEGMENT;}
bool intersect(const Segment&s,const Segment&t){
	return ccw(s,t.p1)*ccw(s,t.p2)<=0&&ccw(t,s.p1)*ccw(t,s.p2)<=0;
}
bool intersect(const Line&s,const Segment&t){
	return cross(vec(s),t.p1-s.p1)*cross(vec(s),t.p2-s.p1)<EPS;
}
bool intersect(const Segment&s,const Line&t){return intersect(t,s);}
bool intersect(const Circle&c,const Point&p){return eq(distance(c.o,p),c.r);}
int intersect(const Circle&c,const Line&s){
	double d=distance(s,c.o);
	return eq(d,c.r)?1:d<c.r?2:0;
}
int intersect(const Circle&c,const Segment&s){
	Point h=projection(s,c.o);
	double d1=distance(c.o,s.p1),d2=distance(c.o,s.p2);
	return distance(c.o,h)>c.r+EPS?0
		:d1<c.r-EPS&&d2<c.r-EPS?0
		:d1<c.r-EPS&&d2>c.r-EPS||d1>c.r-EPS&&d2<c.r-EPS?1
		:intersect(s,h)?eq(distance(c.o,h),c.r)?1:2
		:0;
}
int intersect(const Circle&a,const Circle&b){
	double d=distance(a.o,b.o);
	return eq(d,a.r+b.r)?3:d>a.r+b.r?4:eq(d,abs(a.r-b.r))?1:d>abs(a.r-b.r)?2:0;
}
double distance(const Point&a,const Point&b){return abs(a-b);}
double distance(const Line&s,const Point&p){return distance(p,projection(s,p));}
double distance(const Line&s,const Line&t){return intersect(s,t)?0:distance(s,t.p1);}
double distance(const Segment&s,const Point&p){
	return distance(p,
		dot(vec(s),p-s.p1)<0?s.p1
		:dot(-vec(s),p-s.p2)<0?s.p2
		:projection(s,p)
	);
}
double distance(const Segment&s,const Segment&t){
	return intersect(s,t)?0:min({
		distance(s,t.p1),distance(s,t.p2),
		distance(t,s.p1),distance(t,s.p2)
	});
}
double distance(const Line&s,const Segment&t){
	return intersect(s,t)?0:min(distance(s,t.p1),distance(s,t.p2));
}
double distance(const Segment&s,const Line&t){return distance(t,s);}
double distance(const Circle&c,const Point&p){return abs(distance(c.o,p)-c.r);}
double distance(const Circle&c,const Line&s){return max(distance(s,c.o)-c.r,0.);}
double distance(const Circle&c,const Segment&s){
	return intersect(c,s)?0
		:contain(c,s)?c.r-max(distance(c.o,s.p1),distance(c.o,s.p2))
		:distance(s,c.o)-c.r;
}
double distance(const Circle&a,const Circle&b){return max(distance(a.o,b.o)-a.r-b.r,0.);}
Point projection(const Line&s,const Point&p){
	return s.p1+vec(s)*dot(p-s.p1,vec(s))/norm(s);
}
Point reflection(const Line&s,const Point&p){return projection(s,p)*2-p;}
Point crosspoint(const Line&s,const Line&t){
	double d1=abs(cross(vec(s),t.p1-s.p1));
	double d2=abs(cross(vec(s),t.p2-s.p1));
	return t.p1+vec(t)*(d1/(d1+d2));
}
pair<Point,Point>crosspoint(const Circle&c,const Line&s){
	Point h=projection(s,c.o);
	Point e=vec(s)/abs(s)*sqrt(c.r*c.r-norm(h-c.o));
	return minmax(h-e,h+e);
}
pair<Point,Point>crosspoint(const Circle&c,const Segment&s){
	pair<Point,Point>p=crosspoint(c,Line(s));
	return intersect(c,s)==2?p
		:intersect(s,p.first)?make_pair(p.first,p.first)
		:make_pair(p.second,p.second);
}
pair<Point,Point>crosspoint(const Circle&a,const Circle&b){
	double d=distance(a.o,b.o);
	double alpha=acos((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d));
	double theta=arg(b.o-a.o);
	return minmax(a.o+polar(a.r,theta+alpha),a.o+polar(a.r,theta-alpha));
}
pair<Point,Point>tangent(const Circle&c,const Point&p){
	return crosspoint(c,Circle(p,sqrt(norm(c.o-p)-c.r*c.r)));
}
vector<Line>tangent(const Circle&a,const Circle&b){
	vector<Line>ret;
	double g=distance(a.o,b.o);
	if(eq(g,0))return ret;
	Point u=(b.o-a.o)/g;
	Point v=rotate(u,M_PI/2);
	for(int s:{-1,1}){
		double h=(a.r+b.r*s)/g;
		if(eq(h*h,1))ret.emplace_back(a.o+(h>0?u:-u)*a.r,a.o+(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.o+(U+V)*a.r,b.o-(U+V)*b.r*s);
			ret.emplace_back(a.o+(U-V)*a.r,b.o-(U-V)*b.r*s);
		}
	}
	return ret;
}
bool is_convex(const Polygon&P){
	for(int i=0;i<P.size();i++)
		if(ccw(P[i],P[(i+1)%P.size()],P[(i+2)%P.size()])==CLOCKWISE)return false;
	return true;
}
Polygon convex_full(Polygon P,bool ONSEG){
	if(P.size()<=2)return P;
	sort(P.begin(),P.end());
	Polygon ret(2*P.size());
	int k=0,t;
	if(ONSEG){
		for(const Point&p:P){
			while(k>=2&&ccw(ret[k-2],ret[k-1],p)==CLOCKWISE)k--;
			ret[k++]=p;
		}
		t=k;
		for(int i=P.size()-2;i>=0;i--){
			while(k>=t+1&&ccw(ret[k-2],ret[k-1],P[i])==CLOCKWISE)k--;
			ret[k++]=P[i];
		}
	}
	else{
		for(const Point&p:P){
			while(k>=2&&ccw(ret[k-2],ret[k-1],p)!=COUNTER_CLOCKWISE)k--;
			ret[k++]=p;
		}
		t=k;
		for(int i=P.size()-2;i>=0;i--){
			while(k>=t+1&&ccw(ret[k-2],ret[k-1],P[i])!=COUNTER_CLOCKWISE)k--;
			ret[k++]=P[i];
		}
	}
	ret.resize(k-1);
	int mi=0;
	for(int i=1;i<k-1;i++)
		if(eq(ret[mi].y,ret[i].y)?ret[mi].x>ret[i].x:ret[mi].y>ret[i].y)mi=i;
	rotate(ret.begin(),ret.begin()+mi,ret.end());
	return ret;
}
int contain(const Polygon&P,const Point&p){
	bool in=false;
	for(int i=0;i<P.size();i++){
		Segment s(P[i],P[(i+1)%P.size()]);
		if(intersect(s,p))return ON;
		else{
			Point a=s.p1-p,b=s.p2-p;
			if(a.y>b.y)swap(a,b);
			if(a.y<EPS&&EPS<b.y&&cross(a,b)>EPS)in=!in;
		}
	}
	return in?IN:OUT;
}
int contain(const Circle&c,const Point&p){
	double d=distance(c.o,p);
	return eq(d,c.r)?ON:d<c.r?IN:OUT;
}
int contain(const Circle&c,const Segment&s){
	double d1=distance(c.o,s.p1),d2=distance(c.o,s.p2);
	return d1<c.r+EPS&&d2<c.r+EPS?eq(d1,c.r)||eq(d2,c.r)?ON:IN:OUT;
}
Polygon convex_cut(const Polygon&P,const Line&s){
	Polygon ret;
	for(int i=0;i<P.size();i++){
		Segment t(P[i],P[(i+1)%P.size()]);
		if(ccw(s,t.p1)!=CLOCKWISE)ret.push_back(t.p1);
		if(!parallel(s,t)&&!intersect(s,t.p1)
			&&!intersect(s,t.p2)&&intersect(s,t))ret.push_back(crosspoint(s,t));
	}
	return ret;
}
double diameter(Polygon P){
	if(!is_convex(P))P=convex_full(P);
	int mi=0,Mi=0;
	for(int i=1;i<P.size();i++){
		if(P[i].x<P[mi].x)mi=i;
		if(P[i].x>P[Mi].x)Mi=i;
	}
	double ret=0;
	int sm=mi,sM=Mi;
	while(mi!=sM||Mi!=sm){
		ret=max(ret,norm(P[mi]-P[Mi]));
		if(cross(P[(mi+1)%P.size()]-P[mi],P[(Mi+1)%P.size()]-P[Mi])<0)mi=(mi+1)%P.size();
		else Mi=(Mi+1)%P.size();
	}
	return sqrt(ret);
}
double area(const Polygon&P){
	double ret=0;
	for(int i=0;i<P.size();i++)ret+=cross(P[i],P[(i+1)%P.size()]);
	return ret/2;
}
double area(const Polygon&P,const Line&s){return area(convex_cut(P,s));}
double area(const Polygon&P,const Circle&c){
	double ret=0;
	for(int i=0;i<P.size();i++)
	{
		Segment s(P[i],P[(i+1)%P.size()]);
		if(contain(c,s))ret+=cross(s.p1-c.o,s.p2-c.o);
		else if(!intersect(c,s)){
			double a=arg(s.p2-c.o)-arg(s.p1-c.o);
			if(a>M_PI)a-=2*M_PI;
			if(a<-M_PI)a+=2*M_PI;
			ret+=c.r*c.r*a;
		}
		else
		{
			pair<Point,Point>p=crosspoint(c,s);
			Point tmp[4]={s.p1,p.first,p.second,s.p2};
			if(intersect(c,Segment(s.p1,p.first))==2)swap(tmp[1],tmp[2]);
			for(int j=0;j<3;j++)
			{
				Segment t(tmp[j],tmp[j+1]);
				if(contain(c,t))ret+=cross(t.p1-c.o,t.p2-c.o);
				else{
					double a=arg(t.p2-c.o)-arg(t.p1-c.o);
					if(a>M_PI)a-=2*M_PI;
					if(a<-M_PI)a+=2*M_PI;
					ret+=c.r*c.r*a;
				}
			}
		}
	}
	return ret/2;
}
main()
{
	int N;
	while(cin>>N,N)
	{
		Circle c[100];
		char tmp;
		for(int i=0;i<N;i++)
		{
			cin>>c[i].o.x>>tmp>>c[i].o.y;
			c[i].r=1;
		}
		vector<Point>A;
		for(int i=0;i<N;i++)A.push_back(c[i].o);
		for(int i=0;i<N;i++)for(int j=i+1;j<N;j++)
		{
			if(intersect(c[i],c[j]))
			{
				A.push_back(crosspoint(c[i],c[j]).first);
				A.push_back(crosspoint(c[i],c[j]).second);
			}
		}
		int ans=1;
		for(Point p:A)
		{
			int now=0;
			for(int i=0;i<N;i++)now+=contain(c[i],p)!=OUT;
			ans=max(ans,now);
		}
		cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 4080
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef double Real;
typedef complex<Real> P;

bool ishit_circle_segment(P o, Real r, P t, P s){
    // s to origin
    o -= s;
    t -= s;
    // t on x axis
    if(s==t)return false;
    o = (o / t) * abs(t);
    
    Real d = r*r - o.imag()*o.imag();
    if(d < 0.0)return false;
    Real x0 = o.real() + sqrt(d);
    Real x1 = o.real() - sqrt(d);
    Real tb = abs(t);
    if(0.0 <= x0 && x0 <= tb)return true;
    if(0.0 <= x1 && x1 <= tb)return true;
    return false;
}
pair<P,P> hitpoint_circle_circle(P o1,Real r1,P o2,Real r2){
    if(o1==o2 && r1==r2){
        return make_pair(o1,o2);
    }
    // o1 to origin
    o2 -= o1;
    Real x1 = o2.real();
    Real y1 = o2.imag();
    Real a = (x1*x1 + y1*y1 + r1*r1 - r2*r2)/2.0;
    Real d = (x1*x1 + y1*y1)*r1*r1 - a*a;
    if(d < 0.0){
        return make_pair(o1,o2+o1);
    }
    if(x1*x1 + y1*y1 == 0.0){
        return make_pair(o1,o2+o1);
    }
    P hit1 = P((a*x1+y1*sqrt(d))/(x1*x1+y1*y1), (a*y1-x1*sqrt(d))/(x1*x1+y1*y1));
    P hit2 = P((a*x1-y1*sqrt(d))/(x1*x1+y1*y1), (a*y1+x1*sqrt(d))/(x1*x1+y1*y1));
    return make_pair(hit1+o1,hit2+o1);
}
bool inner_circle_point(P o,Real r,P p){
    return abs(p-o)<=r+1e-8;
}

int n;
P ps[125];

int main(void){
    // Here your code !
    while(true){
        scanf("%d",&n);
        if(n==0)break;
        REP(i,n){
            Real x,y;
            scanf("%lf,%lf",&x,&y);
            ps[i] = P(x,y);
        }
        vector<P> check;
        REP(i,n)REP(j,i){
            pair<P,P> t = hitpoint_circle_circle(ps[i],1.0,ps[j],1.0);
            check.push_back(t.first);
            check.push_back(t.second);
        }
        int ans = 1;
        REP(i,check.size()){
            P p = check[i];
            int tmp = 0;
            REP(j,n){
                if(inner_circle_point(ps[j],1.0,p)){
                    tmp++;
                }
            }
            if(tmp > ans){
               // printf("%f %f -> %d\n",p.real(),p.imag(),tmp);
               ans = tmp;
            }
        }
        printf("%d\n",ans);
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3468
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,ans,a;
double x[101],y[101];
int main(){
  while(cin>>n,n){
    ans=0;
    r(i,n)scanf("%lf,%lf",&x[i],&y[i]);
    r(i,1000)r(j,1000){a=0;
      double q=(double)i/100,w=(double)j/100;
      r(k,n)if((x[k]-q)*(x[k]-q)+(y[k]-w)*(y[k]-w)<=1)a++;
      ans=max(a,ans);
    }
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 430
memory_kb: 3160
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,ans;
double x[101],y[101],a[101][101];
int main(){
  while(cin>>n,n){
    ans=0;
    r(i,n)scanf("%lf,%lf",&x[i],&y[i]);
    r(i,1000)r(j,1000){
      int a=0;
      r(k,n)if((x[k]-(double)i/100)*(x[k]-(double)i/100)+(y[k]-(double)j/100)*(y[k]-(double)j/100)<=1)a++;
      ans=max(a,ans);
    }
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 490
memory_kb: 3080
final_rank: 15

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
int n,ans;
double x[101],y[101],a[101][101];
int main(){
  while(cin>>n,n){
    ans=0;
    r(i,n)scanf("%lf,%lf",&x[i],&y[i]);
    r(i,1000)r(j,1000){
      int a=0;
      r(k,n)if((x[k]-(double)i/10)*(x[k]-(double)i/10)+(y[k]-(double)j/10)*(y[k]-(double)j/10)<=1)a++;
      ans=max(a,ans);
    }
    cout<<ans<<endl;
  }
}
accuracy: 1
time_ms: 490
memory_kb: 3076
final_rank: 14

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
using namespace std;

#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define all(v) begin(v), end(v)
#define pb(a) push_back(a)
#define fr first
#define sc second
#define INF 2000000000
#define int long long int

#define X real()
#define Y imag()
#define EPS (1e-12)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) ( EQ((a).X, (b).X) && EQ((a).Y, (b).Y) )
#define LE(n, m) ((n) < (m) + EPS)
#define LEQ(n, m) ((n) <= (m) + EPS)
#define GE(n, m) ((n) + EPS > (m))
#define GEQ(n, m) ((n) + EPS >= (m))

typedef vector<int> VI;
typedef vector<VI> MAT;
typedef pair<int, int> pii;
typedef long long ll;

typedef complex<double> P;
typedef pair<P, P> L;
typedef pair<P, double> C;

int dy[]={0, 0, 1, -1};
int dx[]={1, -1, 0, 0};
int const MOD = 1000000007;

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

double calc(P x, P y) {
    double dx = (x.X - y.X) * (x.X - y.X);
    double dy = (x.Y - y.Y) * (x.Y - y.Y);
    return dx + dy;
}

signed main() {
    int n;
    while(cin >> n, n) {
        vector<P> v(n);
        double x, y;
        int ma = 0;
        rep(i,0,n) {
            scanf("%lf,%lf", &x, &y);
            v[i] = P(x, y);
        }
        for(double i = 0.0; i <= 10.01; i += 0.01) {
            for(double j = 0.0; j <= 10.01; j += 0.01) {
                int cnt = 0;
                rep(k,0,n) if(calc(P(i, j), v[k]) <= 1.0 + EPS) cnt++;
                ma = max(ma, cnt);
            }
        }
        cout << ma << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 3184
final_rank: 11