#include <iostream>
#include <cmath>
#include <vector>
#include <initializer_list>
struct point
{
double x, y;
point(double x, double y) : x(x), y(y) {} // emplace_back() requires this constructor, at least, for g++ 4.5
};
inline double square(double d)
{
return d*d;
}
// Calculate coordinate(s) of crossing point(s) between 2 circles
// (x-x1)^2 + (y-y1)^2 = r1^2 and (x-x2)^2 + (y-y2)^2 = r2^2
std::vector<point> cross_circle(double x1, double y1, double r1, double x2, double y2, double r2)
{
double la = 2 * (x1 - x2), lb = 2 * (y1 -y2), lc = r1*r1 - r2*r2 - x1*x1 + x2*x2 - y1*y1 + y2*y2;
std::vector<point> result;
if(la == 0) {
if(lb == 0) {
if(lc == 0) throw 1; // any point in whole plane can be root.
} else {
double Y = - lc / lb;
double D = r1*r1 - (Y - y1)*(Y- y1);
if(D > 0) {
result.emplace_back(x1 + sqrt(D), Y);
result.emplace_back(x1 - sqrt(D), Y);
} else if(D == 0) {
result.emplace_back(x1, Y);
}
}
} else {
double A = - lb / la, B = - lc / la;
double D = square(2*A*(B-x1)-2*y1)-4*(A*A+1)*((B-x1)*(B-x1)+y1*y1-r1*r1);
if(D > 0) {
result.emplace_back(A*(-2*A*(B-x1)+2*y1+sqrt(D))/2/(1+A*A)+B, (-2*A*(B-x1)+2*y1+sqrt(D))/2/(1+A*A));
result.emplace_back(A*(-2*A*(B-x1)+2*y1-sqrt(D))/2/(1+A*A)+B, (-2*A*(B-x1)+2*y1-sqrt(D))/2/(1+A*A));
} else if(D == 0) {
result.emplace_back(A*(-2*A*(B-x1)+2*y1)/2/(1+A*A)+B, (-2*A*(B-x1)+2*y1)/2/(1+A*A));
}
}
return result;
}
const double THRESHOLD = 0.000001;
inline double distance2(const point &p1, const point &p2)
{
return square(p1.x - p2.x) + square(p1.y - p2.y);
}
inline double distance(const point &p1, const point &p2)
{
return std::sqrt(distance2(p1, p2));
}
inline bool near(const point& p1, const point &p2)
{
return distance2(p1, p2) <= square(THRESHOLD);
}
bool check(int n, double dist, const std::vector<point> &v)
{
for(std::size_t i = 0; i != v.size(); ++i) {
if(distance2({ 0, 0 }, v[i]) > 1 + THRESHOLD) return false; // Not in circle
for(std::size_t j = i + 1; j < v.size(); ++j) {
if(distance2(v[i], v[j]) + THRESHOLD < square(dist)) return false; // Distance unsatisfactory
}
}
return true;
}
bool process(int n, int level, double dist, std::vector<point> &v)
{
if(level == n) {
return check(n, dist, v);
} else if(level == 0) {
v.clear();
v.emplace_back(-1, 0);
return process(n, level+1, dist, v);
} else {
std::vector<point> candidate;
auto is_new = [&](const point &p)->bool {
if(distance2({ 0, 0 }, p) > 1 + THRESHOLD) return false; // Not in circle
for(int j = 0; j < level - 1; ++j) {
if(near(p, v[j])) return false; // Duplicate
if(distance2(p, v[j]) + THRESHOLD < square(dist)) return false; // Distance unsatisfactory
}
for(std::size_t j = 0; j != candidate.size(); ++j) {
if(near(p, candidate[j])) return false; // Duplicate in candidates
}
return true;
};
try {
auto v1 = cross_circle(0, 0, 1, v[level-1].x, v[level-1].y, dist);
if(v1.size() > 1 && level == 1) v1.pop_back(); // vertically symmetric
for(std::size_t i = 0; i != v1.size(); ++i) {
if(is_new(v1[i])) candidate.push_back(v1[i]);
}
} catch(int) {
// When v[level-1].x == v[level-1].y == 0 && dist == 1, exception thrown
// We can simply ignore because candidates are selected by the below criteria
}
for(int i = 0; i < level - 1; ++i) {
auto v2 = cross_circle(v[i].x, v[i].y, dist, v[level-1].x, v[level-1].y, dist);
for(std::size_t j = 0; j != v2.size(); ++j) {
if(is_new(v2[j])) candidate.push_back(v2[j]);
}
}
for(std::size_t i = 0; i != candidate.size(); ++i) {
v.push_back(candidate[i]);
if(process(n, level+1, dist, v)) return true;
v.pop_back();
}
return false;
}
}
int main(void)
{
int n; std::cin >> n;
std::vector<point> result;
double l = THRESHOLD, r = 2.1, t;
for(int i=0;i<30;++i) {
t = (l+r)/2;
if(process(n, 0, t, result)) {
l = t;
} else {
r = t;
}
}
if(process(n, 0, l, result)) {
std::cout << "POSSIBLE: " << l << std::endl;
for(std::size_t i = 0; i != result.size(); ++i) {
std::cout << result[i].x << ',' << result[i].y << std::endl;
}
} else {
std::cout << "IMPOSSIBLE" << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxpbml0aWFsaXplcl9saXN0PgoKc3RydWN0IHBvaW50CnsKCWRvdWJsZSB4LCB5OwoJcG9pbnQoZG91YmxlIHgsIGRvdWJsZSB5KSA6IHgoeCksIHkoeSkge30gLy8gZW1wbGFjZV9iYWNrKCkgcmVxdWlyZXMgdGhpcyBjb25zdHJ1Y3RvciwgYXQgbGVhc3QsIGZvciBnKysgNC41Cn07CgppbmxpbmUgZG91YmxlIHNxdWFyZShkb3VibGUgZCkKewoJcmV0dXJuIGQqZDsKfQoKLy8gQ2FsY3VsYXRlIGNvb3JkaW5hdGUocykgb2YgY3Jvc3NpbmcgcG9pbnQocykgYmV0d2VlbiAyIGNpcmNsZXMKLy8gKHgteDEpXjIgKyAoeS15MSleMiA9IHIxXjIgYW5kICh4LXgyKV4yICsgKHkteTIpXjIgPSByMl4yIApzdGQ6OnZlY3Rvcjxwb2ludD4gY3Jvc3NfY2lyY2xlKGRvdWJsZSB4MSwgZG91YmxlIHkxLCBkb3VibGUgcjEsIGRvdWJsZSB4MiwgZG91YmxlIHkyLCBkb3VibGUgcjIpCnsKCWRvdWJsZSBsYSA9IDIgKiAoeDEgLSB4MiksIGxiID0gMiAqICh5MSAteTIpLCBsYyA9IHIxKnIxIC0gcjIqcjIgLSB4MSp4MSArIHgyKngyIC0geTEqeTEgKyB5Mip5MjsKCXN0ZDo6dmVjdG9yPHBvaW50PiByZXN1bHQ7CglpZihsYSA9PSAwKSB7CgkJaWYobGIgPT0gMCkgewoJCQlpZihsYyA9PSAwKSB0aHJvdyAxOyAvLyBhbnkgcG9pbnQgaW4gd2hvbGUgcGxhbmUgY2FuIGJlIHJvb3QuCgkJfSBlbHNlIHsKCQkJZG91YmxlIFkgPSAtIGxjIC8gbGI7CgkJCWRvdWJsZSBEID0gcjEqcjEgLSAoWSAtIHkxKSooWS0geTEpOwoJCQlpZihEID4gMCkgewoJCQkJcmVzdWx0LmVtcGxhY2VfYmFjayh4MSArIHNxcnQoRCksIFkpOwoJCQkJcmVzdWx0LmVtcGxhY2VfYmFjayh4MSAtIHNxcnQoRCksIFkpOwoJCQl9IGVsc2UgaWYoRCA9PSAwKSB7CgkJCQlyZXN1bHQuZW1wbGFjZV9iYWNrKHgxLCBZKTsKCQkJfQoJCX0KCX0gZWxzZSB7CgkJZG91YmxlIEEgPSAtIGxiIC8gbGEsIEIgPSAtIGxjIC8gbGE7CgkJZG91YmxlIEQgPSBzcXVhcmUoMipBKihCLXgxKS0yKnkxKS00KihBKkErMSkqKChCLXgxKSooQi14MSkreTEqeTEtcjEqcjEpOwoJCWlmKEQgPiAwKSB7CgkJCXJlc3VsdC5lbXBsYWNlX2JhY2soQSooLTIqQSooQi14MSkrMip5MStzcXJ0KEQpKS8yLygxK0EqQSkrQiwgKC0yKkEqKEIteDEpKzIqeTErc3FydChEKSkvMi8oMStBKkEpKTsKCQkJcmVzdWx0LmVtcGxhY2VfYmFjayhBKigtMipBKihCLXgxKSsyKnkxLXNxcnQoRCkpLzIvKDErQSpBKStCLCAoLTIqQSooQi14MSkrMip5MS1zcXJ0KEQpKS8yLygxK0EqQSkpOwoJCX0gZWxzZSBpZihEID09IDApIHsKCQkJcmVzdWx0LmVtcGxhY2VfYmFjayhBKigtMipBKihCLXgxKSsyKnkxKS8yLygxK0EqQSkrQiwgKC0yKkEqKEIteDEpKzIqeTEpLzIvKDErQSpBKSk7CgkJfQoJfQoJcmV0dXJuIHJlc3VsdDsKfQoKY29uc3QgZG91YmxlIFRIUkVTSE9MRCA9IDAuMDAwMDAxOwoKaW5saW5lIGRvdWJsZSBkaXN0YW5jZTIoY29uc3QgcG9pbnQgJnAxLCBjb25zdCBwb2ludCAmcDIpCnsKCXJldHVybiBzcXVhcmUocDEueCAtIHAyLngpICsgc3F1YXJlKHAxLnkgLSBwMi55KTsKfQoKCmlubGluZSBkb3VibGUgZGlzdGFuY2UoY29uc3QgcG9pbnQgJnAxLCBjb25zdCBwb2ludCAmcDIpCnsKCXJldHVybiBzdGQ6OnNxcnQoZGlzdGFuY2UyKHAxLCBwMikpOwp9CgppbmxpbmUgYm9vbCBuZWFyKGNvbnN0IHBvaW50JiBwMSwgY29uc3QgcG9pbnQgJnAyKQp7CglyZXR1cm4gZGlzdGFuY2UyKHAxLCBwMikgPD0gc3F1YXJlKFRIUkVTSE9MRCk7Cn0KCmJvb2wgY2hlY2soaW50IG4sIGRvdWJsZSBkaXN0LCBjb25zdCBzdGQ6OnZlY3Rvcjxwb2ludD4gJnYpCnsKCWZvcihzdGQ6OnNpemVfdCBpID0gMDsgaSAhPSB2LnNpemUoKTsgKytpKSB7CgkJaWYoZGlzdGFuY2UyKHsgMCwgMCB9LCB2W2ldKSA+IDEgKyBUSFJFU0hPTEQpIHJldHVybiBmYWxzZTsgLy8gTm90IGluIGNpcmNsZQoJCWZvcihzdGQ6OnNpemVfdCBqID0gaSArIDE7IGogPCB2LnNpemUoKTsgKytqKSB7CgkJCWlmKGRpc3RhbmNlMih2W2ldLCB2W2pdKSArIFRIUkVTSE9MRCA8IHNxdWFyZShkaXN0KSkgcmV0dXJuIGZhbHNlOyAvLyBEaXN0YW5jZSB1bnNhdGlzZmFjdG9yeQoJCX0KCX0KCXJldHVybiB0cnVlOwp9Cgpib29sIHByb2Nlc3MoaW50IG4sIGludCBsZXZlbCwgZG91YmxlIGRpc3QsIHN0ZDo6dmVjdG9yPHBvaW50PiAmdikKewoJaWYobGV2ZWwgPT0gbikgewoJCXJldHVybiBjaGVjayhuLCBkaXN0LCB2KTsKCX0gZWxzZSBpZihsZXZlbCA9PSAwKSB7CgkJdi5jbGVhcigpOwoJCXYuZW1wbGFjZV9iYWNrKC0xLCAwKTsKCQlyZXR1cm4gcHJvY2VzcyhuLCBsZXZlbCsxLCBkaXN0LCB2KTsKCX0gZWxzZSB7CgkJc3RkOjp2ZWN0b3I8cG9pbnQ+IGNhbmRpZGF0ZTsKCQlhdXRvIGlzX25ldyA9IFsmXShjb25zdCBwb2ludCAmcCktPmJvb2wgewoJCQlpZihkaXN0YW5jZTIoeyAwLCAwIH0sIHApID4gMSArIFRIUkVTSE9MRCkgcmV0dXJuIGZhbHNlOyAvLyBOb3QgaW4gY2lyY2xlCgkJCWZvcihpbnQgaiA9IDA7IGogPCBsZXZlbCAtIDE7ICsraikgewoJCQkJaWYobmVhcihwLCB2W2pdKSkgcmV0dXJuIGZhbHNlOyAvLyBEdXBsaWNhdGUKCQkJCWlmKGRpc3RhbmNlMihwLCB2W2pdKSArIFRIUkVTSE9MRCA8IHNxdWFyZShkaXN0KSkgcmV0dXJuIGZhbHNlOyAvLyBEaXN0YW5jZSB1bnNhdGlzZmFjdG9yeQoJCQl9CgkJCWZvcihzdGQ6OnNpemVfdCBqID0gMDsgaiAhPSBjYW5kaWRhdGUuc2l6ZSgpOyArK2opIHsKCQkJCWlmKG5lYXIocCwgY2FuZGlkYXRlW2pdKSkgcmV0dXJuIGZhbHNlOyAvLyBEdXBsaWNhdGUgaW4gY2FuZGlkYXRlcwoJCQl9CgkJCXJldHVybiB0cnVlOwoJCX07CgkJdHJ5IHsKCQkJYXV0byB2MSA9IGNyb3NzX2NpcmNsZSgwLCAwLCAxLCB2W2xldmVsLTFdLngsIHZbbGV2ZWwtMV0ueSwgZGlzdCk7CgkJCWlmKHYxLnNpemUoKSA+IDEgJiYgbGV2ZWwgPT0gMSkgdjEucG9wX2JhY2soKTsgLy8gdmVydGljYWxseSBzeW1tZXRyaWMKCQkJZm9yKHN0ZDo6c2l6ZV90IGkgPSAwOyBpICE9IHYxLnNpemUoKTsgKytpKSB7CgkJCQlpZihpc19uZXcodjFbaV0pKSBjYW5kaWRhdGUucHVzaF9iYWNrKHYxW2ldKTsKCQkJfQoJCX0gY2F0Y2goaW50KSB7CgkJCS8vIFdoZW4gdltsZXZlbC0xXS54ID09IHZbbGV2ZWwtMV0ueSA9PSAwICYmIGRpc3QgPT0gMSwgZXhjZXB0aW9uIHRocm93bgoJCQkvLyBXZSBjYW4gc2ltcGx5IGlnbm9yZSBiZWNhdXNlIGNhbmRpZGF0ZXMgYXJlIHNlbGVjdGVkIGJ5IHRoZSBiZWxvdyBjcml0ZXJpYQoJCX0KCQlmb3IoaW50IGkgPSAwOyBpIDwgbGV2ZWwgLSAxOyArK2kpIHsKCQkJYXV0byB2MiA9IGNyb3NzX2NpcmNsZSh2W2ldLngsIHZbaV0ueSwgZGlzdCwgdltsZXZlbC0xXS54LCB2W2xldmVsLTFdLnksIGRpc3QpOwoJCQlmb3Ioc3RkOjpzaXplX3QgaiA9IDA7IGogIT0gdjIuc2l6ZSgpOyArK2opIHsKCQkJCWlmKGlzX25ldyh2MltqXSkpIGNhbmRpZGF0ZS5wdXNoX2JhY2sodjJbal0pOwoJCQl9CgkJfQoJCWZvcihzdGQ6OnNpemVfdCBpID0gMDsgaSAhPSBjYW5kaWRhdGUuc2l6ZSgpOyArK2kpIHsKCQkJdi5wdXNoX2JhY2soY2FuZGlkYXRlW2ldKTsKCQkJaWYocHJvY2VzcyhuLCBsZXZlbCsxLCBkaXN0LCB2KSkgcmV0dXJuIHRydWU7CgkJCXYucG9wX2JhY2soKTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQp9CgppbnQgbWFpbih2b2lkKQp7CglpbnQgbjsgc3RkOjpjaW4gPj4gbjsKCXN0ZDo6dmVjdG9yPHBvaW50PiByZXN1bHQ7Cglkb3VibGUgbCA9IFRIUkVTSE9MRCwgciA9IDIuMSwgdDsKCWZvcihpbnQgaT0wO2k8MzA7KytpKSB7CgkJdCA9IChsK3IpLzI7CgkJaWYocHJvY2VzcyhuLCAwLCB0LCByZXN1bHQpKSB7CgkJCWwgPSB0OwoJCX0gZWxzZSB7CgkJCXIgPSB0OwoJCX0KCX0KCWlmKHByb2Nlc3MobiwgMCwgbCwgcmVzdWx0KSkgewoJCXN0ZDo6Y291dCA8PCAiUE9TU0lCTEU6ICIgPDwgbCA8PCBzdGQ6OmVuZGw7CgkJZm9yKHN0ZDo6c2l6ZV90IGkgPSAwOyBpICE9IHJlc3VsdC5zaXplKCk7ICsraSkgewoJCQlzdGQ6OmNvdXQgPDwgcmVzdWx0W2ldLnggPDwgJywnIDw8IHJlc3VsdFtpXS55IDw8IHN0ZDo6ZW5kbDsKCQl9Cgl9IGVsc2UgewoJCXN0ZDo6Y291dCA8PCAiSU1QT1NTSUJMRSIgPDwgc3RkOjplbmRsOwoJfQoJcmV0dXJuIDA7Cn0K