Problem:
Score : 100 points

Problem Statement

You are given an array a_0, a_1, ..., a_{N-1} of length N. Process Q queries of the following types.

0 p x: a_p \gets a_p + x

1 l r: Print \sum_{i = l}^{r - 1}{a_i}.

Constraints

1 \leq N, Q \leq 500,000

0 \leq a_i, x \leq 10^9

0 \leq p < N

0 \leq l_i < r_i \leq N

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N Q
a_0 a_1 ... a_{N - 1}
\textrm{Query}_0
\textrm{Query}_1
:
\textrm{Query}_{Q - 1}

Output

For each query of the latter type, print the answer.

Sample Input 1

5 5
1 2 3 4 5
1 0 5
1 2 4
0 3 10
1 0 5
1 0 3

Sample Output 1

15
7
25
6

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Runtime.Intrinsics.X86;

namespace FertiLib.Contest.H
{
	static class Program
	{
		public static void Solve(Scanner cin)
		{
			var (n, q) = cin.ReadValue<int, int>();
			var a = cin.ReadLongArray(n);
			var fenwick = new FenwickTree<long, LongOperator>(n);
			for (int i = 0; i < n; i++)
			{
				fenwick.Add(i, a[i]);
			}
			for (int i = 0; i < q; i++)
			{
				int que = cin.ReadInt();
				if(que == 0)
				{
					var (index, x) = cin.ReadValue<int, long>();
					fenwick.Add(index, x);
				}
				else
				{
					var (l, r) = cin.ReadValue<int, int>();
					Console.WriteLine(fenwick.Sum(l, r));
				}
			}
		}

		public static void Main(string[] args)
		{
			var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
			Console.SetOut(sw);
			var cin = new Scanner();
			Solve(cin);
			Console.Out.Flush();
		}

		public static void YESNO(bool condition) => Console.WriteLine(condition ? "YES" : "NO");
		public static void YesNo(bool condition) => Console.WriteLine(condition ? "Yes" : "No");
		public static void yesno(bool condition) => Console.WriteLine(condition ? "yes" : "no");

		public static bool Chmax<T>(ref T a, T b) where T : IComparable<T>
		{
			if (a.CompareTo(b) >= 0) return false;
			a = b;
			return true;
		}
		public static bool Chmin<T>(ref T a, T b) where T : IComparable<T>
		{
			if (a.CompareTo(b) <= 0) return false;
			a = b;
			return true;
		}
	}

	public static class InternalBit
	{
		/// <summary>
		/// _blsi_u32 OR <paramref name="n"/> &amp; -<paramref name="n"/>
		/// <para><paramref name="n"/>で立っているうちの最下位の 1 ビットのみを立てた整数を返す</para>
		/// </summary>
		/// <param name="n"></param>
		/// <returns><paramref name="n"/> &amp; -<paramref name="n"/></returns>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int ExtractLowestSetBit(int n)
		{
			if (Bmi1.IsSupported)
			{
				return (int)Bmi1.ExtractLowestSetBit((uint)n);
			}
			return n & -n;
		}

		/// <summary>
		/// (<paramref name="n"/> &amp; (1 &lt;&lt; x)) != 0 なる最小の非負整数 x を求めます。
		/// </summary>
		/// <remarks>
		/// <para>BSF: Bit Scan Forward</para>
		/// <para>制約: 1 ≤ <paramref name="n"/></para>
		/// </remarks>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BSF(uint n)
		{
			Debug.Assert(n >= 1);
			return BitOperations.TrailingZeroCount(n);
		}
	}

#pragma warning disable CA1815 // Override equals and operator equals on value types
	public interface INumOperator<T> : IEqualityComparer<T>, IComparer<T> where T : struct
	{
		/// <summary>
		/// MinValue
		/// </summary>
		public T MinValue { get; }
		/// <summary>
		/// MaxValue
		/// </summary>
		public T MaxValue { get; }
		/// <summary>
		/// Addition operator +
		/// </summary>
		/// <returns><paramref name="x"/> + <paramref name="y"/></returns>
		T Add(T x, T y);
		/// <summary>
		/// Subtraction operator -
		/// </summary>
		/// <returns><paramref name="x"/> - <paramref name="y"/></returns>
		T Subtract(T x, T y);
		/// <summary>
		/// Multiplication operator *
		/// </summary>
		/// <returns><paramref name="x"/> * <paramref name="y"/></returns>
		T Multiply(T x, T y);
		/// <summary>
		/// Division operator /
		/// </summary>
		/// <returns><paramref name="x"/> / <paramref name="y"/></returns>
		T Divide(T x, T y);
		/// <summary>
		/// Remainder operator %
		/// </summary>
		/// <returns><paramref name="x"/> % <paramref name="y"/></returns>
		T Modulo(T x, T y);
		/// <summary>
		/// Unary minus operator -
		/// </summary>
		/// <returns>-<paramref name="x"/></returns>
		T Minus(T x);
		/// <summary>
		/// Increment operator ++
		/// </summary>
		/// <returns>++<paramref name="x"/></returns>
		T Increment(T x);
		/// <summary>
		/// Decrement operator --
		/// </summary>
		/// <returns>--<paramref name="x"/></returns>
		T Decrement(T x);
		/// <summary>
		/// Greater than operator &gt;
		/// </summary>
		/// <returns><paramref name="x"/> &gt; <paramref name="y"/></returns>
		bool GreaterThan(T x, T y);
		/// <summary>
		/// Greater than or equal operator &gt;=
		/// </summary>
		/// <returns><paramref name="x"/> &gt;= <paramref name="y"/></returns>
		bool GreaterThanOrEqual(T x, T y);
		/// <summary>
		/// Less than operator &lt;
		/// </summary>
		/// <returns><paramref name="x"/> &lt; <paramref name="y"/></returns>
		bool LessThan(T x, T y);
		/// <summary>
		/// Less than or equal operator &lt;=
		/// </summary>
		/// <returns><paramref name="x"/> &lt;= <paramref name="y"/></returns>
		bool LessThanOrEqual(T x, T y);
	}
	public readonly struct IntOperator : INumOperator<int>
	{
		public int MinValue => int.MinValue;
		public int MaxValue => int.MaxValue;
		public int Add(int x, int y) => x + y;
		public int Subtract(int x, int y) => x - y;
		public int Multiply(int x, int y) => x * y;
		public int Divide(int x, int y) => x / y;
		public int Modulo(int x, int y) => x % y;
		public int Minus(int x) => -x;
		public int Increment(int x) => ++x;
		public int Decrement(int x) => --x;
		public bool GreaterThan(int x, int y) => x > y;
		public bool GreaterThanOrEqual(int x, int y) => x >= y;
		public bool LessThan(int x, int y) => x < y;
		public bool LessThanOrEqual(int x, int y) => x <= y;
		public int Compare(int x, int y) => x.CompareTo(y);
		public bool Equals(int x, int y) => x == y;
		public int GetHashCode(int obj) => obj.GetHashCode();
	}
	public readonly struct LongOperator : INumOperator<long>
	{
		public long MinValue => long.MinValue;
		public long MaxValue => long.MaxValue;
		public long Add(long x, long y) => x + y;
		public long Subtract(long x, long y) => x - y;
		public long Multiply(long x, long y) => x * y;
		public long Divide(long x, long y) => x / y;
		public long Modulo(long x, long y) => x % y;
		public long Minus(long x) => -x;
		public long Increment(long x) => ++x;
		public long Decrement(long x) => --x;
		public bool GreaterThan(long x, long y) => x > y;
		public bool GreaterThanOrEqual(long x, long y) => x >= y;
		public bool LessThan(long x, long y) => x < y;
		public bool LessThanOrEqual(long x, long y) => x <= y;
		public int Compare(long x, long y) => x.CompareTo(y);
		public bool Equals(long x, long y) => x == y;
		public int GetHashCode(long obj) => obj.GetHashCode();
	}
	public readonly struct UIntOperator : INumOperator<uint>
	{
		public uint MinValue => uint.MinValue;
		public uint MaxValue => uint.MaxValue;
		public uint Add(uint x, uint y) => x + y;
		public uint Subtract(uint x, uint y) => x - y;
		public uint Multiply(uint x, uint y) => x * y;
		public uint Divide(uint x, uint y) => x / y;
		public uint Modulo(uint x, uint y) => x % y;
		public uint Minus(uint x) => throw new InvalidOperationException("Uint type cannot be negative.");
		public uint Increment(uint x) => ++x;
		public uint Decrement(uint x) => --x;
		public bool GreaterThan(uint x, uint y) => x > y;
		public bool GreaterThanOrEqual(uint x, uint y) => x >= y;
		public bool LessThan(uint x, uint y) => x < y;
		public bool LessThanOrEqual(uint x, uint y) => x <= y;
		public int Compare(uint x, uint y) => x.CompareTo(y);
		public bool Equals(uint x, uint y) => x == y;
		public int GetHashCode(uint obj) => obj.GetHashCode();
	}
	public readonly struct ULongOperator : INumOperator<ulong>
	{
		public ulong MinValue => ulong.MinValue;
		public ulong MaxValue => ulong.MaxValue;
		public ulong Add(ulong x, ulong y) => x + y;
		public ulong Subtract(ulong x, ulong y) => x - y;
		public ulong Multiply(ulong x, ulong y) => x * y;
		public ulong Divide(ulong x, ulong y) => x / y;
		public ulong Modulo(ulong x, ulong y) => x % y;
		public ulong Minus(ulong x) => throw new InvalidOperationException("Ulong type cannot be negative.");
		public ulong Increment(ulong x) => ++x;
		public ulong Decrement(ulong x) => --x;
		public bool GreaterThan(ulong x, ulong y) => x > y;
		public bool GreaterThanOrEqual(ulong x, ulong y) => x >= y;
		public bool LessThan(ulong x, ulong y) => x < y;
		public bool LessThanOrEqual(ulong x, ulong y) => x <= y;
		public int Compare(ulong x, ulong y) => x.CompareTo(y);
		public bool Equals(ulong x, ulong y) => x == y;
		public int GetHashCode(ulong obj) => obj.GetHashCode();
	}
	public readonly struct DoubleOperator : INumOperator<double>
	{
		public double MinValue => double.MinValue;
		public double MaxValue => double.MaxValue;
		public double Add(double x, double y) => x + y;
		public double Subtract(double x, double y) => x - y;
		public double Multiply(double x, double y) => x * y;
		public double Divide(double x, double y) => x / y;
		public double Modulo(double x, double y) => x % y;
		public double Minus(double x) => -x;
		public double Increment(double x) => ++x;
		public double Decrement(double x) => --x;
		public bool GreaterThan(double x, double y) => x > y;
		public bool GreaterThanOrEqual(double x, double y) => x >= y;
		public bool LessThan(double x, double y) => x < y;
		public bool LessThanOrEqual(double x, double y) => x <= y;
		public int Compare(double x, double y) => x.CompareTo(y);
		public bool Equals(double x, double y) => x == y;
		public int GetHashCode(double obj) => obj.GetHashCode();
	}
#pragma warning restore CA1815 // Override equals and operator equals on value types

	/// <summary>
	/// 長さ N の配列に対し、
	/// <list type="bullet">
	/// <item>
	/// <description>要素の 1 点変更</description>
	/// </item>
	/// <item>
	/// <description>区間の要素の総和</description>
	/// </item>
	/// </list>
	/// <para>を O(log⁡N) で求めることが出来るデータ構造です。</para>
	/// </summary>
	public class IntFenwickTree : FenwickTree<int, IntOperator> { public IntFenwickTree(int n) : base(n) { } }

	/// <summary>
	/// 長さ N の配列に対し、
	/// <list type="bullet">
	/// <item>
	/// <description>要素の 1 点変更</description>
	/// </item>
	/// <item>
	/// <description>区間の要素の総和</description>
	/// </item>
	/// </list>
	/// <para>を O(log⁡N) で求めることが出来るデータ構造です。</para>
	/// </summary>
	public class UIntFenwickTree : FenwickTree<uint, UIntOperator> { public UIntFenwickTree(int n) : base(n) { } }

	/// <summary>
	/// 長さ N の配列に対し、
	/// <list type="bullet">
	/// <item>
	/// <description>要素の 1 点変更</description>
	/// </item>
	/// <item>
	/// <description>区間の要素の総和</description>
	/// </item>
	/// </list>
	/// <para>を O(log⁡N) で求めることが出来るデータ構造です。</para>
	/// </summary>
	public class LongFenwickTree : FenwickTree<long, LongOperator> { public LongFenwickTree(int n) : base(n) { } }

	/// <summary>
	/// 長さ N の配列に対し、
	/// <list type="bullet">
	/// <item>
	/// <description>要素の 1 点変更</description>
	/// </item>
	/// <item>
	/// <description>区間の要素の総和</description>
	/// </item>
	/// </list>
	/// <para>を O(log⁡N) で求めることが出来るデータ構造です。</para>
	/// </summary>
	public class ULongFenwickTree : FenwickTree<ulong, ULongOperator> { public ULongFenwickTree(int n) : base(n) { } }

	/// <summary>
	/// 長さ N の配列に対し、
	/// <list type="bullet">
	/// <item>
	/// <description>要素の 1 点変更</description>
	/// </item>
	/// <item>
	/// <description>区間の要素の総和</description>
	/// </item>
	/// </list>
	/// <para>を O(log⁡N) で求めることが出来るデータ構造です。</para>
	/// </summary>
	// TODO: public class ModIntFenwickTree : FenwickTree<ModInt, ModIntOperator> { public ModIntFenwickTree(int n) : base(n) { } }


	/// <summary>
	/// 長さ N の配列に対し、
	/// <list type="bullet">
	/// <item>
	/// <description>要素の 1 点変更</description>
	/// </item>
	/// <item>
	/// <description>区間の要素の総和</description>
	/// </item>
	/// </list>
	/// <para>を O(log⁡N) で求めることが出来るデータ構造です。</para>
	/// </summary>
	/// <typeparam name="TValue">配列要素の型</typeparam>
	/// <typeparam name="TOp">配列要素の操作を表す型</typeparam>
	[DebuggerTypeProxy(typeof(FenwickTree<,>.DebugView))]
	public class FenwickTree<TValue, TOp>
		where TValue : struct
		where TOp : struct, INumOperator<TValue>
	{
		private static readonly TOp op = default;
		private readonly TValue[] data;

		/// <summary>
		/// 長さ <paramref name="n"/> の配列aを持つ <see cref="FenwickTree{TValue, TOp}"/> クラスの新しいインスタンスを作ります。
		/// </summary>
		/// <remarks>
		/// <para>制約: 0≤<paramref name="n"/>≤10^8</para>
		/// <para>計算量: O(<paramref name="n"/>)</para>
		/// </remarks>
		/// <param name="n">配列の長さ</param>
		public FenwickTree(int n)
		{
			Debug.Assert(unchecked((uint)n <= 100_000_000));
			data = new TValue[n + 1];
		}

		/// <summary>
		/// a[<paramref name="p"/>] += <paramref name="x"/> を行います。
		/// </summary>
		/// <remarks>
		/// <para>制約: 0≤<paramref name="p"/>&lt;n</para>
		/// <para>計算量: O(log n)</para>
		/// </remarks>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Add(int p, TValue x)
		{
			Debug.Assert(unchecked((uint)p < data.Length));
			for (p++; p < data.Length; p += InternalBit.ExtractLowestSetBit(p))
			{
				data[p] = op.Add(data[p], x);
			}
		}

		/// <summary>
		/// a[<paramref name="l"/>] + a[<paramref name="l"/> - 1] + ... + a[<paramref name="r"/> - 1] を返します。
		/// </summary>
		/// <remarks>
		/// <para>制約: 0≤<paramref name="l"/>≤<paramref name="r"/>≤n</para>
		/// <para>計算量: O(log n)</para>
		/// </remarks>
		/// <returns>a[<paramref name="l"/>] + a[<paramref name="l"/> - 1] + ... + a[<paramref name="r"/> - 1]</returns>
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public TValue Sum(int l, int r)
		{
			Debug.Assert(0 <= l && l <= r && r < data.Length);
			return op.Subtract(Sum(r), Sum(l));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private TValue Sum(int r)
		{
			TValue s = default;
			for (; r > 0; r -= InternalBit.ExtractLowestSetBit(r))
			{
				s = op.Add(s, data[r]);
			}
			return s;
		}


		[DebuggerDisplay("Value = {" + nameof(value) + "}, Sum = {" + nameof(sum) + "}")]
		private struct DebugItem
		{
			public DebugItem(TValue value, TValue sum)
			{
				this.sum = sum;
				this.value = value;
			}
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			public readonly TValue value;
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			public readonly TValue sum;
		}
		private class DebugView
		{
			private readonly FenwickTree<TValue, TOp> fenwickTree;
			public DebugView(FenwickTree<TValue, TOp> fenwickTree)
			{
				this.fenwickTree = fenwickTree;
			}
			[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
			public DebugItem[] Items
			{
				get
				{
					var data = fenwickTree.data;
					var items = new DebugItem[data.Length - 1];
					items[0] = new DebugItem(data[1], data[1]);
					for (int i = 2; i < data.Length; i++)
					{
						int length = InternalBit.ExtractLowestSetBit(i);
						var pr = i - length - 1;
						var sum = op.Add(data[i], 0 <= pr ? items[pr].sum : default);
						var val = op.Subtract(sum, items[i - 2].sum);
						items[i - 1] = new DebugItem(val, sum);
					}
					return items;
				}
			}
		}
	}

	static class Extention
	{
		public static string Join<T>(this IEnumerable<T> x, string separator = "") => string.Join(separator, x);

		public static int UpperBound<T>(this IList<T> list, T value) => list.BinarySearch(value, true, 0, list.Count, Comparer<T>.Default);
		public static int LowerBound<T>(this IList<T> list, T value) => list.BinarySearch(value, false, 0, list.Count, Comparer<T>.Default);
		public static int BinarySearch<T>(this IList<T> list, T value, bool isUpperBound, int index, int length, Comparer<T> comparer)
		{
			var ng = index - 1;
			var ok = index + length;
			while (ok - ng > 1)
			{
				var mid = ng + (ok - ng) / 2;
				var res = comparer.Compare(list[mid], value);
				if (res < 0 || (isUpperBound && res == 0)) ng = mid;
				else ok = mid;
			}
			return ok;
		}
	}

	class Scanner
	{
		string[] s;
		int i;

		char[] separator = new char[] { ' ' };

		public Scanner()
		{
			s = new string[0];
			i = 0;
		}

		public string Read() => ReadString();

		public string ReadString()
		{
			if (i < s.Length) return s[i++];
			string st = Console.ReadLine();
			while (st == "") st = Console.ReadLine();
			s = st.Split(separator, StringSplitOptions.RemoveEmptyEntries);
			if (s.Length == 0) return ReadString();
			i = 0;
			return s[i++];
		}

		public string[] ReadStringArray(int N)
		{
			string[] Array = new string[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadString();
			}
			return Array;
		}

		public int ReadInt()
		{
			return int.Parse(ReadString());
		}

		public int[] ReadIntArray(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadInt() + add;
			}
			return Array;
		}

		public long ReadLong()
		{
			return long.Parse(ReadString());
		}

		public long[] ReadLongArray(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadLong() + add;
			}
			return Array;
		}

		public double ReadDouble()
		{
			return double.Parse(ReadString());
		}

		public double[] ReadDoubleArray(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = ReadDouble() + add;
			}
			return Array;
		}

		public T1 ReadValue<T1>() => (T1)Convert.ChangeType(ReadString(), typeof(T1));

		public (T1, T2) ReadValue<T1, T2>()
		{
			var inputs = ReadStringArray(2);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			return (v1, v2);
		}

		public (T1, T2, T3) ReadValue<T1, T2, T3>()
		{
			var inputs = ReadStringArray(3);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			return (v1, v2, v3);
		}

		public (T1, T2, T3, T4) ReadValue<T1, T2, T3, T4>()
		{
			var inputs = ReadStringArray(4);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			return (v1, v2, v3, v4);
		}

		public (T1, T2, T3, T4, T5) ReadValue<T1, T2, T3, T4, T5>()
		{
			var inputs = ReadStringArray(5);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
			return (v1, v2, v3, v4, v5);
		}

		public (T1, T2, T3, T4, T5, T6) ReadValue<T1, T2, T3, T4, T5, T6>()
		{
			var inputs = ReadStringArray(6);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
			var v6 = (T6)Convert.ChangeType(inputs[5], typeof(T6));
			return (v1, v2, v3, v4, v5, v6);
		}

		public (T1, T2, T3, T4, T5, T6, T7) ReadValue<T1, T2, T3, T4, T5, T6, T7>()
		{
			var inputs = ReadStringArray(7);
			var v1 = (T1)Convert.ChangeType(inputs[0], typeof(T1));
			var v2 = (T2)Convert.ChangeType(inputs[1], typeof(T2));
			var v3 = (T3)Convert.ChangeType(inputs[2], typeof(T3));
			var v4 = (T4)Convert.ChangeType(inputs[3], typeof(T4));
			var v5 = (T5)Convert.ChangeType(inputs[4], typeof(T5));
			var v6 = (T6)Convert.ChangeType(inputs[5], typeof(T6));
			var v7 = (T7)Convert.ChangeType(inputs[6], typeof(T7));
			return (v1, v2, v3, v4, v5, v6, v7);
		}

		public T1[] ReadValueArray<T1>(int N)
		{
			var v1 = new T1[N];
			for (int i = 0; i < N; i++)
			{
				v1[i] = ReadValue<T1>();
			}
			return v1;
		}

		public (T1[], T2[]) ReadValueArray<T1, T2>(int N)
		{
			var (v1, v2) = (new T1[N], new T2[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2) = ReadValue<T1, T2>();
				v1[i] = t1;
				v2[i] = t2;
			}
			return (v1, v2);
		}

		public (T1[], T2[], T3[]) ReadValueArray<T1, T2, T3>(int N)
		{
			var (v1, v2, v3) = (new T1[N], new T2[N], new T3[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3) = ReadValue<T1, T2, T3>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
			}
			return (v1, v2, v3);
		}

		public (T1[], T2[], T3[], T4[]) ReadValueArray<T1, T2, T3, T4>(int N)
		{
			var (v1, v2, v3, v4) = (new T1[N], new T2[N], new T3[N], new T4[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4) = ReadValue<T1, T2, T3, T4>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
			}
			return (v1, v2, v3, v4);
		}

		public (T1[], T2[], T3[], T4[], T5[]) ReadValueArray<T1, T2, T3, T4, T5>(int N)
		{
			var (v1, v2, v3, v4, v5) = (new T1[N], new T2[N], new T3[N], new T4[N], new T5[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4, t5) = ReadValue<T1, T2, T3, T4, T5>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
				v5[i] = t5;
			}
			return (v1, v2, v3, v4, v5);
		}

		public (T1[], T2[], T3[], T4[], T5[], T6[]) ReadValueArray<T1, T2, T3, T4, T5, T6>(int N)
		{
			var (v1, v2, v3, v4, v5, v6) = (new T1[N], new T2[N], new T3[N], new T4[N], new T5[N], new T6[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4, t5, t6) = ReadValue<T1, T2, T3, T4, T5, T6>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
				v5[i] = t5;
				v6[i] = t6;
			}
			return (v1, v2, v3, v4, v5, v6);
		}

		public (T1[], T2[], T3[], T4[], T5[], T6[], T7[]) ReadValueArray<T1, T2, T3, T4, T5, T6, T7>(int N)
		{
			var (v1, v2, v3, v4, v5, v6, v7) = (new T1[N], new T2[N], new T3[N], new T4[N], new T5[N], new T6[N], new T7[N]);
			for (int i = 0; i < N; i++)
			{
				var (t1, t2, t3, t4, t5, t6, t7) = ReadValue<T1, T2, T3, T4, T5, T6, T7>();
				v1[i] = t1;
				v2[i] = t2;
				v3[i] = t3;
				v4[i] = t4;
				v5[i] = t5;
				v6[i] = t6;
				v7[i] = t7;
			}
			return (v1, v2, v3, v4, v5, v6, v7);
		}
	}
}