Problem:
Score: 600 points

Problem Statement

E869120 is initially standing at the origin (0, 0) in a two-dimensional plane.

He has N engines, which can be used as follows:

When E869120 uses the i-th engine, his X- and Y-coordinate change by x_i and y_i, respectively. In other words, if E869120 uses the i-th engine from coordinates (X, Y), he will move to the coordinates (X + x_i, Y + y_i).

E869120 can use these engines in any order, but each engine can be used at most once. He may also choose not to use some of the engines.

He wants to go as far as possible from the origin.
Let (X, Y) be his final coordinates. Find the maximum possible value of \sqrt{X^2 + Y^2}, the distance from the origin.

Constraints

1 \leq N \leq 100

-1 \ 000 \ 000 \leq x_i \leq 1 \ 000 \ 000

-1 \ 000 \ 000 \leq y_i \leq 1 \ 000 \ 000

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
x_1 y_1
x_2 y_2
: :
x_N y_N

Output

Print the maximum possible final distance from the origin, as a real value.
Your output is considered correct when the relative or absolute error from the true answer is at most 10^{-10}.

Sample Input 1

3
0 10
5 -5
-5 -5

Sample Output 1

10.000000000000000000000000000000000000000000000000

The final distance from the origin can be 10 if we use the engines in one of the following three ways:

Use Engine 1 to move to (0, 10).

Use Engine 2 to move to (5, -5), and then use Engine 3 to move to (0, -10).

Use Engine 3 to move to (-5, -5), and then use Engine 2 to move to (0, -10).

The distance cannot be greater than 10, so the maximum possible distance is 10.

Sample Input 2

5
1 1
1 0
0 1
-1 0
0 -1

Sample Output 2

2.828427124746190097603377448419396157139343750753

The maximum possible final distance is 2 \sqrt{2} = 2.82842....
One of the ways to achieve it is:

Use Engine 1 to move to (1, 1), and then use Engine 2 to move to (2, 1), and finally use Engine 3 to move to (2, 2).

Sample Input 3

5
1 1
2 2
3 3
4 4
5 5

Sample Output 3

21.213203435596425732025330863145471178545078130654

If we use all the engines in the order 1 \rightarrow 2 \rightarrow 3 \rightarrow 4 \rightarrow 5, we will end up at (15, 15), with the distance 15 \sqrt{2} = 21.2132... from the origin.

Sample Input 4

3
0 0
0 1
1 0

Sample Output 4

1.414213562373095048801688724209698078569671875376

There can be useless engines with (x_i, y_i) = (0, 0).

Sample Input 5

1
90447 91000

Sample Output 5

128303.000000000000000000000000000000000000000000000000

Note that there can be only one engine.

Sample Input 6

2
96000 -72000
-72000 54000

Sample Output 6

120000.000000000000000000000000000000000000000000000000

There can be only two engines, too.

Sample Input 7

10
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20

Sample Output 7

148.660687473185055226120082139313966514489855137208

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace ABC139F
{
    class Program
    {
        public static void Solve(Input input)
        {
            var n = input.NextInt();
            var x = new int[n];
            var y = new int[n];

            for (int i = 0; i < n; i++)
            {
                x[i] = input.NextInt();
                y[i] = input.NextInt();
            }

            var ch = new Geometry.Point[] { new Geometry.Point(0, 0), new Geometry.Point(x[0], y[0]) };

            for (int i = 1; i < n; i++)
            {
                var l = new List<Geometry.Point>(ch);
                for (int j = 0; j < ch.Length; j++)
                {
                    l.Add(new Geometry.Point(ch[j].X + x[i], ch[j].Y + y[i]));
                }

                ch = Geometry.ConvexHull(l);
            }

            var max = ch.Max(v => v.X * v.X + v.Y * v.Y);

            Console.WriteLine($"{Math.Sqrt(max):F30}");
        }

        /// <summary>
        /// 幾何学系
        /// </summary>
        class Geometry
        {
            public enum Relationship
            {
                CCW = 1,            // CCW方向に存在する
                CW = -1,            // CW方向に存在する
                OnlineBack = 2,     // 折り返して、開始点を行き過ぎる
                OnlineFront = -2,   // 同じ方向に伸びている（一つの線分と見なせる）
                Onsegment = 0,      // 折り返して、開始点との間に終端がある

                Unsolved = 9,       // 未解決
            }

            static readonly double Epsilon = 1e-10;

            public static bool IsEqual(double x, double y) => Math.Abs(x - y) < Epsilon;

            public struct Point
            {
                public double X { get; set; }
                public double Y { get; set; }

                public Point(double x, double y)
                {
                    this.X = x;
                    this.Y = y;
                }

                public Point(IEnumerable<double> coords)
                    : this(coords.ElementAt(0), coords.ElementAt(1)) { }

                public Point(IEnumerable<int> coords)
                    : this(coords.Take(2).Select(x => (double)x)) { }

                public static double Norm(Point p) => p.X * p.X + p.Y * p.Y;
                public static double Abs(Point p) => Math.Sqrt(p.Norm());
                public static double Distance(Point p1, Point p2) => Abs(p2 - p1);

                /// <summary>
                /// 内積
                /// </summary>
                /// <param name="x"></param>
                /// <param name="y"></param>
                /// <returns></returns>
                public static double Dot(Point x, Point y) => x.X * y.X + x.Y * y.Y;

                /// <summary>
                /// 外積
                /// </summary>
                /// <param name="x"></param>
                /// <param name="y"></param>
                /// <returns></returns>
                public static double Cross(Point x, Point y) => x.X * y.Y - x.Y * y.X;

                /// <summary>
                /// p1からp2を経由してp3へ移動する時を考え
                /// p2でどのような挙動をしたか
                /// </summary>
                /// <param name="p1"></param>
                /// <param name="p2"></param>
                /// <param name="p3"></param>
                /// <returns></returns>
                public static Relationship Relation(Point p1, Point p2, Point p3)
                {
                    var a = p2 - p1;
                    var b = p3 - p1;

                    var cross = Cross(a, b);
                    if (cross > Epsilon) return Relationship.CCW;
                    if (cross < -Epsilon) return Relationship.CW;
                    if (Dot(a, b) < -Epsilon) return Relationship.OnlineBack;
                    if (a.Norm() < b.Norm()) return Relationship.OnlineFront;

                    return Relationship.Onsegment;
                }

                /// <summary>
                /// 線分1,2 と 線分3,4が直交するか
                /// </summary>
                /// <param name="p1"></param>
                /// <param name="p2"></param>
                /// <param name="p3"></param>
                /// <param name="p4"></param>
                /// <returns></returns>
                public static bool Intersect(Point p1, Point p2, Point p3, Point p4)
                {
                    var r1 = (int)Relation(p1, p2, p3);
                    var r2 = (int)Relation(p1, p2, p4);
                    var r3 = (int)Relation(p3, p4, p1);
                    var r4 = (int)Relation(p3, p4, p2);

                    return r1 * r2 <= 0 && r3 * r4 <= 0;
                }

                public static Point operator +(Point x, Point y) => new Point(x.X + y.X, x.Y + y.Y);
                public static Point operator -(Point x, Point y) => new Point(x.X - y.X, x.Y - y.Y);
                public static Point operator *(Point x, double k) => new Point(x.X * k, x.Y * k);
                public static Point operator /(Point x, double k) => new Point(x.X / k, x.Y / k);
                public static bool operator <(Point x, Point y) => x.X != y.Y ? x.X < y.X : x.Y < x.Y;
                public static bool operator >(Point x, Point y) => x.X != y.Y ? x.X > y.X : x.Y > x.Y;

                public static bool operator ==(Point x, Point y)
                {
                    return IsEqual(x.X, y.X) && IsEqual(x.Y, y.Y);
                }

                public static bool operator !=(Point x, Point y)
                {
                    return !(x == y);
                }

                public double Norm() => Point.Norm(this);
                public double Abs() => Point.Abs(this);
                public double Distance(Point other) => Point.Distance(this, other);
                public double Dot(Point other) => Point.Dot(this, other);
                public double Cross(Point other) => Point.Cross(this, other);

                public override bool Equals(object obj) => this == ((Point)obj);

                public override int GetHashCode()
                {
                    return this.X.GetHashCode() ^ this.Y.GetHashCode();
                }
            }

            public struct Line
            {
                public Point P1 { get; set; }
                public Point P2 { get; set; }

                public Line(Point p1, Point p2)
                {
                    this.P1 = p1;
                    this.P2 = p2;
                }

                public Line(double x1, double y1, double x2, double y2)
                    : this(new Point(x1, y1), new Point(x2, y2)) { }

                public Line(IEnumerable<double> points)
                    : this(new Point(points), new Point(points.Skip(2))) { }

                public Line(IEnumerable<int> points)
                    : this(points.Take(4).Select(x => (double)x)) { }

                /// <summary>
                /// P1からの相対的なP2座標
                /// </summary>
                /// <returns></returns>
                public Point Diffrent()
                {
                    return this.P2 - this.P1;
                }

                /// <summary>
                /// 直交するか？
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public bool IsOrthgonal(Line other)
                {
                    return IsEqual(Point.Dot(this.Diffrent(), other.Diffrent()), 0);
                }

                /// <summary>
                /// 平行か？
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public bool IsParallel(Line other)
                {
                    return IsEqual(Point.Cross(this.Diffrent(), other.Diffrent()), 0);
                }

                /// <summary>
                /// 点pの射影（pからLineへの垂線の交点）
                /// </summary>
                /// <param name="p"></param>
                /// <returns></returns>
                public Point Project(Point p)
                {
                    var bs = this.Diffrent();
                    var hypo = p - this.P1;

                    var t = Point.Dot(p - this.P1, bs);
                    var r = t / bs.Norm();

                    return this.P1 + bs * r;
                }

                /// <summary>
                /// 点pの反射（Lineを軸としたときのpの線対称にある点）
                /// </summary>
                /// <param name="p"></param>
                /// <returns></returns>
                public Point Reflect(Point p)
                {
                    return (this.Project(p) - p) * 2 + p;
                }

                /// <summary>
                /// 直線と点pとの距離
                /// （一応、直線は無限長の線のこと）
                /// </summary>
                /// <param name="p"></param>
                /// <returns></returns>
                public double DistanceLP(Point p)
                {
                    return Math.Abs(Point.Cross(this.Diffrent(), p - this.P1) / Point.Abs(this.Diffrent()));
                }

                /// <summary>
                /// 線分と点pとの距離
                /// （一応、線分は有限長の線のこと）
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public double DistanceSP(Point p)
                {
                    if (Point.Dot(this.P2 - this.P1, p - this.P1) < 0)
                    {
                        return Point.Abs(p - this.P1);
                    }
                    if (Point.Dot(this.P1 - this.P2, p - this.P2) < 0)
                    {
                        return Point.Abs(p - this.P2);
                    }

                    return DistanceLP(p);
                }

                /// <summary>
                /// 交差するか
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public bool IsIntersect(Line other)
                {
                    return Point.Intersect(this.P1, this.P2, other.P1, other.P2);
                }

                /// <summary>
                /// 線分間の最短距離
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public double Distance(Line other)
                {
                    if (this.IsIntersect(other)) return 0;

                    var r1 = this.DistanceSP(other.P1);
                    var r2 = this.DistanceSP(other.P2);
                    var r3 = other.DistanceSP(this.P1);
                    var r4 = other.DistanceSP(this.P2);

                    return Math.Min(Math.Min(Math.Min(r1, r2), r3), r4);
                }

                /// <summary>
                /// 線分間の交点
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public Point CrossPoint(Line other)
                {
                    var bs = other.P2 - other.P1;

                    var d1 = Math.Abs(Point.Cross(bs, this.P1 - other.P1));
                    var d2 = Math.Abs(Point.Cross(bs, this.P2 - other.P1));
                    var t = d1 / (d1 + d2);

                    return this.P1 + this.Diffrent() * t;
                }

                /// <summary>
                /// this.P2とother.P1が同一
                /// </summary>
                /// <param name="other"></param>
                /// <returns></returns>
                public Relationship Relation(Line other)
                {
                    if (this.P2 != other.P1) { return Relationship.Unsolved; }

                    return Point.Relation(this.P1, other.P1, other.P2);
                }
            }

            public struct Circle
            {
                public Point Center { get; set; }
                public double Radius { get; set; }

                public Circle(Point c, double r)
                {
                    this.Center = c;
                    this.Radius = r;
                }

                /// <summary>
                /// 線分との交点
                /// </summary>
                /// <param name="l"></param>
                /// <returns></returns>
                public IEnumerable<Point> CrossPoints(Line l)
                {
                    var pr = l.Project(this.Center);
                    var e = l.Diffrent() / l.Diffrent().Abs();

                    var bs = Math.Sqrt(this.Radius * this.Radius - (pr - this.Center).Norm());

                    if (this.Center.Distance(pr) > this.Radius)
                    {
                        yield break;
                    }

                    yield return pr + e * bs;
                    yield return pr - e * bs;
                }

                double Radian(Point p) => Math.Atan2(p.Y, p.X);
                Point Polar(double power, double radian) => new Point(Math.Cos(radian), Math.Sin(radian)) * power;

                /// <summary>
                /// 円との交点
                /// </summary>
                /// <param name="c"></param>
                /// <returns></returns>
                public IEnumerable<Point> CrossPoints(Circle c)
                {
                    var d = Point.Distance(this.Center, c.Center);
                    if (d > this.Radius + c.Radius)
                    {
                        yield break;
                    }

                    var a = Math.Acos((this.Radius * this.Radius + d * d - c.Radius * c.Radius) / (2 * this.Radius * d));
                    var t = Radian(c.Center - this.Center);

                    yield return this.Center + Polar(this.Radius, t + a);
                    yield return this.Center + Polar(this.Radius, t - a);
                }
            }

            public class Polygon
            {
                public List<Point> Points { get; set; }

                public Polygon(IEnumerable<Point> points)
                {
                    this.Points = points.ToList();
                }

                /// <summary>
                /// 
                /// </summary>
                /// <param name="coords"></param>
                /// <param name="n">頂点数(coordsの個数ではない)</param>
                public Polygon(IEnumerable<double> coords, int n)
                {
                    this.Points = new List<Point>();

                    foreach (var i in Enumerable.Range(0, n))
                    {
                        this.Points.Add(new Point(coords.ElementAt(i * 2), coords.ElementAt(i * 2 + 1)));
                    }
                }

                /// <summary>
                /// 
                /// </summary>
                /// <param name="coords"></param>
                /// <param name="n">頂点数(coordsの個数ではない)</param>
                public Polygon(IEnumerable<int> coords, int n)
                    : this(coords.Select(x => (double)x), n) { }

                public Polygon() : this(Enumerable.Empty<double>(), 0) { }

                public void Add(Point p) => this.Points.Add(p);
                public void Add(double x, double y) => this.Points.Add(new Point(x, y));
                public void Add(IEnumerable<double> coords) => this.Points.Add(new Point(coords));
                public void Add(IEnumerable<int> coords) => this.Points.Add(new Point(coords));

                /// <summary>
                /// 構成する線分リストを取得
                /// </summary>
                /// <returns></returns>
                public List<Line> Lines()
                {
                    var lines = new List<Line>();

                    var n = Points.Count();
                    for (int i = 0; i < n; i++)
                    {
                        lines.Add(new Line(Points[i].X, Points[i].Y,
                            Points[(i + 1) % n].X, Points[(i + 1) % n].Y));
                    }

                    return lines;
                }

                /// <summary>
                /// 点pとの関係
                /// </summary>
                /// <param name="p"></param>
                /// <returns>0: 外部、1: 線上、2: 内部</returns>
                public int JudgeRelationship(Point p)
                {
                    var n = this.Points.Count();
                    var x = false;

                    foreach (var i in Enumerable.Range(0, n))
                    {
                        var a = this.Points[i] - p;
                        var b = this.Points[(i + 1) % n] - p;

                        if ((Math.Abs(Point.Cross(a, b)) < Epsilon)
                            && (Point.Dot(a, b) < Epsilon))
                        {
                            return 1;
                        }
                        if (a.Y > b.Y)
                        {
                            var temp = a;
                            a = b;
                            b = temp;
                        }

                        if (a.Y < Epsilon && b.Y > Epsilon && Point.Cross(a, b) > Epsilon)
                        {
                            x = !x;
                        }
                    }

                    return x ? 2 : 0;
                }

                /// <summary>
                /// 点pが線上か内部にいる
                /// </summary>
                /// <param name="p"></param>
                /// <returns></returns>
                public bool Contains(Point p)
                {
                    return JudgeRelationship(p) > 0;
                }

                /// <summary>
                /// 重心の取得
                /// </summary>
                /// <param name="points"></param>
                /// <returns></returns>
                public Point CenterOfGravity()
                {
                    var n = Points.Count();
                    var sum = Points.Aggregate((x, next) => x + next);

                    return new Point(sum.X / n, sum.Y / n);
                }

                /// <summary>
                /// 面積の取得
                /// </summary>
                /// <returns></returns>
                public double Area()
                {
                    double sum = 0;
                    for (int i = 0; i < Points.Count(); i++)
                    {
                        sum += Points[i].Cross(Points[(i + 1) % Points.Count()]);
                    }

                    return Math.Abs(sum) / 2.0;
                }

                /// <summary>
                /// 凸性判定（内角が全て180度以下）
                /// </summary>
                /// <param name="isCcwPoints">PointsがCCWで格納されているか？</param>
                /// <returns></returns>
                public bool IsConvex(bool isCcwPoints = true)
                {
                    // CCWで格納されている点を見る場合は
                    // 巡回したときCWに点がでなければ内角が180度以内と見なせる
                    var dir = isCcwPoints ? Relationship.CW : Relationship.CCW;
                    var n = Points.Count();
                    for (int i = 0; i < n; i++)
                    {
                        var r = Point.Relation(Points[i], Points[(i + 1) % n], Points[(i + 2) % n]);

                        if (r == dir) { return false; }
                    }

                    return true;
                }
            }

            /// <summary>
            /// 凸包の構成点を取得
            /// 左下の点から反時計回り
            /// </summary>
            /// <param name="points"></param>
            /// <returns></returns>
            public static Point[] ConvexHull(IEnumerable<Point> points)
            {
                var ps = points.OrderBy(x => x.X)
                    .ThenBy(x => x.Y)
                    .ToArray();

                var qs = new Point[ps.Length * 2];
                int k = 0;

                // 下側凸包の作成
                for (int i = 0; i < ps.Length; i++)
                {
                    // 新しく追加する点によって凸包ではなくなるのなら、以前追加した点を削除する
                    while (k > 1 && (qs[k - 1] - qs[k - 2]).Cross(ps[i] - qs[k - 1]) < -Epsilon)
                    {
                        k--;
                    }

                    qs[k++] = ps[i];
                }

                // 上側凸包の作成
                int t = k;
                for (int i = ps.Length - 2; i >= 0; i--)
                {
                    // 新しく追加する点によって凸包ではなくなるのなら、以前追加した点を削除する
                    while (k > t && (qs[k - 1] - qs[k - 2]).Cross(ps[i] - qs[k - 1]) < -Epsilon)
                    {
                        k--;
                    }

                    qs[k++] = ps[i];
                }

                // 有効長に丸める
                Array.Resize(ref qs, k - 1);

                return qs;
            }

            /// <summary>
            /// 多角形の直径
            /// キャリパー法
            /// </summary>
            /// <param name="ps"></param>
            /// <returns></returns>
            public static double ConvexDiameter(IEnumerable<Point> ps)
            {
                var ch = ConvexHull(ps);
                var n = ch.Count();
                if (n == 2)
                {
                    // 凸が潰れている
                    return ch[0].Distance(ch[1]);
                }

                int i = 0, j = 0;
                // X軸方向に最も遠い対となる点
                for (int k = 0; k < n; k++)
                {
                    if (ch[i].X < ch[k].X) i = k;
                    if (ch[j].X > ch[k].X) j = k;
                }

                double r = 0;
                int si = i, sj = j;
                while (i != sj || j != si)
                {
                    r = Math.Max(r, ch[i].Distance(ch[j]));

                    if ((ch[(i + 1) % n] - ch[i]).Cross(ch[(j + 1) % n] - ch[j]) < Epsilon)
                    {
                        i = (i + 1) % n;
                    }
                    else
                    {
                        j = (j + 1) % n;
                    }
                }

                return r;
            }
        }

        #region Main
        public static void Main(string[] args)
        {
            // 出力が少ないときはこれをセットする方が時間かかるけれど
            // そのときにTLEするのはアルゴリズムが悪いせいだし、まあ良しとする
            var needsFlushOutput = true;
            if (needsFlushOutput)
            {
                // 細かく出力しないようにする
                var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
                Console.SetOut(sw);
            }

            // 通常は引数無しで、ファイルから読み出したい場合はpath指定する
            var input = new Input();

            // 仮想的に標準入力をセットする
            // テスト入力したまま提出することがままあるので……
#if DEBUG
            //input.SetText("3 5 5 5 5 -10 5");
            //input.SetText("2 -1 1 -1 1");
            //input.SetText("2 -1 -1 -1 -1");
            //input.SetText("2 1 -1 1 -1");
#endif

            Solve(input);

            Console.Out.Flush();
        }
        #endregion

        #region Competitive Template
#pragma warning disable CS0414
        static readonly int MOD = (int)1e9 + 7;
        static readonly int[] dx = { 1, 0, -1, 0 };
        static readonly int[] dy = { 0, 1, 0, -1 };
        /// <summary> 左上が原点 </summary>
        static readonly char[] dir = { 'R', 'U', 'L', 'D' };
#pragma warning restore CS0414

        public class Input
        {
            // 変な改行コードがたまに混じっているので、一応セパレート指定する
            // スペース単独指定の方がもちろん早い
            static readonly char[] separator = { ' ', '\r', '\n' };
            readonly StreamReader sr;
            readonly Queue<string> queue;

            /// <summary>
            /// 特定のファイルから読み出したい場合はpath指定する
            /// </summary>
            public Input(string path = "")
            {
                queue = new Queue<string>();

                if (string.IsNullOrEmpty(path)) { sr = new StreamReader(Console.OpenStandardInput()); }
                else { sr = new StreamReader(path); }
            }

            /// <summary>
            /// 入力予約
            /// </summary>
            public void SetText(IEnumerable<string> items)
            {
                foreach (var item in items)
                    SetText(item);
            }

            /// <summary>
            /// 入力予約
            /// </summary>
            public bool SetText(string s)
            {
                if (string.IsNullOrEmpty(s)) return false;

                foreach (var elem in s.Trim().Split(separator, StringSplitOptions.RemoveEmptyEntries))
                    queue.Enqueue(elem);

                return true;
            }

            /// <summary>
            /// 要素が存在するか
            /// </summary>
            public bool Any() => queue.Any() || Read();

            /// <summary>
            /// 内部queueに入力からの値をsplitして格納する
            /// </summary>
            bool Read()
            {
                if (!SetText(sr.ReadLine())) return false;

                if (!queue.Any()) return Read();

                return queue.Any();
            }

            /// <summary>
            /// 次のstringを一つ読み込む
            /// </summary>
            public string Next()
            {
                if (!queue.Any() && !Read()) return "";

                return queue.Dequeue();
            }

            /// <summary>
            /// 指定個数queueにたまるまでenqueueし続ける
            /// </summary>
            bool Accumulate(int n)
            {
                while (queue.Count() < n)
                    if (!Read()) return false;

                return true;
            }

            public int NextInt() => int.Parse(Next());
            public long NextLong() => long.Parse(Next());
            public double NextDouble() => double.Parse(Next());

            /// <summary>
            /// n個の要素をparseして、それぞれにoffsetをaddした配列を返す
            /// </summary>
            T[] NextT<T>(int n, T offset, Func<string, T> parse, Func<T, T, T> add)
            {
                if (!Accumulate(n)) return null;

                var a = new T[n];

                for (int i = 0; i < n; i++)
                    a[i] = add(parse(queue.Dequeue()), offset);

                return a;
            }

            public string[] Next(int n) => NextT(n, "", x => x, (x, y) => x);
            public int[] NextInt(int n, int offset = 0) => NextT(n, offset, int.Parse, (x, y) => x + y);
            public long[] NextLong(int n, long offset = 0) => NextT(n, offset, long.Parse, (x, y) => x + y);
            public double[] NextDouble(int n, double offset = 0.0) => NextT(n, offset, double.Parse, (x, y) => x + y);
        }

        static class Utils
        {
            public static T Max<T>(params T[] objs) => objs.Max();
            public static T Min<T>(params T[] objs) => objs.Min();

            /// <summary>
            /// vでfillされたT[d1][d2]配列を作成する
            /// </summary>
            public static T[][] Create2DArray<T>(int d1, int d2, T v)
            {
                return
                    Enumerable.Repeat(0, d1).Select(_ =>
                    Enumerable.Repeat(v, d2).ToArray()).ToArray();
            }

            /// <summary>
            /// vでfillされたT[d1][d2][d3]配列を作成する
            /// </summary>
            public static T[][][] Create3DArray<T>(int d1, int d2, int d3, T v)
            {
                return
                    Enumerable.Repeat(0, d1).Select(_ =>
                    Enumerable.Repeat(0, d2).Select(__ =>
                    Enumerable.Repeat(v, d3).ToArray()).ToArray()).ToArray();
            }
        }
        #endregion
    }
}