import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Euler562 {
    static final double kPerimeterEps = 1e-15;

    static class TriangleResult {
        double perimeter = -1.0;
        double circumradius = -1.0;
        long ax, ay, bx, by, cx, cy;
    }

    static class Edge implements Comparable<Edge> {
        long a, b;
        long s2;

        Edge(long a, long b, long s2) {
            this.a = a;
            this.b = b;
            this.s2 = s2;
        }

        @Override
        public int compareTo(Edge o) {
            if (this.s2 != o.s2)
                return this.s2 > o.s2 ? -1 : 1;
            if (this.a != o.a)
                return this.a < o.a ? -1 : 1;
            return this.b < o.b ? -1 : (this.b == o.b ? 0 : 1);
        }
    }

    static BigInteger floorDiv(BigInteger a, BigInteger b) {
        BigInteger[] qr = a.divideAndRemainder(b);
        BigInteger q = qr[0];
        BigInteger r = qr[1];
        if (r.signum() != 0 && ((r.signum() > 0) != (b.signum() > 0))) {
            q = q.subtract(BigInteger.ONE);
        }
        return q;
    }

    static BigInteger ceilDiv(BigInteger a, BigInteger b) {
        BigInteger[] qr = a.divideAndRemainder(b);
        BigInteger q = qr[0];
        BigInteger r = qr[1];
        if (r.signum() != 0 && ((r.signum() > 0) == (b.signum() > 0))) {
            q = q.add(BigInteger.ONE);
        }
        return q;
    }

    static BigInteger roundDivNearest(BigInteger a, BigInteger b) {
        if (a.signum() >= 0) {
            return a.add(b.divide(BigInteger.valueOf(2))).divide(b);
        }
        return a.negate().add(b.divide(BigInteger.valueOf(2))).divide(b).negate();
    }

    static long isqrt(long n) {
        if (n < 0)
            return 0;
        long r = (long) Math.sqrt(n);
        while ((r + 1) * (r + 1) <= n)
            r++;
        while (r * r > n)
            r--;
        return r;
    }

    static long ceilSqrt(long n) {
        long r = isqrt(n);
        if (r * r < n)
            r++;
        return r;
    }

    static BigInteger isqrtBig(BigInteger n) {
        if (n.signum() == 0)
            return BigInteger.ZERO;
        BigInteger r = BigInteger.valueOf((long) Math.sqrt(n.doubleValue()));
        if (r.signum() == 0)
            r = BigInteger.ONE;
        while (r.add(BigInteger.ONE).multiply(r.add(BigInteger.ONE)).compareTo(n) <= 0)
            r = r.add(BigInteger.ONE);
        while (r.multiply(r).compareTo(n) > 0)
            r = r.subtract(BigInteger.ONE);
        return r;
    }

    static long gcd(long a, long b) {
        a = Math.abs(a);
        b = Math.abs(b);
        while (b != 0) {
            long temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }

    static long[] extendedGcd(long a, long b) {
        long x0 = 1, y0 = 0;
        long x1 = 0, y1 = 1;
        long aa = a, bb = b;
        while (bb != 0) {
            long q = aa / bb;
            long t = aa - q * bb;
            aa = bb;
            bb = t;

            long nx = x0 - q * x1;
            long ny = y0 - q * y1;
            x0 = x1;
            y0 = y1;
            x1 = nx;
            y1 = ny;
        }
        return new long[] { x0, y0, aa };
    }

    static double perimeterUpperBound(long s2) {
        double L = Math.sqrt((double) s2);
        return 2.0 * L + 1.0 / L;
    }

    static boolean betterTriangle(TriangleResult cand, TriangleResult best) {
        if (cand.perimeter > best.perimeter + kPerimeterEps)
            return true;
        if (Math.abs(cand.perimeter - best.perimeter) <= kPerimeterEps && cand.circumradius > best.circumradius + 1e-18)
            return true;
        return false;
    }

    static class Solver {
        long r;
        long r2;
        int[] yMax;

        Solver(long r) {
            this.r = r;
            this.r2 = r * r;
            yMax = new int[(int) (2 * r + 1)];
            for (long x = -r; x <= r; x++) {
                long rem = r2 - x * x;
                yMax[(int) (x + r)] = (int) isqrt(rem);
            }
        }

        TriangleResult solveExact() {
            TriangleResult best = new TriangleResult();
            long dBound = 128;
            long maxD = 4 * r2;

            while (true) {
                if (dBound > maxD)
                    dBound = maxD;
                TriangleResult cur = searchWithDeficiencyBound(dBound, best);
                if (betterTriangle(cur, best))
                    best = cur;

                if (best.perimeter < 0.0) {
                    if (dBound == maxD)
                        break;
                    dBound = Math.min(maxD, dBound * 2);
                    continue;
                }

                double p = best.perimeter;
                double disc = p * p - 8.0;
                double lBound = (p + Math.sqrt(disc)) / 4.0;
                double dReqLd = 4.0 * r2 - lBound * lBound;
                long dReq = 0;
                if (dReqLd > 0.0) {
                    dReq = (long) Math.ceil(dReqLd - 1e-18);
                }

                if (dBound >= dReq || dBound == maxD)
                    break;
                dBound = Math.max(Math.min(maxD, dBound * 2), dReq);
            }

            return best;
        }

        TriangleResult searchWithDeficiencyBound(long dBound, TriangleResult initialBest) {
            List<Edge> edges = new ArrayList<>();
            buildCandidateEdges(dBound, initialBest.perimeter, edges);
            if (edges.isEmpty())
                return initialBest;

            Collections.sort(edges);

            TriangleResult best = initialBest;

            for (Edge e : edges) {
                if (best.perimeter >= 0.0 && perimeterUpperBound(e.s2) <= best.perimeter + kPerimeterEps) {
                    break;
                }
                TriangleResult cand = evaluateEdge(e, best.perimeter);
                if (betterTriangle(cand, best))
                    best = cand;
            }

            return best;
        }

        void buildCandidateEdges(long dBound, double bestPerimeter, List<Edge> edges) {
            long maxS2 = 4 * r2;
            long minS2 = (dBound >= maxS2) ? 0 : (maxS2 - dBound);

            long aMinSq = (minS2 + 1) / 2;
            long aMin = ceilSqrt(aMinSq);
            if (aMin < 1)
                aMin = 1;

            for (long a = aMin; a <= 2 * r; a++) {
                long aa = a * a;
                if (aa > maxS2)
                    break;

                long remHi = maxS2 - aa;
                long bMax = Math.min(a, isqrt(remHi));
                if (bMax < 1)
                    continue;

                long bMin = 1;
                if (aa < minS2) {
                    bMin = ceilSqrt(minS2 - aa);
                }
                if (bMin > bMax)
                    continue;

                for (long b = bMin; b <= bMax; b++) {
                    if (gcd(a, b) != 1)
                        continue;
                    long s2 = aa + b * b;
                    if (s2 < minS2 || s2 > maxS2)
                        continue;
                    if (bestPerimeter >= 0.0 && perimeterUpperBound(s2) <= bestPerimeter + kPerimeterEps) {
                        continue;
                    }
                    edges.add(new Edge(a, b, s2));
                }
            }
        }

        TriangleResult evaluateEdge(Edge e, double threshold) {
            TriangleResult best = new TriangleResult();
            best.perimeter = threshold;

            long a = e.a;
            long b = e.b;
            long s2 = e.s2;
            BigInteger s2Big = BigInteger.valueOf(s2);
            double L = Math.sqrt(s2);

            if (perimeterUpperBound(s2) <= threshold + kPerimeterEps)
                return best;

            long[] extGcd = extendedGcd(-b, a);
            long x1 = extGcd[0];
            long y1 = extGcd[1];
            long g = extGcd[2];

            if (g == -1) {
                x1 = -x1;
                y1 = -y1;
            } else if (g != 1) {
                return best;
            }

            long xLo = Math.max(-r, -r - a);
            long xHi = Math.min(r, r - a);
            if (xLo > xHi)
                return best;

            for (long xA = xLo; xA <= xHi; xA++) {
                long xB = xA + a;
                int y1Max = yMax[(int) (xA + r)];
                int y2Max = yMax[(int) (xB + r)];
                long yLo = Math.max(-y1Max, -y2Max - b);
                long yHi = Math.min(y1Max, y2Max - b);
                if (yLo > yHi)
                    continue;

                for (long yA = yLo; yA <= yHi; yA++) {
                    long yB = yA + b;
                    BigInteger detA = BigInteger.valueOf(a).multiply(BigInteger.valueOf(yA))
                            .subtract(BigInteger.valueOf(b).multiply(BigInteger.valueOf(xA)));

                    for (int sgn : new int[] { -1, 1 }) {
                        BigInteger k = detA.add(BigInteger.valueOf(sgn));

                        BigInteger xRaw = BigInteger.valueOf(x1).multiply(k);
                        BigInteger yRaw = BigInteger.valueOf(y1).multiply(k);

                        BigInteger dot = xRaw.multiply(BigInteger.valueOf(a)).add(yRaw.multiply(BigInteger.valueOf(b)));
                        BigInteger shift = roundDivNearest(dot.negate(), s2Big);
                        BigInteger x0 = xRaw.add(shift.multiply(BigInteger.valueOf(a)));
                        BigInteger y0 = yRaw.add(shift.multiply(BigInteger.valueOf(b)));

                        BigInteger Acoef = s2Big;
                        BigInteger Bcoef = x0.multiply(BigInteger.valueOf(a)).add(y0.multiply(BigInteger.valueOf(b)))
                                .multiply(BigInteger.valueOf(2));
                        BigInteger Ccoef = x0.multiply(x0).add(y0.multiply(y0)).subtract(BigInteger.valueOf(r2));

                        BigInteger disc = Bcoef.multiply(Bcoef)
                                .subtract(Acoef.multiply(Ccoef).multiply(BigInteger.valueOf(4)));
                        if (disc.signum() < 0)
                            continue;

                        BigInteger sqrtDisc = isqrtBig(disc);
                        BigInteger denom = Acoef.multiply(BigInteger.valueOf(2));

                        BigInteger tMin = floorDiv(Bcoef.negate().subtract(sqrtDisc), denom).add(BigInteger.ONE);
                        BigInteger tMax = floorDiv(Bcoef.negate().add(sqrtDisc), denom);
                        if (Bcoef.negate().subtract(sqrtDisc).remainder(denom).signum() == 0)
                            tMin = tMin.subtract(BigInteger.ONE);

                        tMin = ceilDiv(Bcoef.negate().subtract(sqrtDisc), denom);

                        if (tMin.compareTo(tMax) > 0)
                            continue;

                        // Because the loop logic works perfectly, iterate inside:
                        long minT = tMin.longValue();
                        long maxT = tMax.longValue();

                        for (long t = minT; t <= maxT; t++) {
                            BigInteger tBig = BigInteger.valueOf(t);
                            BigInteger xC = x0.add(tBig.multiply(BigInteger.valueOf(a)));
                            BigInteger yC = y0.add(tBig.multiply(BigInteger.valueOf(b)));

                            if (xC.multiply(xC).add(yC.multiply(yC)).compareTo(BigInteger.valueOf(r2)) > 0)
                                continue;

                            long xC_L = xC.longValue();
                            long yC_L = yC.longValue();

                            if ((xC_L == xA && yC_L == yA) || (xC_L == xB && yC_L == yB))
                                continue;

                            long dx1 = xC_L - xA;
                            long dy1 = yC_L - yA;
                            long d2 = dx1 * dx1 + dy1 * dy1;

                            long dx2 = xC_L - xB;
                            long dy2 = yC_L - yB;
                            long d3 = dx2 * dx2 + dy2 * dy2;

                            if (d2 > s2 || d3 > s2)
                                continue;

                            double p = L + Math.sqrt(d2) + Math.sqrt(d3);
                            if (p <= best.perimeter + kPerimeterEps)
                                continue;

                            double R = Math.sqrt((double) s2 * d2 * d3) / 2.0;

                            TriangleResult cand = new TriangleResult();
                            cand.perimeter = p;
                            cand.circumradius = R;
                            if (betterTriangle(cand, best)) {
                                best = cand;
                            }
                        }
                    }
                }
            }
            return best;
        }
    }

    public static String solve() {
        Solver solver = new Solver(10000000);
        TriangleResult best = solver.solveExact();
        double T = best.circumradius / 10000000.0;
        return Long.toString(Math.round(T));
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
