You've been in love with Coronavirus-chan for a long time, but you didn't know where she lived until now. And just now you found out that she lives in a faraway place called Naha. 

You immediately decided to take a vacation and visit Coronavirus-chan. Your vacation lasts exactly $x$ days and that's the exact number of days you will spend visiting your friend. You will spend exactly $x$ consecutive (successive) days visiting Coronavirus-chan.

They use a very unusual calendar in Naha: there are $n$ months in a year, $i$-th month lasts exactly $d_i$ days. Days in the $i$-th month are numbered from $1$ to $d_i$. There are no leap years in Naha.

The mood of Coronavirus-chan (and, accordingly, her desire to hug you) depends on the number of the day in a month. In particular, you get $j$ hugs if you visit Coronavirus-chan on the $j$-th day of the month.

You know about this feature of your friend and want to plan your trip to get as many hugs as possible (and then maybe you can win the heart of Coronavirus-chan). 

Please note that your trip should not necessarily begin and end in the same year.


-----Input-----

The first line of input contains two integers $n$ and $x$ ($1 \le n \le 2 \cdot 10^5$) — the number of months in the year and the number of days you can spend with your friend.

The second line contains $n$ integers $d_1, d_2, \ldots, d_n$, $d_i$ is the number of days in the $i$-th month ($1 \le d_i \le 10^6$).

It is guaranteed that $1 \le x \le d_1 + d_2 + \ldots + d_n$.


-----Output-----

Print one integer — the maximum number of hugs that you can get from Coronavirus-chan during the best vacation in your life.


-----Examples-----
Input
3 2
1 3 1

Output
5
Input
3 6
3 3 3

Output
12
Input
5 6
4 2 3 1 3

Output
15


-----Note-----

In the first test case, the numbers of the days in a year are (indices of days in a corresponding month) $\{1,1,2,3,1\}$. Coronavirus-chan will hug you the most if you come on the third day of the year: $2+3=5$ hugs.

In the second test case, the numbers of the days are $\{1,2,3,1,2,3,1,2,3\}$. You will get the most hugs if you arrive on the third day of the year: $3+1+2+3+1+2=12$ hugs.

In the third test case, the numbers of the days are $\{1,2,3,4,1,2, 1,2,3, 1, 1,2,3\}$. You will get the most hugs if you come on the twelfth day of the year: your friend will hug you $2+3+1+2+3+4=15$ times.

Source: codeforces | Difficulty: HARD
Tags: Sorting

Amortized analysis

Implementation

Greedy algorithms

Complete search


Solutions:
import sys
readline = sys.stdin.readline
(N, X) = map(int, readline().split())
D = list(map(int, readline().split()))
AD = D + D + [0]
S = [d * (d + 1) // 2 for d in D]
S = S + S + [0]
for i in range(1, 2 * N):
	AD[i] += AD[i - 1]
	S[i] += S[i - 1]
D = D + D + [0]
ans = 0
for r in range(N, 2 * N):
	ng = -1
	ok = r
	while abs(ok - ng) > 1:
		med = (ok + ng) // 2
		if AD[r] - AD[med] < X:
			ok = med
		else:
			ng = med
	l = ok
	res = S[r] - S[l - 1]
	dd = D[l] - (X - (AD[r] - AD[l]))
	res -= dd * (dd + 1) // 2
	ans = max(ans, res)
print(ans)


import bisect
(n, m) = map(int, input().split())
l = list(map(int, input().split()))
l = l + l
pre = [0, l[0]]
su = [0, l[0] * (l[0] + 1) // 2]
for i in range(2, 2 * n):
	pre.append(pre[i - 1] + l[i - 1])
	su.append(su[i - 1] + l[i - 1] * (l[i - 1] + 1) // 2)
ans = 0
for i in range(1, n + 1):
	le = m + pre[i - 1]
	ind = bisect.bisect_left(pre, le)
	di = pre[ind] - pre[i - 1] - m
	cans = su[ind] - su[i - 1] - di * (di + 1) // 2
	ans = max(ans, cans)
print(ans)


import sys
input = sys.stdin.readline
(n, x) = list(map(int, input().split()))
D = list(map(int, input().split()))
D2 = [x * (x + 1) // 2 for x in D]
from itertools import accumulate
S = [0] + list(accumulate(D + D))
S2 = [0] + list(accumulate(D2 + D2))
ANS = 0
import bisect
for i in range(2 * n + 1):
	if S[i] - x < 0:
		continue
	y = bisect.bisect_left(S, S[i] - x)
	score = S2[i] - S2[y]
	rest = x - (S[i] - S[y])
	MAX = D[(y - 1) % n]
	score += (MAX + (MAX - rest + 1)) * rest // 2
	ANS = max(ANS, score)
print(ANS)


from sys import stdin, stderr

def rl():
	return [int(w) for w in stdin.readline().split()]
(n, end_day) = rl()
d = rl()
start_month = start_day = end_month = hugs = 0
while end_month < n and end_day >= d[end_month]:
	hugs += d[end_month] * (d[end_month] + 1) // 2
	end_day -= d[end_month]
	end_month += 1
hugs += end_day * (end_day + 1) // 2
max_hugs = hugs
if end_month < n:
	while start_month < n:
		step = min(d[start_month] - start_day, d[end_month] - end_day)
		hugs += step * (end_day - start_day)
		start_day += step
		end_day += step
		if start_day >= d[start_month]:
			start_day = 0
			start_month += 1
		if end_day >= d[end_month]:
			end_day = 0
			end_month += 1
			if end_month >= n:
				end_month = 0
		if hugs > max_hugs:
			max_hugs = hugs
print(max_hugs)


import math, sys, bisect
from collections import defaultdict, Counter, deque
from itertools import groupby, accumulate
input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
ilele = lambda : map(int, input().split())
alele = lambda : list(map(int, input().split()))

def Y(c):
	print(['NO', 'YES'][c])

def y(c):
	print(['no', 'yes'][c])

def fun(x):
	return x * (x + 1) // 2
(n, x) = ilele()
A = alele()
B = [0] + list(accumulate(A + A))
C = [fun(i) for i in A]
D = [0] + list(accumulate(C + C))
maxi = -1000000000.0
i = j = len(B) - 1
while i > 0:
	y = B[j] - B[i - 1]
	if y < x:
		i -= 1
	else:
		extra = fun(y - x)
		maxi = max(D[j] - D[i - 1] - extra, maxi)
		j -= 1
print(maxi)


def NSum(N):
	return N * (N + 1) >> 1
(N, K) = map(int, input().split())
List = [int(x) for x in input().split()]
Days = [0]
Hugs = [0]
for i in range(2 * N):
	Days.append(Days[-1] + List[i % N])
	Hugs.append(Hugs[-1] + NSum(List[i % N]))
i = 0
j = 1
Max = 0
while i < N:
	if Days[j] - Days[i] > K and Days[j] - Days[i + 1] >= K:
		i += 1
	elif Days[j] - Days[i] >= K and Days[j] - Days[i + 1] < K:
		Max = max(Max, Hugs[j] - Hugs[i] - NSum(Days[j] - Days[i] - K))
		i += 1
		j += 1
	else:
		j += 1
print(Max)


from bisect import bisect_left
(N, X) = map(int, input().split())
A = list(map(int, input().split()))
S = [0 for _ in range(len(A) * 2)]
C = [0 for _ in range(len(A) * 2)]
S[0] = A[0]
C[0] = A[0] * (A[0] + 1) // 2
for i in range(1, len(S)):
	S[i] = A[i % N] + S[i - 1]
	C[i] = A[i % N] * (A[i % N] + 1) // 2 + C[i - 1]
result = 0
for i in range(len(A), len(A) * 2):
	f = bisect_left(S, S[i] - X + 1)
	r = C[i] - C[f - 1] - (S[i] + 1 - X - S[f - 1]) * (S[i] - X - S[f - 1]) // 2
	if result < r:
		result = r
print(result)


def upper_bound(arr, l, r, x):
	(start, end) = (l, r)
	while l <= r:
		m = l + (r - l) // 2
		if arr[m] > x:
			r = m - 1
		else:
			l = m + 1
	if start <= l <= end:
		return l
	return -1
(n, x) = map(int, input().split())
a = list(map(int, input().split()))
a += a
n *= 2
cur = 0
cur2 = 0
b = []
c = []
for i in range(n):
	cur += a[i]
	cur2 += a[i] * (a[i] + 1) // 2
	b.append(cur)
	c.append(cur2)
ans = 0
for i in range(n - 1):
	if b[i + 1] >= x:
		z = upper_bound(b, 0, n, b[i + 1] - x)
		cnt = c[i + 1] - c[z]
		days = b[i + 1] - b[z]
		extra = x - days
		cnt += a[z] * (a[z] + 1) // 2
		cnt -= (a[z] - extra) * (a[z] - extra + 1) // 2
		ans = max(ans, cnt)
print(ans)


import sys
input = sys.stdin.readline

def main():
	(N, X) = [int(x) for x in input().split()]
	D = [int(x) for x in input().split()]

	def sum_up_to_n(n):
		return n * (n + 1) // 2
	D = D + D
	ans = 0
	cnt = 0
	l = 2 * N - 1
	tmp = 0
	for r in range(2 * N - 1, -1, -1):
		while l >= 0 and cnt < X:
			cnt += D[l]
			tmp += sum_up_to_n(D[l])
			l -= 1
		ans = max(ans, tmp - sum_up_to_n(cnt - X))
		tmp -= sum_up_to_n(D[r])
		cnt -= D[r]
	print(ans)
main()


(n, d) = map(int, input().strip().split())
arr = list(map(int, input().strip().split()))
max_hugs = 0
start = n - 1
end = n - 1
days = 0
hugs = 0
while end >= 0:
	while days + arr[start] < d:
		hugs += arr[start] * (arr[start] + 1) // 2
		days += arr[start]
		start = (n + start - 1) % n
	if days < d:
		extra_days = arr[start] - (d - days)
		extra_hugs = arr[start] * (arr[start] + 1) // 2 - extra_days * (extra_days + 1) // 2
	max_hugs = max(max_hugs, hugs + extra_hugs)
	hugs -= arr[end] * (arr[end] + 1) // 2
	days -= arr[end]
	end -= 1
print(max_hugs)


import bisect
import sys
input = sys.stdin.readline
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d += d
sum_ = [0] * (2 * n)
for i in range(2 * n):
	sum_[i] = d[i] * (d[i] + 1) // 2
ru_sum = [0] * (2 * n + 1)
for i in range(2 * n):
	ru_sum[i + 1] = ru_sum[i] + sum_[i]
ru_cnt = [0] * (2 * n + 1)
for i in range(2 * n):
	ru_cnt[i + 1] = ru_cnt[i] + d[i]

def solve(ind, days):
	if ind - 1 < 0:
		return 0
	return sum_[ind] - (d[ind] - days) * (d[ind] - days + 1) // 2
ans = 0
for i in range(2 * n):
	l = bisect.bisect_left(ru_cnt, ru_cnt[i + 1] - x)
	r = i + 1
	res = ru_sum[r] - ru_sum[l]
	days = x - (ru_cnt[r] - ru_cnt[l])
	res += solve(l - 1, days)
	ans = max(ans, res)
print(ans)


(n, x) = map(int, input().split())
days = list(map(int, input().split()))
(nd, ans, premax, j) = (0, 0, 0, 0)
for i in range(n):
	while nd < x:
		nd += days[j]
		premax += days[j] * (days[j] + 1) // 2
		j = (j + 1) % n
	ans = max(ans, premax - (nd - x) * (nd - x + 1) // 2)
	nd -= days[i]
	premax -= days[i] * (days[i] + 1) // 2
print(ans)


import sys
input = sys.stdin.readline
(n, x) = map(int, input().split())
a = [int(item) for item in input().split()]
a = a + a
cnt = 0
val = 0
l = 0
r = 0
left_idx = 0
ans = 0
while r < 2 * n:
	cnt += a[r]
	val += (a[r] + 1) * a[r] // 2
	r += 1
	if cnt < x:
		continue
	while cnt > x:
		step = cnt - x
		if a[l] - left_idx <= step:
			cnt -= a[l] - left_idx
			val -= (a[l] + 1) * a[l] // 2 - (left_idx + 1) * left_idx // 2
			left_idx = 0
			l += 1
		else:
			step = cnt - x
			cnt = x
			val -= (left_idx + step + 1) * (left_idx + step) // 2 - (left_idx + 1) * left_idx // 2
			left_idx += step
	ans = max(ans, val)
print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip()
(N, X) = map(int, input().split())
A = [int(a) for a in input().split()][::-1] * 2 + [1] * 10
x = X
j = 0
s = 0
la = A[0]
ans = 0
for i in range(len(A)):
	while j < len(A) - 1 and x >= la:
		x -= la
		s += la * (la + 1) // 2
		j += 1
		la = A[j]
	if j == len(A):
		break
	s += x * (la + la - x + 1) // 2
	la -= x
	x = 0
	ans = max(ans, s)
	s -= A[i] * (A[i] + 1) // 2
	x += A[i]
print(ans)


def su(x, y):
	a = y * (y + 1) // 2
	b = x * (x - 1) // 2
	return a - b
(n, x) = map(int, input().split())
mas = list(map(int, input().split()))
for i in range(n):
	mas.append(mas[i])
r = n - 1
l = n - 1
suma = 0
ans = 0
maxi = 0
while suma <= x:
	suma += mas[l]
	ans += su(1, mas[l])
	l -= 1
l += 1
suma -= mas[l]
ans -= su(1, mas[l])
r += 1
suma += mas[r]
ans += su(1, mas[r])
for i in range(n):
	while suma > x:
		l += 1
		suma -= mas[l]
		ans -= su(1, mas[l])
	if suma == x:
		now = ans
	else:
		now = ans + su(mas[l] - (x - suma - 1), mas[l])
	maxi = max(maxi, now)
	r += 1
	if r != 2 * n:
		suma += mas[r]
		ans += su(1, mas[r])
print(maxi)


import sys

def getAp(n):
	return n * (n + 1) // 2
(n, x) = (int(var) for var in sys.stdin.readline().strip().split())
months = [int(var) for var in sys.stdin.readline().strip().split()]
months += months
(hugs, days) = ([0 for _ in range(2 * n)], [0 for _ in range(2 * n)])
(hugs[-1], days[-1]) = (getAp(months[-1]), months[-1])
for i in reversed(range(2 * n - 1)):
	hugs[i] = hugs[i + 1] + getAp(months[i])
	days[i] += days[i + 1] + months[i]
days.append(0)
hugs.append(0)
maxHugs = 0
for invx in reversed(range(2 * n)):
	(l, r) = (0, invx)
	(offset, store) = (days[invx + 1], None)
	while l <= r:
		mid = (l + r) // 2
		dayCalc = days[mid] - offset
		if dayCalc == x:
			store = mid
			break
		elif dayCalc < x:
			store = mid
			r = mid - 1
		else:
			l = mid + 1
	if store is None:
		maxHugs = max(maxHugs, getAp(months[invx]) - getAp(months[invx] - x))
	else:
		tempHugs = hugs[store] - hugs[invx + 1]
		daysLeft = x - (days[store] - offset)
		if store - 1 >= 0:
			tempHugs += getAp(months[store - 1]) - getAp(months[store - 1] - daysLeft)
		else:
			maxHugs = max(maxHugs, tempHugs)
			break
		maxHugs = max(maxHugs, tempHugs)
print(maxHugs)


(n, x) = list(map(int, input().split(' ')))
nums = list(map(int, input().split(' ')))
n += n
nums += nums
re = 0
left = 0
s = 0
day = 0

def awesomeFunc(x):
	return (1 + x) * x // 2
for (i, v) in enumerate(nums):
	s += awesomeFunc(v)
	day += v
	while day - nums[left] > x:
		day -= nums[left]
		s -= awesomeFunc(nums[left])
		left += 1
	re = max(re, s - awesomeFunc(day - x))
print(re)


import os
import sys
if os.path.exists('/mnt/c/Users/Square/square/codeforces'):
	f = iter(open('D.txt').readlines())

	def input():
		return next(f)
else:
	input = lambda : sys.stdin.readline().strip()
fprint = lambda *args: print(*args, flush=True)
(n, x) = map(int, input().split())
A = list(map(int, input().split()))
A = A + A

def f(x):
	return x * (x + 1) // 2
S = [A[0]]
H = [f(A[0])]
for i in A[1:]:
	S.append(S[-1] + i)
	H.append(H[-1] + f(i))
n = len(A)
res2 = 0
pos1 = 0
for (pos2, a) in list(enumerate(A)):
	while S[pos2] - S[pos1] > x:
		pos1 += 1
	I = S[pos2] - S[pos1]
	t = x - I
	dH = H[pos2] - H[pos1]
	if t > A[pos1]:
		continue
	res2 = max(dH + f(A[pos1]) - f(A[pos1] - t), res2)
print(res2)


import sys
input = sys.stdin.readline

def swaparr(arr, a, b):
	temp = arr[a]
	arr[a] = arr[b]
	arr[b] = temp

def gcd(a, b):
	if a == 0:
		return b
	return gcd(b % a, a)

def nCr(n, k):
	if k > n - k:
		k = n - k
	res = 1
	for i in range(k):
		res = res * (n - i)
		res = res / (i + 1)
	return int(res)

def upper_bound(a, x, lo=0):
	hi = len(a)
	while lo < hi:
		mid = (lo + hi) // 2
		if a[mid] < x:
			lo = mid + 1
		else:
			hi = mid
	return lo

def primefs(n):
	primes = {}
	while n % 2 == 0:
		primes[2] = primes.get(2, 0) + 1
		n = n // 2
	for i in range(3, int(n ** 0.5) + 2, 2):
		while n % i == 0:
			primes[i] = primes.get(i, 0) + 1
			n = n // i
	if n > 2:
		primes[n] = primes.get(n, 0) + 1
	return primes

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def swap(a, b):
	temp = a
	a = b
	b = temp
	return (a, b)

def find(x, link):
	p = x
	while p != link[p]:
		p = link[p]
	while x != p:
		nex = link[x]
		link[x] = p
		x = nex
	return p

def union(x, y, link, size):
	x = find(x, link)
	y = find(y, link)
	if size[x] < size[y]:
		(x, y) = swap(x, y)
	if x != y:
		size[x] += size[y]
		link[y] = x

def sieve(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime
MAXN = int(1000000.0 + 5)

def spf_sieve():
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, ceil(MAXN ** 0.5), 2):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def factoriazation(x):
	ret = {}
	while x != 1:
		ret[spf[x]] = ret.get(spf[x], 0) + 1
		x = x // spf[x]
	return ret

def int_array():
	return list(map(int, input().strip().split()))

def str_array():
	return input().strip().split()
MOD = int(1000000000.0) + 7
CMOD = 998244353
INF = float('inf')
NINF = -float('inf')
(n, m) = int_array()
a = int_array()
a *= 2
i = j = ans = td = days = 0
while i < n:
	while days < m:
		td += a[j] * (a[j] + 1) // 2
		days += a[j]
		j += 1
	ans = max(ans, td - (days - m) * (days - m + 1) // 2)
	days -= a[i]
	td -= a[i] * (a[i] + 1) // 2
	i += 1
print(ans)


import sys
input = sys.stdin.readline

def sum_upto_n(n):
	return n * (n + 1) // 2

def main():
	test = 1
	for _ in range(test):
		(n, x) = map(int, input().split())
		ara = [int(num) for num in input().split()]
		ara = ara * 2
		days = x
		hugs = 0
		ans = 0
		right = 2 * n - 1
		left = 2 * n - 1
		while right >= n:
			while ara[left] < days:
				hugs += sum_upto_n(ara[left])
				days -= ara[left]
				left -= 1
			ans = max(ans, hugs + sum_upto_n(ara[left]) - sum_upto_n(ara[left] - days))
			if left != right:
				days += ara[right]
				hugs -= sum_upto_n(ara[right])
				right -= 1
			else:
				left -= 1
				right -= 1
		print(ans)
main()


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
n *= 2
d += d

def val(m):
	return m * (m + 1) // 2
pref = [0] * (n + 1)
for i in range(n):
	pref[i + 1] = pref[i] + d[i]
wyn = -65836576238468732467823442342323468236784
indeksy = []
ind = 0
for i in range(1, n // 2 + 1):
	while True:
		if pref[ind + 1] - pref[i - 1] <= x - 1:
			ind += 1
		else:
			break
	if pref[ind] - pref[i - 1] == x - 1:
		indeksy.append([i, ind])
pref_hugs = [0] * (n + 1)
for i in range(n):
	pref_hugs[i + 1] = pref_hugs[i] + val(d[i])
for indeks in indeksy:
	dl = indeks[0]
	dp = indeks[1]
	if d[dl - 1] > d[dp]:
		cyk = pref_hugs[dp + 1] - pref_hugs[dl - 1] - d[dp] * (d[dp] - 1) // 2
	else:
		cyk = pref_hugs[dp] - pref_hugs[dl] + d[dl - 1] + d[dl - 1] * (d[dl - 1] + 1) // 2
	wyn = max(cyk, wyn)
ind = 0
for i in range(n + 1):
	if pref[i] < x:
		continue
	if pref[i] == x:
		wyn = min(wyn, pref_hugs[i])
		continue
	while pref[i] - pref[ind] > x:
		ind += 1
	cyk = pref_hugs[i] - pref_hugs[ind]
	leftovers = x - (pref[i] - pref[ind])
	cyk += (2 * d[ind - 1] - (leftovers - 1)) * leftovers // 2
	wyn = max(wyn, cyk)
print(wyn)


import os
import sys
from io import BytesIO, IOBase
from types import GeneratorType
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		import os
		self.os = os
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = self.os.read(self._fd, max(self.os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			self.os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

def getStr():
	return input()

def listStr():
	return list(input())

def get_month(pref_days, start, end, days):
	assert days <= pref_days[end] - pref_days[start - 1]
	left = start
	right = end
	if pref_days[end] - pref_days[end - 1] >= days:
		return end
	if pref_days[end] - pref_days[start] < days:
		return start
	left = start
	right = end
	while right - left > 1:
		middle = (left + right) // 2
		if pref_days[end] - pref_days[middle - 1] < days:
			right = middle
		else:
			left = middle
	return left

def solve():
	(N, X) = getInts()
	D = [0] + getInts()
	pref_days = [0]
	pref_sum_days = [0]
	curr_days = 0
	curr_sum_days = 0
	for n in range(1, N + 1):
		curr_days += D[n]
		pref_days.append(curr_days)
		curr_sum_days += D[n] * (D[n] + 1) // 2
		pref_sum_days.append(curr_sum_days)
	year_days = pref_days[-1]
	year_sum_days = pref_sum_days[-1]
	total_years = X // year_days
	extra_days = X % year_days
	if extra_days == 0:
		return total_years * year_sum_days
	best = 0
	for n in range(1, N + 1):
		if pref_days[n] >= X:
			start_mon = get_month(pref_days, 1, n, extra_days)
			assert start_mon <= n
			hugs = pref_sum_days[n] - pref_sum_days[start_mon - 1]
			days = pref_days[n] - pref_days[start_mon - 1]
			spare_days = days - extra_days
			hugs -= spare_days * (spare_days + 1) // 2
		else:
			start_mon = get_month(pref_days, n + 1, N, extra_days - pref_days[n])
			hugs = pref_sum_days[n] + pref_sum_days[N] - pref_sum_days[start_mon - 1]
			days = pref_days[n] + pref_days[N] - pref_days[start_mon - 1]
			spare_days = days - extra_days
			hugs -= spare_days * (spare_days + 1) // 2
		best = max(best, hugs)
	return best
print(solve())


(n, x) = map(int, input().split())
s = [int(x) for x in input().split()]
s = s + s
con = []
pre = [0]
ct = [0]
for i in range(0, len(s)):
	tt = s[i] * (s[i] + 1) // 2
	con.append(tt)
for i in range(0, len(con)):
	pre.append(pre[i] + con[i])
	ct.append(ct[i] + s[i])
pre = pre + [pre[-1] + 10000]
ct = ct + [ct[-1] + 10000]
ans = x
for i in range(0, len(ct) - 1):
	trg = ct[i] + x
	low = i + 1
	high = len(ct) - 1
	temp = i + 1
	while low <= high:
		mid = low + high >> 1
		if ct[mid] <= trg:
			low = mid + 1
		else:
			temp = mid
			high = mid - 1
	c = pre[temp - 1] - pre[i]
	dd = ct[temp - 1] - ct[i]
	diff = x - dd
	if diff >= 0:
		if temp - 1 == i:
			ele1 = s[i % n]
			c += ele1 * (ele1 + 1) // 2
			h = ele1 - diff
			c -= h * (h + 1) // 2
		else:
			ele1 = s[i % n]
			ele2 = s[(temp - 1) % n]
			h = min(ele1 - 1, ele2 - diff)
			c -= h * (h + 1) // 2
			h2 = diff + h
			c += h2 * (h2 + 1) // 2
	ans = max(ans, c)
print(ans)


import os
import sys
from io import BytesIO, IOBase

def main():
	(n, m) = map(int, input().split())
	a = [int(x) for x in input().split()]
	a = a * 2
	(ans, days, cnt) = (0, 0, 0)
	(i, j) = (0, 0)
	while i < len(a):
		while j < len(a) and days < m:
			days += a[j]
			cnt += a[j] * (a[j] + 1) // 2
			j += 1
		ans = max(ans, cnt - (days - m) * (days - m + 1) // 2)
		days -= a[i]
		cnt -= a[i] * (a[i] + 1) // 2
		i += 1
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


def rangesum(i, j):
	return int((j - i + 1) * (i + j) / 2)
(n, x) = list(map(int, input().split(' ')))
D = list(map(int, input().split(' ')))
maximum = max(D)
hugs = 0
i = 0
i_days = None
while True:
	if D[i] >= x:
		hugs += int((D[i] + (D[i] - x + 1)) / 2 * x)
		i_days = x
		break
	else:
		hugs += int(D[i] * (D[i] + 1) / 2)
		x -= D[i]
		i -= 1
maxHugs = hugs
for j in range(1, n):
	hugs += int(D[j] * (D[j] + 1) / 2)
	if i_days >= D[j]:
		hugs -= rangesum(D[i] - i_days + 1, D[i] - i_days + D[j])
		i_days -= D[j]
	else:
		hugs -= rangesum(D[i] - i_days + 1, D[i])
		i += 1
		y = D[j] - i_days
		while True:
			if D[i] >= y:
				i_days = D[i] - y
				hugs -= rangesum(1, y)
				break
			else:
				y -= D[i]
				hugs -= rangesum(1, D[i])
				i += 1
	maxHugs = max(hugs, maxHugs)
print(int(maxHugs))


import sys
from collections import deque
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]

def main():
	(n, x) = MI()
	dd = LI() * 2
	n *= 2
	i = 0
	ans = 0
	c = 0
	s = 0
	q = deque()
	while 1:
		while c < x and i < n:
			c += dd[i]
			s += dd[i] * (dd[i] + 1) // 2
			q.append(dd[i])
			i += 1
		if c < x:
			break
		while c - q[0] >= x:
			d = q.popleft()
			c -= d
			s -= d * (d + 1) // 2
		r = c - x
		cur = s - r * (r + 1) // 2
		if cur > ans:
			ans = cur
		d = q.popleft()
		c -= d
		s -= d * (d + 1) // 2
	print(ans)
main()


(n, x) = [int(a) for a in input().split()]
d = [int(a) for a in input().split()]
d += d
i = n
j = n
s = 0
ans = 0
hug = 0
while s < x:
	i -= 1
	hug += d[i] * (d[i] + 1) // 2
	s += d[i]
while j < len(d):
	while s < x and j < len(d):
		s += d[j]
		hug += d[j] * (d[j] + 1) // 2
		j += 1
	while s - d[i] >= x:
		s -= d[i]
		hug -= d[i] * (d[i] + 1) // 2
		i += 1
	rm = s - x
	hugs = hug - rm * (rm + 1) // 2
	ans = max(ans, hugs)
	s -= d[i]
	hug -= d[i] * (d[i] + 1) // 2
	i += 1
print(ans)


def _sum(f, t):
	return t * (t + 1) // 2 - f * (f - 1) // 2
(n, x) = map(int, input().split())
a = list(map(int, input().split()))
a += a
l = r = n
lf = -1
total = x
curr = 0
while total:
	lf = max(a[l] - total + 1, 1)
	curr += _sum(lf, a[l])
	total -= a[l] - lf + 1
	if total:
		l -= 1
sol = curr
while r + 1 < 2 * n:
	r += 1
	curr += _sum(1, a[r])
	total -= a[r]
	while total < 0:
		if a[l] - lf + 1 == -total:
			curr -= _sum(lf, a[l])
			total = 0
			lf = 1
			l += 1
		elif a[l] - lf + 1 > -total:
			curr -= _sum(lf, lf - total - 1)
			lf -= total
			total = 0
		else:
			curr -= _sum(lf, a[l])
			total += a[l] - lf + 1
			lf = 1
			l += 1
	sol = max(sol, curr)
print(sol)


import sys
import os
import heapq
import math
try:
	path = './file/input.txt'
	if os.path.exists(path):
		sys.stdin = open(path, 'r')
except:
	pass
t = 1

def printd(value):
	pass

def case():
	arr = list(map(int, input().split(' ')))
	(n, x) = (arr[0], arr[1])
	arr = list(map(int, input().split(' ')))
	arr = arr * 2
	result = [0] * len(arr)
	total = [0] * len(arr)
	left = 0
	right = 0
	sum = arr[0]
	result[0] = arr[0]
	total[0] += int((1 + arr[0]) * arr[0] / 2)
	while right < n * 2:
		right += 1
		if right >= n * 2:
			break
		total[right] = total[right - 1]
		sum += arr[right]
		result[right] = sum
		total[right] += int((1 + arr[right]) * arr[right] / 2)
		while left < right and sum - arr[left] > x:
			sum -= arr[left]
			total[right] -= int((1 + arr[left]) * arr[left] / 2)
			result[right] = sum
			left += 1
	answer = 0
	for index in range(n * 2):
		if result[index] >= x:
			diff = result[index] - x
			value = total[index] - int((1 + diff) * diff / 2)
			answer = max(answer, value)
	print(answer)
for _ in range(t):
	case()


import sys
from bisect import *
from itertools import accumulate
INT_MAX = sys.maxsize
INT_MIN = -sys.maxsize - 1
mod = 1000000007
lcm = lambda a, b: a * b // gcd(a, b)
setbit = lambda x: bin(x)[2:].count('1')
Sum = lambda i: i * (i + 1) // 2

def solve():
	(n, x) = map(int, sys.stdin.readline().split())
	a = list(map(int, sys.stdin.readline().split()))
	a = a + a
	aa = [Sum(i) for i in a]
	n = len(a)
	Prefix_a = [0] + list(accumulate(a))
	Prefix_suma = [0] + list(accumulate(aa))
	ans = 0
	for i in range(n):
		if Prefix_a[i + 1] >= x:
			z = bisect_right(Prefix_a, Prefix_a[i + 1] - x)
			cnt = Prefix_suma[i + 1] - Prefix_suma[z]
			days = Prefix_a[i + 1] - Prefix_a[z]
			too = x - days
			cnt += Sum(a[z - 1])
			cnt -= Sum(a[z - 1] - too)
			ans = max(ans, cnt)
	print(ans)
solve()


import bisect
(n, days) = map(int, input().strip().split())
arr = list(map(int, input().strip().split()))
arr = arr + arr
pre1 = [0]
pre2 = [0]
res = 0
for i in range(2 * n):
	pre1.append(pre1[-1] + arr[i])
	pre2.append(pre2[-1] + arr[i] * (arr[i] + 1) // 2)
for i in range(2 * n, n, -1):
	l = 1
	r = i
	ans = i
	while l <= r:
		mid = l + (r - l) // 2
		if pre1[i] - pre1[mid - 1] > days:
			l = mid + 1
		elif pre1[i] - pre1[mid - 1] <= days:
			ans = mid
			r = mid - 1
	if pre1[i] - pre1[ans - 1] < days and ans >= 0:
		ans -= 1
	tot = pre1[i] - pre1[ans - 1] - days
	temp = pre2[i] - pre2[ans - 1] - tot * (tot + 1) // 2
	res = max(res, temp)
print(res)


from sys import stdin, gettrace
if not gettrace():

	def input():
		return next(stdin)[:-1]

def main():
	(n, x) = map(int, input().split())
	dd = [int(a) for a in input().split()]
	ddh = []
	ddd = [0]
	for i in range(n):
		ddh.append(dd[i] * (dd[i] + 1) // 2)
	for i in range(2 * n):
		ddd.append(dd[i % n] + ddd[-1])
	best = 0
	hugs = 0
	l = 1
	r = 1
	while ddd[r] < x:
		hugs += ddh[(r - 1) % n]
		r += 1
	while r < n * 2:
		hugs += ddh[(r - 1) % n]
		firstday = ddd[r] - x
		while firstday >= ddd[l]:
			hugs -= ddh[(l - 1) % n]
			l += 1
		lostdays = dd[(l - 1) % n] - (ddd[l] - firstday)
		h = hugs - lostdays * (lostdays + 1) // 2
		best = max(best, h)
		r += 1
	print(best)
main()


from bisect import bisect_right
import sys
ints = (int(x) for x in sys.stdin.read().split())
sys.setrecursionlimit(3000)

def main():
	(n, x) = (next(ints) for i in range(2))
	d = [next(ints) for i in range(n)]
	d += d
	d = d[::-1]
	ans = 0
	D = [0] * (2 * n + 1)
	C = [0] * (2 * n + 1)
	for i in range(2 * n):
		D[i + 1] = D[i] + d[i]
		C[i + 1] = C[i] + d[i] * (d[i] + 1) // 2
	for i in range(n):
		j = bisect_right(D, D[i] + x) - 1
		assert D[j] - D[i] <= x and (j + 1 == 2 * n or C[j + 1] - C[i] > x)
		(lo, hi) = (d[j] - (x - (D[j] - D[i])), d[j])
		ans = max(ans, C[j] - C[i] + (hi * (hi + 1) - lo * (lo + 1)) // 2)
	print(ans)
	return
main()


import io
import os
import functools
import itertools
import math
import collections
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def prog(n):
	return (1 + n) * n // 2
(n, x) = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]
arr = a * 2
qu = collections.deque()
(q, s) = (0, 0)
answer = 0
for i in arr:
	while q >= x:
		answer = max(answer, s - prog(q - x))
		p = qu[0]
		qu.popleft()
		q -= p
		s -= prog(p)
	if i >= x:
		qu.clear()
		qu.append(i)
		answer = max(answer, prog(i) - prog(i - x))
		s = prog(i)
		q = i
	else:
		qu.append(i)
		q += i
		s += prog(i)
		if q >= x:
			answer = max(answer, s - prog(q - x))
print(answer)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
e = [d[i] for i in range(n)]
f = [d[i] for i in range(n)]
g = [d[i] * (d[i] + 1) // 2 for i in range(n)]
h = [d[i] * (d[i] + 1) // 2 for i in range(n)]
a = [d[i] for i in range(n)]
for i in range(1, n):
	d[i] += d[i - 1]
for i in range(n - 2, -1, -1):
	e[i] += e[i + 1]
for i in range(1, n):
	g[i] += g[i - 1]
for i in range(n - 2, -1, -1):
	h[i] += h[i + 1]
ans = 0
for i in range(n):
	test = x
	res = 0
	if test > d[i]:
		test -= d[i]
		start = 0
		end = n - 1
		while end - start > 1:
			t = (end + start) // 2
			if test >= e[t]:
				end = t
			else:
				start = t
		if test >= e[start]:
			val = start
		elif test >= e[end]:
			val = end
		else:
			val = n
		res += g[i]
		if val != n:
			res += h[val]
			test -= e[val]
		res += test * (2 * a[val - 1] - test + 1) // 2
		ans = max(ans, res)
	else:
		start = 0
		end = i
		while end - start > 1:
			t = (end + start) // 2
			if test >= d[i] - d[t]:
				end = t
			else:
				start = t
		if test >= d[i] - d[start]:
			val = start
		else:
			val = end
		res += g[i] - g[val]
		test -= d[i] - d[val]
		res += test * (2 * a[val] - test + 1) // 2
		ans = max(ans, res)
print(ans)


import sys
input = sys.stdin.buffer.readline
from bisect import bisect_left, bisect_right
(N, x) = map(int, input().split())
A = list(map(int, input().split()))
B = A + A
C = [0] * (2 * N)
C[0] = A[0] * (A[0] + 1) // 2
for i in range(1, 2 * N):
	C[i] = C[i - 1] + B[i] * (B[i] + 1) // 2
	B[i] += B[i - 1]
ans = 0
for i in range(N, 2 * N):
	b = B[i]
	ind = bisect_left(B, b - x)
	a = A[ind - N]
	d = a - (B[ind] - (b - x))
	score = C[i] - C[ind] + (a * (a + 1) // 2 - d * (d + 1) // 2)
	if score > ans:
		ans = score
print(ans)


(n, x) = list(map(int, input().split()))
arr = list(map(int, input().split()))
arr = arr * 2
i = 0
j = 0
days = 0
res = 0
ans = 0
while i < n:
	while days < x:
		days += arr[j]
		res += arr[j] * (arr[j] + 1) // 2
		j += 1
	e = days - x
	temp = res - e * (e + 1) // 2
	ans = max(ans, temp)
	days -= arr[i]
	res -= arr[i] * (arr[i] + 1) // 2
	i += 1
print(ans)


from sys import stdin, gettrace
if not gettrace():

	def input():
		return next(stdin)[:-1]

def main():

	def solve():
		(n, k) = map(int, input().split())
		li = [0] + [int(x) for x in input().split()]
		for i in range(n):
			li.append(li[i])
		pref1 = [0] * (2 * n + 1)
		pref2 = [0] * (2 * n + 1)
		pref1[1] = li[1] * (li[1] + 1) // 2
		pref2[1] = li[1]
		for i in range(2, 2 * n + 1):
			pref1[i] = pref1[i - 1] + li[i] * (li[i] + 1) // 2
			pref2[i] = pref2[i - 1] + li[i]
		mx = 0
		for i in range(2 * n, n - 1, -1):
			ans = i
			(low, high) = (0, i)
			while low <= high:
				mid = (low + high) // 2
				if pref2[i] - pref2[mid] < k:
					high = mid - 1
					ans = mid
				else:
					low = mid + 1
			rem = pref2[i] - pref2[ans - 1] - k
			val = pref1[i] - pref1[ans - 1] - rem * (rem + 1) // 2
			mx = max(val, mx)
		print(mx)
	solve()
main()


import sys, os, io
import bisect
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, x) = [int(i) for i in input().split()]
a = [int(i) for i in input().split()]
a += a
ansl = [i * (i + 1) // 2 for i in a] + [0]
cntl = a[:] + [0]
for i in range(1, len(cntl) - 1):
	cntl[i] += cntl[i - 1]
	ansl[i] += ansl[i - 1]
ans = 0
for i in range(n):
	cans = 0
	if x <= a[i]:
		rem = a[i] - x
		cans = a[i] * (a[i] + 1) // 2 - rem * (rem + 1) // 2
		ans = max(ans, cans)
		continue
	j = i + n
	indl = bisect.bisect_right(cntl, cntl[j] - x)
	cans = ansl[j] - ansl[indl]
	rem = x - (cntl[j] - cntl[indl])
	if indl >= n:
		indl -= n
	rem = a[indl] - rem
	cans += a[indl] * (a[indl] + 1) // 2 - rem * (rem + 1) // 2
	ans = max(ans, cans, rem)
print(ans)


import math
import collections
import bisect
import heapq
import time
import random
import itertools
import sys
from typing import List
(N, X) = map(int, input().split())
D = [int(x) for x in input().split()] * 2
H = [x * (x + 1) // 2 for x in D]
presum = [0]
preh = [0]
for v in D:
	presum.append(presum[-1] + v)
for v in H:
	preh.append(preh[-1] + v)
ans = 0
for i in range(N):
	d = D[i]
	s = bisect.bisect_right(presum, presum[i + 1] + X - d, i + 1)
	right = presum[s] - presum[i + 1]
	curr = X - right
	hugs = curr * (d + d - curr + 1) // 2 + preh[s] - preh[i + 1]
	ans = max(ans, hugs)
print(ans)


def sum_first(di):
	return di * (di + 1) // 2
(n, x) = list(map(int, input().split()))
n *= 2
d = tuple(map(int, input().split())) * 2
ans = 0
i = 0
j = 0
cur_ans = 0
total_days = 0
while j <= n:
	if total_days < x:
		if j == n:
			break
		cur_ans += sum_first(d[j])
		total_days += d[j]
		j += 1
	else:
		ans = max(ans, cur_ans - sum_first(total_days - x))
		cur_ans -= sum_first(d[i])
		total_days -= d[i]
		i += 1
print(ans)


(n, k) = map(int, input().split())
s = map(int, input().split())
s = list(s)
s = s + s
count = SUM = 0

def f(a, b):
	return (a + b) * (b - a + 1) // 2
for (i, x) in enumerate(s):
	if count + x >= k:
		break
	count += x
	SUM += f(1, x)
j = i
i = 0
MAX = -float('inf')
remain = s[0]
for j in range(j, len(s)):
	count += s[j]
	SUM += f(1, s[j])
	count -= remain
	SUM -= f(s[i] - remain + 1, s[i])
	while i != j and count >= k:
		i += 1
		count -= s[i]
		SUM -= f(1, s[i])
	remain = k - count
	SUM += f(s[i] - remain + 1, s[i])
	count = k
	MAX = max(MAX, SUM)
print(MAX)


import sys
buff_readline = sys.stdin.readline
readline = sys.stdin.readline
INF = 2 ** 62 - 1

def read_int():
	return int(buff_readline())

def read_int_n():
	return list(map(int, buff_readline().split()))

def read_float():
	return float(buff_readline())

def read_float_n():
	return list(map(float, buff_readline().split()))

def read_str():
	return readline().strip()

def read_str_n():
	return readline().strip().split()

def error_print(*args):
	print(*args, file=sys.stderr)

def mt(f):
	import time

	def wrap(*args, **kwargs):
		s = time.time()
		ret = f(*args, **kwargs)
		e = time.time()
		error_print(e - s, 'sec')
		return ret
	return wrap

class Bisect:

	def __init__(self, func):
		self.__func = func

	def bisect_left(self, x, lo, hi):
		while lo < hi:
			mid = (lo + hi) // 2
			if self.__func(mid) < x:
				lo = mid + 1
			else:
				hi = mid
		return lo

	def bisect_right(self, x, lo, hi):
		while lo < hi:
			mid = (lo + hi) // 2
			if x < self.__func(mid):
				hi = mid
			else:
				lo = mid + 1
		return lo

def slv(N, X, D):

	def f(n):
		return (n ** 2 + n) // 2
	yh = sum(map(f, D))
	yn = sum(D)
	D.reverse()
	D += D
	sd = [0]
	sh = [0]
	for d in D:
		sd.append(sd[-1] + d)
		sh.append(sh[-1] + f(d))
	o = X // yn * yh
	X %= yn
	ans = 0
	for i in range(N):
		j = Bisect(lambda x: sd[x] - sd[i]).bisect_left(X + 1, i, i + N)
		u = sd[j] - sd[i]
		r = u - X
		t = sh[j - 1] - sh[i] + f(D[j - 1]) - f(r)
		ans = max(ans, o + t)
	return ans

def main():
	(N, X) = read_int_n()
	D = read_int_n()
	print(slv(N, X, D))
main()


(n, x) = map(int, input().split())
d = list(map(int, input().split())) * 3
d.reverse
e = [i * (i + 1) // 2 for i in d]

def f(a, b):
	c = a - b
	return a * (a + 1) // 2 - c * (c + 1) // 2
ss = 0
ee = 0
whole = d[ee]
tsol = e[ee]
while True:
	ee += 1
	if whole + d[ee] > x:
		ee -= 1
		break
	whole += d[ee]
	tsol += e[ee]
tend = f(d[ee + 1], x - whole)
tsol += tend
sol = tsol
while ss < n:
	whole -= d[ss]
	tsol -= e[ss] + tend
	ss += 1
	while True:
		ee += 1
		if whole + d[ee] > x:
			ee -= 1
			break
		whole += d[ee]
		tsol += e[ee]
	tend = f(d[ee + 1], x - whole)
	tsol += tend
	sol = max(tsol, sol)
print(sol)


from bisect import bisect_left as bisect
from itertools import accumulate

def solve(n: int, x: int, d: map) -> int:
	days = [k for k in d] * 2
	running_days = list(accumulate(days))
	running_hugs = list(accumulate((k * (k + 1) // 2 for k in days)))
	n = len(days)
	max_hugs = 0
	for i in range(n):
		start_day = running_days[i] - x
		if start_day < 0:
			continue
		start_month = bisect(running_days, start_day, 0, i)
		month_day = days[start_month] - (running_days[start_month] - start_day)
		hugs = running_hugs[i] if start_month == 0 else running_hugs[i] - running_hugs[start_month - 1]
		hugs -= month_day * (month_day + 1) // 2
		max_hugs = max(max_hugs, hugs)
	return max_hugs

def _test():
	assert 5 == solve(3, 2, [1, 3, 1])
	assert 12 == solve(3, 6, [3, 3, 3])
	assert 15 == solve(5, 6, [4, 2, 3, 1, 3])
(n, x) = map(int, input().split())
print(solve(n, x, map(int, input().split())))


from collections import defaultdict as dd
import math
import sys
import heapq
import copy
input = sys.stdin.readline

def nn():
	return int(input())

def li():
	return list(input())

def mi():
	return map(int, input().split())

def lm():
	return list(map(int, input().split()))
(n, x) = mi()
cal = lm()
cal_copy = copy.deepcopy(cal)
end_mo = n - 1
start_mo = n - 1
remaining = x
hugs = 0
max_hugs = 0
while cal[start_mo] <= remaining:
	hugs += cal[start_mo] * (cal[start_mo] + 1) // 2
	remaining -= cal[start_mo]
	start_mo = (start_mo - 1) % n
lost = cal[start_mo] - remaining
hugs += cal[start_mo] * (cal[start_mo] + 1) // 2 - lost * (lost + 1) // 2
cal[start_mo] = lost
max_hugs = max(hugs, max_hugs)
for i in reversed(range(0, n - 1)):
	end_mo = i
	hugs -= cal_copy[end_mo + 1] * (cal_copy[end_mo + 1] + 1) // 2
	remaining = cal_copy[end_mo + 1]
	while cal[start_mo] <= remaining:
		hugs += cal[start_mo] * (cal[start_mo] + 1) // 2
		remaining -= cal[start_mo]
		start_mo = (start_mo - 1) % n
	lost = cal[start_mo] - remaining
	hugs += cal[start_mo] * (cal[start_mo] + 1) // 2 - lost * (lost + 1) // 2
	cal[start_mo] = lost
	max_hugs = max(hugs, max_hugs)
print(max_hugs)


import sys
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.buffer.readline())

def MI():
	return map(int, sys.stdin.buffer.readline().split())

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def BI():
	return sys.stdin.buffer.readline().rstrip()

def SI():
	return sys.stdin.buffer.readline().rstrip().decode()

def li():
	return [int(i) for i in input().split()]

def lli(rows):
	return [li() for _ in range(rows)]

def si():
	return input()

def ii():
	return int(input())

def ins():
	return input().split()
(n, x) = MI()
days = LI()
vals = [x * (x + 1) // 2 for x in days]
(ans, temp) = (0, 0)
(i, j, rem) = (0, 0, x)
for i in range(n):
	while rem > days[j]:
		rem -= days[j]
		temp += vals[j]
		j = (j + 1) % n
	if rem == days[j]:
		ans = max(ans, temp + vals[j])
		if i != j:
			rem += days[i]
			temp -= vals[i]
		else:
			j = (j + 1) % n
	elif i == j:
		left = days[i] - rem
		curr = vals[i] - left * (left + 1) // 2
		ans = max(ans, curr)
		j = (j + 1) % n
	else:
		shift = min(days[i] - 1, days[j] - rem)
		change = (shift + rem) * (shift + rem + 1) // 2 - shift * (shift + 1) // 2
		ans = max(ans, temp + change)
		rem += days[i]
		temp -= vals[i]
print(ans)


from bisect import bisect_right
(n, k) = map(int, input().split())
ar = [int(x) for x in input().split()]
ar = ar * 2
pref1 = []
pref2 = []
for i in range(len(ar)):
	if i == 0:
		pref1.append(ar[i] * (ar[i] + 1) // 2)
		pref2.append(ar[i])
	else:
		pref1.append(pref1[i - 1] + ar[i] * (ar[i] + 1) // 2)
		pref2.append(pref2[i - 1] + ar[i])
ans = 0
for i in range(len(ar) - 1, -1, -1):
	pos = bisect_right(pref2, pref2[i] - k)
	val = pref1[i] - pref1[pos]
	d = pref2[pos] - (pref2[i] - k)
	if pos == 0:
		break
	if d <= ar[pos]:
		v = pref1[pos] - pref1[pos - 1]
		s = (ar[pos] - d) * (ar[pos] - d + 1) // 2
		v -= s
		val += v
		ans = max(ans, val)
print(ans)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
(i, j, days, t, ans) = (0, 0, 0, 0, 0)
for i in range(n):
	while days < x:
		days += d[j]
		t += d[j] * (d[j] + 1) // 2
		j = (j + 1) % n
	ans = max(ans, t - (days - x) * (days - x + 1) // 2)
	days -= d[i]
	t -= d[i] * (d[i] + 1) // 2
	i += 1
print(ans)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
(m, i) = (0, 0)
(m2, i2) = (0, x)
s = 0
while i2 > d[m2]:
	i2 -= d[m2]
	s += d[m2] * (d[m2] + 1) // 2
	m2 += 1
s += i2 * (i2 + 1) // 2
res = s
while m < n:
	a = min(d[m2] - i2, d[m] - i)
	s += a * (i2 - i)
	res = max(res, s)
	i += a
	i2 += a
	if i >= d[m]:
		i = 0
		m += 1
	if i2 >= d[m2]:
		i2 = 0
		m2 = (m2 + 1) % n
print(res)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
(n, x) = map(int, input().split())
l = list(map(int, input().split()))
from bisect import bisect_left
l = 2 * l
l1 = []
l2 = []
(c, d) = (0, 0)
for i in range(2 * n):
	c += l[i]
	d += l[i] * (l[i] + 1) // 2
	l1.append(c)
	l2.append(d)
ans = 0
for i in range(n):
	a = bisect_left(l1, l1[i] + x - l[i])
	if a != 2 * n:
		b = l1[a] - l1[i] + l[i] - x
		ans = max(ans, l2[a] - l2[i] + l[i] * (l[i] + 1) // 2 - b * (b + 1) // 2)
print(ans)


def sumprog(a, b):
	return (a + b) * (b - a + 1) // 2
(n, x) = map(int, input().split())
d = list(map(int, input().split())) * 2
max_hugs = 0
i = 0
j = 0
days = 0
hugs = 0
while i < n:
	if days + d[j] <= x:
		days += d[j]
		hugs += sumprog(1, d[j])
		j += 1
	else:
		max_hugs = max(max_hugs, hugs + sumprog(d[j] - (x - days) + 1, d[j]))
		hugs -= sumprog(1, d[i])
		days -= d[i]
		i += 1
print(max_hugs)


(n, x) = map(int, input().split())
arr = list(map(int, input().split()))
i = j = su = hu = an = 0
su += arr[j % n]
hu += su * (su + 1) // 2
while i != n:
	while su < x:
		j += 1
		su += arr[j % n]
		hu += arr[j % n] * (arr[j % n] + 1) // 2
	if arr[i] > su - x:
		hu1 = hu
		y = su - x
		hu1 -= y * (y + 1) // 2
		an = max(hu1, an)
	su -= arr[i]
	hu -= arr[i] * (arr[i] + 1) // 2
	i += 1
print(an)


from sys import stdin
(n, x) = [int(x) for x in stdin.readline().split()]
month = [int(x) for x in stdin.readline().split()] * 2
high = max(month)
xCur = x
total = 0
start = 0
end = 0
best = 0
while start < n and end < len(month) - 1:
	while xCur >= 0 and end < len(month) - 1:
		xCur -= month[end]
		total += month[end] * (month[end] + 1) // 2
		end += 1
	tempTotal = total
	while xCur < 0:
		if -xCur <= month[start]:
			tempTotal -= -xCur * (-xCur + 1) // 2
			total -= month[start] * (month[start] + 1) // 2
			xCur += month[start]
			start += 1
		else:
			tempTotal -= month[start] * (month[start] + 1) // 2
			total -= month[start] * (month[start] + 1) // 2
			xCur += month[start]
			start += 1
	best = max(best, tempTotal)
print(best)


import bisect
(n, x) = map(int, input().split())
days = list(map(int, input().split()))
days = days * 2
ds = []
ms = []
for i in days:
	if ds == []:
		ds.append(i * (i + 1) // 2)
	else:
		ds.append(ds[-1] + i * (i + 1) // 2)
	if ms == []:
		ms.append(i)
	else:
		ms.append(ms[-1] + i)
i = 2 * n - 1
ans = 0
while i > n - 1:
	ind = bisect.bisect_right(ms, ms[i] - x) - 1
	ans = max(ans, ds[i] - ds[ind] - (ms[i] - ms[ind] - x) * (ms[i] - ms[ind] - x + 1) // 2)
	i -= 1
print(ans)


import sys, math, cmath, time
start_time = time.time()
global tt

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	return input().strip()

def invr():
	return map(int, input().split())

def solve():
	(n, x) = invr()
	a = inlt()
	a = a + a + a
	qw = q = w = 0
	j = n - 1
	for i in reversed(range(n)):
		while a[j] + q <= x:
			q += a[j]
			w += a[j] * (a[j] + 1) // 2
			j -= 1
		ww = (x - q) * (q - x + a[j] * 2 + 1) // 2 + w
		qw = max(qw, ww)
		if j < i:
			q -= a[i]
			w -= a[i] * (a[i] + 1) // 2
		else:
			j = j - 1
	print(qw)

def main():
	global tt
	if not ONLINE_JUDGE:
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	t = 1
	for tt in range(t):
		solve()
	if not ONLINE_JUDGE:
		print('Time Elapsed :', time.time() - start_time, 'seconds')
	sys.stdout.close()

def counter(a):
	q = [0] * max(a)
	for i in range(len(a)):
		q[a[i] - 1] = q[a[i] - 1] + 1
	return q

def string_counter(a):
	q = [0] * 26
	for i in range(len(a)):
		q[ord(a[i]) - 97] = q[ord(a[i]) - 97] + 1
	return q
ONLINE_JUDGE = __debug__
if ONLINE_JUDGE:
	input = sys.stdin.readline
main()


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline()

def RL():
	return map(int, sys.stdin.readline().split())

def RLL():
	return list(map(int, sys.stdin.readline().split()))

def N():
	return int(input())

def S():
	return input().strip()

def print_list(l):
	print(' '.join(map(str, l)))
from collections import deque as dq
(n, x) = RL()
d = RLL() * 2
q = dq()
(i, now, hug) = (n, 0, 0)
while now < x:
	h = d[i] * (d[i] + 1) >> 1
	q.appendleft((d[i], h))
	now += d[i]
	hug += h
	i -= 1
hh = (now - x) * (now - x + 1) >> 1
res = hug - hh
for i in range(n + 1, n * 2):
	h = d[i] * (d[i] + 1) >> 1
	q.append((d[i], h))
	now += d[i]
	hug += h
	while now - q[0][0] >= x:
		(dd, dh) = q.popleft()
		now -= dd
		hug -= dh
	hh = (now - x) * (now - x + 1) >> 1
	res = max(res, hug - hh)
print(res)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d = d + d
cumulative_days = [0]
cumulative_total = [0]
for i in d:
	cumulative_days.append(cumulative_days[-1] + i)
	cumulative_total.append(cumulative_total[-1] + i * (i + 1) // 2)
left = 1
right = 1
max_hugs = 0
while True:
	if cumulative_days[right] - cumulative_days[left - 1] < x:
		right += 1
		if right == len(cumulative_days):
			break
	else:
		left += 1
		if cumulative_days[right] - cumulative_days[left - 1] < x:
			extra_days = cumulative_days[right] - cumulative_days[left - 2] - x
			num_hugs = cumulative_total[right] - cumulative_total[left - 2] - extra_days * (extra_days + 1) // 2
			max_hugs = max(max_hugs, num_hugs)
print(max_hugs)


from collections import deque
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
q = deque([])
sum_q = 0
sq = deque([])
sum_sq = 0
for i in range(n):
	q.append(d[i])
	sum_q += d[i]
	sq.append((d[i] + 1) * d[i] // 2)
	sum_sq += (d[i] + 1) * d[i] // 2
ans = 0
for i in range(n):
	q.append(d[i])
	sum_q += d[i]
	sq.append((d[i] + 1) * d[i] // 2)
	sum_sq += (d[i] + 1) * d[i] // 2
	while sum_q - q[0] >= x:
		sum_q -= q.popleft()
		sum_sq -= sq.popleft()
	origin = sum_sq - sq[0]
	remday = x - (sum_q - q[0])
	differ = (q[0] + q[0] - remday + 1) * remday // 2
	ans = max(ans, origin + differ)
print(ans)


import sys
from collections import deque

def calcVal(v):
	return v * (v + 1) // 2
(n, x) = map(int, input().split())
d = 2 * list(map(int, input().split()))
dval = list(map(calcVal, d))
xstart = 1
xstartMonth = 0
xstartMonthVal = d[0]
xend = 0
maxV = 0
valBefore = 0
for i in range(2 * n):
	xend += d[i]
	valBefore += dval[i]
	if xend - xstart + 1 > x:
		while xend - xstartMonthVal + 1 > x:
			valBefore -= dval[xstartMonth]
			xstart = xstartMonthVal + 1
			xstartMonth += 1
			xstartMonthVal += d[xstartMonth]
		tmp = xend - x + 1
		valBefore -= calcVal(tmp - xstart)
		dval[xstartMonth] = dval[xstartMonth] - calcVal(tmp - xstart)
		xstart = tmp
	maxV = max(maxV, valBefore)
print(maxV)


(N, X) = [int(_) for _ in input().split()]
D = [int(_) for _ in input().split()]
days_per_year = sum(D)
year_value = sum([d * (d + 1) // 2 for d in D])
answer = year_value * (X // days_per_year)
X = X % days_per_year
answer_year = 0
i = N
pm = N - 1
pd = D[N - 1]
c = 0
to_add = None
while i >= 0:
	if i < N:
		c -= D[i] * (D[i] + 1) // 2
	if to_add is None:
		to_add = X
	else:
		to_add = D[i]
	while D[pm] - (D[pm] - pd) <= to_add:
		to_add -= D[pm] - (D[pm] - pd)
		c += pd * (pd + 1) // 2
		pm -= 1
		if pm < 0:
			pm = N - 1
		pd = D[pm]
	h = pd
	pd -= to_add
	l = pd
	c += h * (h + 1) // 2 - l * (l + 1) // 2
	answer_year = max(answer_year, c)
	i -= 1
answer += answer_year
print(answer)


(n, x) = map(int, input().split())
D = list(map(int, input().split()))
D += D
D = D[::-1]
Ans = []
d = 0
p = 0
q = -1
tot = 0
fin = []
for i in D:
	Ans.append(i * (i + 1) // 2)
while p < 2 * n and q < 2 * n:
	q += 1
	while p < 2 * n and q < 2 * n and (d + D[p] < x):
		d += D[p]
		tot += Ans[p]
		p += 1
	if p == q:
		k = D[p] - x + d
		tot += Ans[p] - k * (k + 1) // 2
		fin.append(tot)
		d = 0
		tot = 0
		p += 1
	elif p < 2 * n and q < 2 * n:
		k = D[p] - x + d
		tot += Ans[p] - k * (k + 1) // 2
		fin.append(tot)
		d -= min(D[q], d)
		tot -= Ans[q]
		tot -= Ans[p] - k * (k + 1) // 2
print(max(fin))


(n, x) = map(int, input().split())
arr = list(map(int, input().split()))
arr += arr
prefix = []
prefix1 = []
Sum = 0
for i in arr:
	Sum += i
	prefix.append(Sum)
Sum = 0
for j in arr:
	Sum += j * (j + 1) // 2
	prefix1.append(Sum)
ans = 0
for i in range(n * 2):
	A = prefix[i] - x
	if A <= 0:
		ans = prefix1[i]
	elif arr[i] >= x:
		jj = prefix1[i] - (arr[i] - x) * (arr[i] - x + 1) // 2
		if i - 1 >= 0:
			jj -= prefix1[i - 1]
		ans = max(ans, jj)
	else:
		l = 0
		r = i
		Ans = i
		while l <= r:
			mid = (l + r) // 2
			if prefix[mid] <= A:
				Ans = mid
				l = mid + 1
			else:
				r = mid - 1
		B = prefix[i] - prefix[Ans] - x
		ans = max(ans, prefix1[i] - prefix1[Ans] - B * (B + 1) // 2)
print(ans)


from sys import stdin, stdout

def the_best_vacation(n, x, d):
	i = j = days = hugs = res = 0
	while j < 2 * n:
		ci = i % n
		pi = (i - 1 + n) % n
		pj = j % n
		if d[pj] >= x:
			res = max(res, gethugs(d[pj] - x + 1, d[pj]))
			j += 1
			i = j
			continue
		r = x - days
		if days + d[pj] > x:
			if d[pi] > r:
				res = max(res, hugs + gethugs(d[pi] - r + 1, d[pi]))
			else:
				res = max(res, hugs + gethugs(1, r))
			days -= d[ci]
			hugs -= gethugs(1, d[ci])
			i += 1
		else:
			if days + d[pi] > x:
				res = max(res, hugs + gethugs(d[pi] - r + 1, d[pi]))
			days += d[pj]
			hugs += gethugs(1, d[pj])
			j += 1
	return res

def gethugs(a, b):
	return (a + b) * (b - a + 1) // 2
nx = list(map(int, stdin.readline().split()))
d = list(map(int, stdin.readline().split()))
stdout.write(str(the_best_vacation(nx[0], nx[1], d)) + '\n')


(n, x) = map(int, input().split())
a = list(map(int, input().split()))
l = r = 0
for i in range(n):
	a.append(a[i])

def fuckit(x):
	return (1 + x) * x // 2
ans = nowd = nows = 0
while r < 2 * n:
	nowd += a[r]
	nows += fuckit(a[r])
	r += 1
	while nowd - a[l] >= x:
		nowd -= a[l]
		nows -= fuckit(a[l])
		l += 1
	dif = max(0, nowd - x)
	ans = max(ans, nows - fuckit(dif))
print(ans)


from bisect import bisect_left as br
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d += d
import sys
input = sys.stdin.readline
prehugs = [0, d[0] * (d[0] + 1) // 2]
predays = [0, d[0]]
for i in range(1, 2 * n):
	prehugs += [prehugs[-1] + d[i] * (d[i] + 1) // 2]
	predays += [predays[-1] + d[i]]
ans = 0
for i in range(1, n + 1):
	find = predays[i - 1] + x
	ind = br(predays, find)
	hugs = prehugs[ind] - prehugs[i - 1]
	exdays = predays[ind] - predays[i - 1] - x
	ans = max(hugs - exdays * (exdays + 1) // 2, ans)
print(ans)


import sys
import math

def I():
	return int(sys.stdin.readline())

def ILT():
	return list(map(int, sys.stdin.readline().strip().split()))

def IL():
	return list(map(int, sys.stdin.readline().strip().split()))

def ILS():
	return list(map(str, sys.stdin.readline().strip().split()))
(n, v) = IL()
l = IL()
ll = []
year = 0
yearno = 0
for x in l:
	day = x * (x + 1) // 2
	year += day
	yearno += x
	ll.append(x)
ds = []
for xl in ll:
	ds.append(xl)
for xl in ll:
	ds.append(xl)
dds = []
for i in range(len(ds)):
	dds.append(ds[i] * (ds[i] + 1) // 2)
cum = []
val = 0
cum.append(val)
for y in ds:
	val += y
	cum.append(val)
cumd = []
val = 0
cumd.append(val)
for y in dds:
	val += y
	cumd.append(val)
ans = v // yearno * year
vac = v % yearno

def bn(st, en, val, cp):
	while st < en - 1:
		mid = (st + en) // 2
		if cum[mid] + val >= cp:
			en = mid
		else:
			st = mid
	return en
for i in range(len(l) + 1, len(cum)):
	st = i - len(l)
	en = i
	vall = vac
	cp = cum[i]
	while st < en - 1:
		mid = (st + en) // 2
		if cum[mid] + vall >= cp:
			en = mid
		else:
			st = mid
	en
	idx = en
	tans = cum[i] - cum[idx]
	tmpans = cumd[i] - cumd[idx]
	vleft = vac - tans
	if vleft > 0:
		tmpans += vleft * (2 * ds[idx - 1] + (vleft - 1) * -1) // 2
	ans = max(ans, tmpans)
print(ans)


import bisect
(n, k) = map(int, input().split())
l = list(map(int, input().split()))
l1 = []
l2 = []
l1.append(0)
l2.append(0)
for i in range(n, 2 * n):
	l.append(l[i - n])
for i in range(2 * n):
	l1.append(l[i] + l1[i])
	l2.append(l[i] * (l[i] + 1) // 2 + l2[i])
ans = 0
for i in range(2 * n):
	if l1[i + 1] >= k:
		cnt = 0
		z = bisect.bisect(l1, l1[i + 1] - k)
		cnt += l2[i + 1] - l2[z]
		day = k - (l1[i + 1] - l1[z])
		cnt += l[z - 1] * (l[z - 1] + 1) // 2
		cnt -= (l[z - 1] - day) * (l[z - 1] - day + 1) // 2
		ans = max(ans, cnt)
print(ans)


from sys import stdin
from math import gcd, sqrt
from collections import deque
input = stdin.readline
R = lambda : map(int, input().split())
I = lambda : int(input())
S = lambda : input().rstrip('\n')
(n, x) = R()
a = list(R())
s = a[-1]
p = 0
while s < x:
	a += (a[p],)
	s += a[p]
	p += 1
v = [(i ** 2 + i) // 2 for i in a]
(ans1, ans2) = ([], [])
s1 = s2 = m = 0
(e, e1) = (deque(), deque())
for i in range(len(a)):
	s1 += a[i]
	s2 += v[i]
	e.appendleft(a[i])
	e1.appendleft(v[i])
	if s1 >= x:
		while s1 - e[-1] >= x:
			s1 -= e.pop()
			s2 -= e1.pop()
		l = s1 - x
		m = max(m, s2 - (l ** 2 + l) // 2)
print(m)


import os, sys, atexit
from io import BytesIO, StringIO
input = BytesIO(os.read(0, os.fstat(0).st_size)).readline
_OUTPUT_BUFFER = StringIO()
sys.stdout = _OUTPUT_BUFFER

@atexit.register
def write():
	sys.__stdout__.write(_OUTPUT_BUFFER.getvalue())
(n, x) = map(int, input().split())
l = list(map(int, input().split()))
l = l + l
l.reverse()
n *= 2
tmp = [0] * n
for i in range(n):
	tmp[i] = l[i] * (l[i] + 1) // 2
cnt = 0
ans = 0
p1 = 0
t1 = 0
for i in range(n):
	cnt += l[i]
	t1 += tmp[i]
	while cnt > x:
		t2 = cnt - x
		a1 = t2 * (t2 + 1) // 2
		t1 -= a1
		ans = max(ans, t1)
		t1 += a1
		cnt -= l[p1]
		t1 -= tmp[p1]
		p1 -= -1
print(ans)


def sum_(x):
	return x * (x + 1) // 2
(n, x) = map(int, input().split())
arr = list(map(int, input().split()))
arr.extend(arr)
start = 0
window_sum = 0
days = 0
ans = 0
for i in arr:
	window_sum += sum_(i)
	days += i
	while days > x:
		window_sum -= sum_(arr[start])
		days -= arr[start]
		start += 1
	if start > 0:
		ans = max(ans, window_sum + sum_(arr[start - 1]) - sum_(arr[start - 1] - x + days))
print(ans)


from sys import stdin
input = stdin.readline
(n, m) = map(int, input().split())
d = [int(x) for x in input().split()] * 2
d.insert(0, 0)
dd = [0, d[1]]
ps = [0, d[1] * (d[1] + 1) // 2]
res = []
for x in d[2:]:
	dd.append(dd[-1] + x)
	ps.append(ps[-1] + x * (x + 1) // 2)
(p, w) = (1, 1)
for x in range(2 * n + 1):
	if m <= dd[x]:
		w = x
		break
for x in range(w, 2 * n + 1):
	while True:
		if m <= dd[x] - dd[p - 1] and m > dd[x] - dd[p]:
			break
		p += 1
	now1 = ps[x] - ps[p]
	now2 = dd[x] - dd[p]
	now3 = m - now2
	now4 = d[p]
	now5 = d[p] - now3
	now1 += d[p] * (d[p] + 1) // 2 - now5 * (now5 + 1) // 2
	res.append(now1)
print(max(res))


(n, x) = map(int, input().split())
a = list(map(int, input().split()))
a = a * 2
(l, r, ans) = (0, 1, 0)
su = a[0]
dp = a[0] * (a[0] + 1) // 2
while r <= 2 * n:
	if su >= x:
		st = l
		while su - a[l] >= x:
			su = su - a[l]
			dp = dp - a[l] * (a[l] + 1) // 2
			l = l + 1
		otv = dp
		otv = otv - (su - x) * (su - x + 1) // 2
		ans = max(ans, otv)
		su = su - a[l]
		dp = dp - a[l] * (a[l] + 1) // 2
		l = l + 1
	if r >= 2 * n:
		break
	su = su + a[r]
	dp = dp + a[r] * (a[r] + 1) // 2
	r = r + 1
print(ans)


(n, x) = [int(x) for x in input().split()]
d = [int(x) for x in input().split()]
dd = d + d

def b2(k):
	return k * (k + 1) // 2
end_pt = 0
days = 0
best = 0
cur_hugs = b2(dd[0])
while days + dd[end_pt] < x:
	days += dd[end_pt]
	end_pt += 1
	cur_hugs += b2(dd[end_pt])
start_pt = 0
start_day = days + dd[end_pt] - x + 1
while start_day > dd[start_pt]:
	start_day -= dd[start_pt]
	cur_hugs -= b2(dd[start_pt])
	start_pt += 1
cur_hugs -= b2(start_day - 1)
best = cur_hugs
if False:
	print('Initial:')
	print('dd = ', dd)
	print('end_month = ', end_pt)
	print('start_month = ', start_pt)
	print('start_day = ', start_day)
	print('cur_hugs = best = ', best)
while end_pt + 1 < len(dd):
	end_pt += 1
	cur_hugs += b2(dd[end_pt])
	cur_hugs += b2(start_day - 1)
	start_day += dd[end_pt]
	while start_day > dd[start_pt]:
		start_day -= dd[start_pt]
		cur_hugs -= b2(dd[start_pt])
		start_pt += 1
	cur_hugs -= b2(start_day - 1)
	best = max(best, cur_hugs)
print(best)


from fractions import Fraction
import bisect
import os
from collections import Counter
import bisect
from collections import defaultdict
import math
import random
import heapq as hq
from math import sqrt
import sys
from functools import reduce, cmp_to_key
from collections import deque
import threading
from itertools import combinations
from io import BytesIO, IOBase
from itertools import accumulate

def input():
	return sys.stdin.readline().strip()

def iinput():
	return int(input())

def tinput():
	return input().split()

def rinput():
	return map(int, tinput())

def rlinput():
	return list(rinput())
mod = int(1000000000.0) + 7

def factors(n):
	return set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))
t = 1

def ss(n):
	return n * (n + 1) // 2
for _ in range(t):
	(n, x) = rinput()
	a = rlinput()
	a = 2 * a
	ans = 0
	pref = list(accumulate(a))
	prefn = [0] * (2 * n)
	prefn[0] = a[0] * (a[0] + 1) // 2
	for i in range(1, 2 * n):
		prefn[i] = prefn[i - 1] + a[i] * (a[i] + 1) // 2
	for i in range(n, 2 * n):
		if a[i] >= x:
			ans = max(ans, ss(a[i]) - ss(a[i] - x))
		else:
			val = pref[i] - x
			newans = 0
			idx = bisect.bisect(pref, val)
			newans += prefn[i] - prefn[idx]
			want = x - pref[i] + pref[idx]
			newans += ss(a[idx]) - ss(a[idx] - want)
			ans = max(ans, newans)
	print(ans)


import sys
readline = sys.stdin.readline
ns = lambda : readline().rstrip()
ni = lambda : int(readline().rstrip())
nm = lambda : map(int, readline().split())
nl = lambda : list(map(int, readline().split()))

def solve():
	(n, x) = nm()
	d = nl() * 2
	f = [x * (x + 1) // 2 for x in d]
	for i in range(2 * n - 1):
		f[i + 1] += f[i]
	l = -1
	s = sum(d[:n])
	ans = 0
	for r in range(n, 2 * n):
		s += d[r]
		while s > x:
			l += 1
			s -= d[l]
		ans = max(ans, f[r] - f[l] + d[l] * (d[l] + 1) // 2 - (d[l] - x + s) * (d[l] - x + s + 1) // 2)
	print(ans)
	return
solve()


import bisect
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d *= 3
xx = 0
s = []
wa = []
s.append(0)
wa.append(0)
for i in range(2 * n):
	xx += d[2 * n - 1 - i]
	s.append(xx)
xx = 0
for i in range(2 * n):
	xx += d[2 * n - 1 - i] * (d[2 * n - 1 - i] + 1) // 2
	wa.append(xx)
ans = 0
aa = 0
for i in range(n):
	b = bisect.bisect(s, s[i] + x)
	zen = wa[b - 1] - wa[i]
	fix = s[b] - s[b - 1]
	fix2 = s[i] + x - s[b - 1]
	zen2 = fix2 * (2 * fix - fix2 + 1) // 2
	ans = max(ans, zen + zen2)
print(ans)


import sys
from bisect import bisect_right as br
(n, x) = map(int, sys.stdin.readline().split())
a = list(map(int, sys.stdin.readline().split()))
a.extend(a)
sun = lambda x: x * (x + 1) // 2
c = [a[0]]
d = [sun(a[0])]
for i in range(n * 2 - 1):
	c.append(c[i] + a[i + 1])
	d.append(d[i] + sun(a[i + 1]))
i = n * 2 - 1
ans = 0
for i in range(n * 2 - 1, n - 1, -1):
	j = br(c, c[i] - x) - 1
	ans = max(d[i] - d[j] - (c[i] - c[j] - x) * (c[i] - c[j] - x + 1) // 2, ans)
sys.stdout.write(f'{ans}')


import sys
from bisect import *
from math import floor, sqrt, ceil, factorial as F, gcd, pi
from itertools import chain, combinations, permutations, accumulate
from collections import Counter, defaultdict, OrderedDict, deque
from array import array
INT_MAX = sys.maxsize
INT_MIN = -sys.maxsize - 1
mod = 1000000007
lcm = lambda a, b: a * b // gcd(a, b)
setbit = lambda x: bin(x)[2:].count('1')
Sum = lambda i: i * (i + 1) // 2

def solve():
	(n, x) = map(int, sys.stdin.readline().split())
	a = list(map(int, sys.stdin.readline().split()))
	a = a + a
	aa = [Sum(i) for i in a]
	n = len(a)
	Prefix_a = [0] + list(accumulate(a))
	Prefix_suma = [0] + list(accumulate(aa))
	ans = 0
	for i in range(n):
		if Prefix_a[i + 1] >= x:
			z = bisect_right(Prefix_a, Prefix_a[i + 1] - x)
			cnt = Prefix_suma[i + 1] - Prefix_suma[z]
			days = Prefix_a[i + 1] - Prefix_a[z]
			too = x - days
			cnt += Sum(a[z - 1])
			cnt -= Sum(a[z - 1] - too)
			ans = max(ans, cnt)
	print(ans)
solve()


def solve(n, x, d):
	b = [d[0]]
	tmp = d[0] * (d[0] + 1) // 2
	c = [tmp]
	length = n
	ans = 0
	n *= 2
	for i in range(1, n):
		b.append(b[i - 1] + d[i % length])
		tmp = d[i % length] * (d[i % length] + 1) // 2
		c.append(tmp + c[i - 1])
	for i in range(n):
		l = 0
		r = i
		key = b[i] - x
		if key < 0:
			continue
		while l < r:
			mid = l + (r - l) // 2
			tmp = b[i] - b[mid]
			if tmp >= x:
				l = mid + 1
			else:
				r = mid
		cnts = c[i] - c[r - 1]
		diff = b[i] - b[r - 1]
		days = diff - x
		cnts -= days * (days + 1) // 2
		ans = max(cnts, ans)
	return ans

def main():
	(n, x) = list(map(int, input().split()))
	d = list(map(int, input().split()))
	ans = solve(n, x, d)
	print(ans)
main()


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
from collections import deque
import threading
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

class Factorial:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorials = [1, 1]
		self.invModulos = [0, 1]
		self.invFactorial_ = [1, 1]

	def calc(self, n):
		if n <= -1:
			print('Invalid argument to calculate n!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.factorials):
			return self.factorials[n]
		nextArr = [0] * (n + 1 - len(self.factorials))
		initialI = len(self.factorials)
		prev = self.factorials[-1]
		m = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * i % m
		self.factorials += nextArr
		return self.factorials[n]

	def inv(self, n):
		if n <= -1:
			print('Invalid argument to calculate n^(-1)')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		p = self.MOD
		pi = n % p
		if pi < len(self.invModulos):
			return self.invModulos[pi]
		nextArr = [0] * (n + 1 - len(self.invModulos))
		initialI = len(self.invModulos)
		for i in range(initialI, min(p, n + 1)):
			next = -self.invModulos[p % i] * (p // i) % p
			self.invModulos.append(next)
		return self.invModulos[pi]

	def invFactorial(self, n):
		if n <= -1:
			print('Invalid argument to calculate (n^(-1))!')
			print('n must be non-negative value. But the argument was ' + str(n))
			exit()
		if n < len(self.invFactorial_):
			return self.invFactorial_[n]
		self.inv(n)
		nextArr = [0] * (n + 1 - len(self.invFactorial_))
		initialI = len(self.invFactorial_)
		prev = self.invFactorial_[-1]
		p = self.MOD
		for i in range(initialI, n + 1):
			prev = nextArr[i - initialI] = prev * self.invModulos[i % p] % p
		self.invFactorial_ += nextArr
		return self.invFactorial_[n]

class Combination:

	def __init__(self, MOD):
		self.MOD = MOD
		self.factorial = Factorial(MOD)

	def ncr(self, n, k):
		if k < 0 or n < k:
			return 0
		k = min(k, n - k)
		f = self.factorial
		return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

def sum_first(di):
	return di * (di + 1) // 2
(n, x) = map(int, input().split())
n *= 2
d = tuple(map(int, input().split())) * 2
ans = 0
i = 0
j = 0
cur_ans = 0
total_days = 0
while j <= n:
	if total_days < x:
		if j == n:
			break
		cur_ans += sum_first(d[j])
		total_days += d[j]
		j += 1
	else:
		ans = max(ans, cur_ans - sum_first(total_days - x))
		cur_ans -= sum_first(d[i])
		total_days -= d[i]
		i += 1
print(ans)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d.extend(d)
k = c = 0
i = 2 * n - 1
a = x
j = i
if n == 1:
	print((2 * d[0] - a + 1) * a // 2)
else:
	while i >= n:
		while a > 0:
			if d[j] < a:
				c += d[j] * (d[j] + 1) // 2
				a -= d[j]
				j -= 1
			else:
				b = c + (2 * d[j] - a + 1) * a // 2
				if b > k:
					k = b
				if x - a >= d[i]:
					a += d[i]
					c -= d[i] * (d[i] + 1) // 2
				i -= 1
				if j > i:
					j = i
				break
	print(k)


import sys
input = sys.stdin.readline
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
mx = 0
i = n - 1
j = n - 1
k = 0
cursum = 0
miss = x
while d[j] < miss:
	miss -= d[j]
	cursum += d[j] * (d[j] + 1) // 2
	j -= 1
k = d[j] - miss
cursum += d[j] * (d[j] + 1) // 2
cursum -= k * (k + 1) // 2
miss = 0
mx = cursum
while i >= 0:
	miss = d[i]
	cursum -= d[i] * (d[i] + 1) // 2
	cursum += k * (k + 1) // 2
	cursum -= d[j] * (d[j] + 1) // 2
	miss -= k
	miss += d[j]
	while d[j] < miss:
		miss -= d[j]
		cursum += d[j] * (d[j] + 1) // 2
		j -= 1
		if j < 0:
			j = n - 1
	k = d[j] - miss
	cursum += d[j] * (d[j] + 1) // 2
	cursum -= k * (k + 1) // 2
	miss = 0
	mx = max(mx, cursum)
	i -= 1
print(mx)


from bisect import *
from collections import *
from math import gcd, ceil, sqrt, floor, inf
from heapq import *
from itertools import *
from operator import add, mul, sub, xor, truediv, floordiv
from functools import *
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())
from types import GeneratorType

def bootstrap(f, stack=[]):

	def wrappedfunc(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		else:
			to = f(*args, **kwargs)
			while True:
				if type(to) is GeneratorType:
					stack.append(to)
					to = next(to)
				else:
					stack.pop()
					if not stack:
						break
					to = stack[-1].send(to)
			return to
	return wrappedfunc
farr = [1]
ifa = []

def fact(x, mod=0):
	if mod:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr) % mod)
	else:
		while x >= len(farr):
			farr.append(farr[-1] * len(farr))
	return farr[x]

def ifact(x, mod):
	global ifa
	ifa.append(pow(farr[-1], mod - 2, mod))
	for i in range(x, 0, -1):
		ifa.append(ifa[-1] * i % mod)
	ifa = ifa[::-1]

def per(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return fact(i) // fact(i - j)
	return farr[i] * ifa[i - j] % mod

def com(i, j, mod=0):
	if i < j:
		return 0
	if not mod:
		return per(i, j) // fact(j)
	return per(i, j, mod) * ifa[j] % mod

def catalan(n):
	return com(2 * n, n) // (n + 1)

def isprime(n):
	for i in range(2, int(n ** 0.5) + 1):
		if n % i == 0:
			return False
	return True

def lowbit(n):
	return n & -n

def inverse(a, m):
	a %= m
	if a <= 1:
		return a
	return (1 - inverse(m, a) * m) // a % m

class BIT:

	def __init__(self, arr):
		self.arr = arr
		self.n = len(arr) - 1

	def update(self, x, v):
		while x <= self.n:
			self.arr[x] += v
			x += x & -x

	def query(self, x):
		ans = 0
		while x:
			ans += self.arr[x]
			x &= x - 1
		return ans

class DSU:

	def __init__(self, n):
		self.c = [-1] * n

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def find(self, x):
		if self.c[x] < 0:
			return x
		self.c[x] = self.find(self.c[x])
		return self.c[x]

	def union(self, u, v):
		(u, v) = (self.find(u), self.find(v))
		if u == v:
			return False
		if self.c[u] < self.c[v]:
			(u, v) = (v, u)
		self.c[u] += self.c[v]
		self.c[v] = u
		return True

	def size(self, x):
		return -self.c[self.find(x)]

class UFS:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.ranks = [0] * n

	def find(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find(self.parent[x])
		return self.parent[x]

	def union(self, u, v):
		(pu, pv) = (self.find(u), self.find(v))
		if pu == pv:
			return False
		if self.ranks[pu] >= self.ranks[pv]:
			self.parent[pv] = pu
			if self.ranks[pv] == self.ranks[pu]:
				self.ranks[pu] += 1
		else:
			self.parent[pu] = pv

def Prime(n):
	c = 0
	prime = []
	flag = [0] * (n + 1)
	for i in range(2, n + 1):
		if not flag[i]:
			prime.append(i)
			c += 1
		for j in range(c):
			if i * prime[j] > n:
				break
			flag[i * prime[j]] = prime[j]
			if i % prime[j] == 0:
				break
	return flag

def dij(s, graph):
	d = {}
	d[s] = 0
	heap = [(0, s)]
	seen = set()
	while heap:
		(dis, u) = heappop(heap)
		if u in seen:
			continue
		for v in graph[u]:
			if v not in d or d[v] > d[u] + graph[u][v]:
				d[v] = d[u] + graph[u][v]
				heappush(heap, (d[v], v))
	return d

def GP(it):
	return [[ch, len(list(g))] for (ch, g) in groupby(it)]

class DLN:

	def __init__(self, val):
		self.val = val
		self.pre = None
		self.next = None

def nb(i, j):
	for (ni, nj) in [[i + 1, j], [i - 1, j], [i, j - 1], [i, j + 1]]:
		if 0 <= ni < n and 0 <= nj < m:
			yield (ni, nj)

@bootstrap
def gdfs(r, p):
	if len(g[r]) == 1 and p != -1:
		yield None
	for ch in g[r]:
		if ch != p:
			yield gdfs(ch, r)
	yield None
t = 1
for i in range(t):
	(n, x) = RL()
	d = RLL()
	d = d + d
	pred = [0]
	preh = [0]
	for i in range(2 * n):
		pred.append(d[i] + pred[-1])
		preh.append(d[i] * (d[i] + 1) // 2 + preh[-1])
	ans = 0
	for i in range(2 * n):
		if pred[i + 1] >= x:
			l = 0
			r = i
			while l < r:
				mid = (l + r + 1) // 2
				if pred[i + 1] - pred[mid] >= x:
					l = mid
				else:
					r = mid - 1
			tmp = preh[i + 1] - preh[l]
			mis = pred[i + 1] - pred[l] - x
			tmp -= mis * (mis + 1) // 2
			ans = max(ans, tmp)
	print(ans)


import bisect
import os
import sys
from io import BytesIO, IOBase

def hugs(n):
	return n * (n + 1) // 2

def rem(n, i):
	return n * (n + 1) // 2 - (n - i) * (n + 1 - i) // 2

def within(x, D):
	A = list()
	for _ in range(2):
		for d in D:
			A.append(d)
	(i, j) = (0, len(A) - 1)
	while i < j:
		(A[i], A[j]) = (A[j], A[i])
		i += 1
		j -= 1
	P = [0] * len(A)
	H = [0] * len(A)
	(P[0], H[0]) = (A[0], hugs(A[0]))
	for i in range(1, len(A)):
		P[i] = P[i - 1] + A[i]
		H[i] = H[i - 1] + hugs(A[i])
	ans = -1
	for i in range(len(A)):
		if i == 0:
			pos = bisect.bisect_left(P, x)
			req = x
		else:
			pos = bisect.bisect_left(P, x + P[i - 1])
			req = x + P[i - 1]
		if pos == len(A):
			break
		if A[pos] == req:
			if pos == 0:
				ans = max(ans, H[0])
			else:
				ans = max(ans, H[pos] - H[i - 1])
		elif pos == 0:
			ans = max(ans, rem(A[0], req))
		elif i == 0:
			ans = max(ans, H[pos - 1] + rem(A[pos], req - P[pos - 1]))
		else:
			ans = max(ans, H[pos - 1] - H[i - 1] + rem(A[pos], req - P[pos - 1]))
	return ans

def main():
	(n, x) = map(int, input().split())
	D = list(map(int, input().split()))
	gMonth = max(D)
	year = sum(D)
	if x <= gMonth:
		ans = rem(gMonth, x)
	elif x < year:
		ans = within(x, D)
	else:
		yearHugs = 0
		for d in D:
			yearHugs += hugs(d)
		if x == year:
			ans = yearHugs
		else:
			(years, days) = divmod(x, year)
			ans = years * yearHugs + within(days, D)
	print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = lambda s: self.buffer.write(s.encode()) if self.writable else None

	def read(self):
		if self.buffer.tell():
			return self.buffer.read().decode('ascii')
		return os.read(self._fd, os.fstat(self._fd).st_size).decode('ascii')

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline().decode('ascii')

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

def print(*args, sep=' ', end='\n', file=sys.stdout, flush=False):
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(end)
	if flush:
		file.flush()
(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
sys.setrecursionlimit(10000)
main()


input = __import__('sys').stdin.readline
(n, x) = map(int, input().split())
lis = list(map(int, input().split()))
lis = lis + lis
pre = [0] * (2 * n + 5)
hug = [0] * (2 * n + 5)
pre[1] = lis[0]
hug[1] = lis[0] * (lis[0] + 1) // 2
for i in range(1, 2 * n):
	pre[i + 1] = pre[i] + lis[i]
	hug[i + 1] = hug[i] + lis[i] * (lis[i] + 1) // 2
ans = 0
for i in range(n + 1, 2 * n + 1):
	l = 0
	r = i
	while l <= r:
		mid = l + (r - l) // 2
		day = pre[i] - pre[mid]
		if day < x:
			r = mid - 1
		else:
			l = mid + 1
	tmp = hug[i] - hug[l]
	rem = x - pre[i] + pre[l]
	lef = pre[l] - pre[l - 1]
	tmp += hug[l] - hug[l - 1] - (lef - rem) * (lef - rem + 1) // 2
	ans = max(ans, tmp)
print(ans)


from bisect import *
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d.extend(d)
date_acc = [0]
tot_acc = [0]
for i in range(n * 2):
	date_acc.append(date_acc[i] + d[i])
	tot_acc.append(tot_acc[i] + d[i] * (d[i] + 1) // 2)
ans = 0
for i in range(n + 1, 2 * n + 1):
	now = date_acc[i]
	start_i = bisect_left(date_acc, now - x)
	start = date_acc[start_i]
	remain = x - (now - start)
	temp = tot_acc[i] - tot_acc[start_i]
	temp += remain * (2 * d[start_i - 1] - remain + 1) // 2
	ans = max(ans, temp)
print(ans)


import sys
from collections import defaultdict as dd

def eprint(*args):
	print(*args, file=sys.stderr)
zz = 1
from math import *
import copy
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')

def li():
	return [int(x) for x in input().split()]

def fi():
	return int(input())

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())

def bo(i):
	return ord(i) - ord('a')

def gooli(n):
	z = 0
	for i in range(1, n + 1):
		z += len(str(i))
	return z
(n, x) = mi()
a = [int(x) for x in input().split()]
cal = [0 for i in range(n)]

def bo(n):
	return (n * n + n) // 2 * int(n >= 0)
pre = [0 for i in range(n)]
pre[0] = a[0]
for i in range(1, n):
	pre[i] = pre[i - 1] + a[i]
pre.insert(0, 0)
res = [0 for i in range(n)]
res[0] = bo(a[0])
for i in range(1, n):
	res[i] = res[i - 1] + bo(a[i])

def bs(p, i):
	l = 0
	r = n
	ans = i
	if p <= 0:
		return -1
	while l <= r:
		mid = (l + r) // 2
		if pre[mid] - pre[i] <= p:
			ans = mid
			l = mid + 1
		else:
			r = mid - 1
	return ans

def left(i):
	l = 0
	p = x
	c = 0
	if pre[i + 1] < p:
		p -= pre[i + 1]
		c += res[i + 1]
		i = n - 1
	r = i
	ans = i
	while l <= r:
		mid = (l + r) // 2
		if pre[i + 1] - pre[mid] < p:
			r = mid - 1
		else:
			ans = mid
			l = mid + 1
	if ans == i:
		c += bo(a[i]) - bo(a[i] - p)
	else:
		c += res[i + 1] - res[ans + 1] + bo(a[ans]) - bo(a[ans] - (p - pre[i + 1] + pre[ans + 1]))
	return c
pre.append(pre[-1])
res.append(res[-1])
res.insert(0, 0)
maxi = 0
for i in range(n):
	maxi = max(maxi, left(i))
print(maxi)


import sys
reader = (s.rstrip() for s in sys.stdin)
input = reader.__next__

def dude(pp):
	return (pp + 1) * pp // 2

def gift():
	for _ in range(1):
		(n, x) = list(map(int, input().split()))
		days = list(map(int, input().split()))
		diulei = max(days)
		if diulei >= x:
			yield ((diulei + diulei - x + 1) * x // 2)
		else:
			(s, e) = (0, 0)
			maxans = 0
			front = []
			fres = 0
			curans = 0
			tored = 0
			while s <= n - 1:
				if s >= 1:
					fres -= days[s - 1]
					curans -= dude(days[s - 1])
					curans -= tored
				while True:
					if fres >= x:
						fres -= days[(e - 1) % n]
						e = (e - 1) % n
						break
					front.append(days[e])
					fres += days[e]
					if fres <= x:
						curans += dude(days[e])
						if fres == x:
							tored = dude(days[e])
					else:
						pp = days[e]
						xtemp = x - (fres - pp)
						curans += (pp + pp - xtemp + 1) * xtemp // 2
						tored = (pp + pp - xtemp + 1) * xtemp // 2
					e = (e + 1) % n
				maxans = max(curans, maxans)
				s += 1
			yield maxans
ans = gift()
print(*ans, sep='\n')
(1, 2, 3, 4, 1, 1, 1, 2, 3, 1, 2, 3, 1)


from __future__ import division, print_function
import itertools
import sys
import os
from io import BytesIO, IOBase
if sys.version_info[0] < 3:
	input = raw_input
	range = xrange
	filter = itertools.ifilter
	map = itertools.imap
	zip = itertools.izip

def is_it_local():
	script_dir = str(os.getcwd()).split('/')
	username = 'dipta007'
	return username in script_dir

def READ(fileName):
	if is_it_local():
		sys.stdin = open(f'./{fileName}', 'r')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
if not is_it_local():
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
	input = lambda : sys.stdin.readline().rstrip('\r\n')

def input1(type=int):
	return type(input())

def input2(type=int):
	[a, b] = list(map(type, input().split()))
	return (a, b)

def input3(type=int):
	[a, b, c] = list(map(type, input().split()))
	return (a, b, c)

def input_array(type=int):
	return list(map(type, input().split()))

def input_string():
	s = input()
	return list(s)
(n, m, ar) = (0, 0, [])
month_day = []
cum_month_day = []
cum_days = []

def end_here(ind):
	low = 0
	high = ind
	while low <= high:
		mid = (low + high) // 2
		if cum_days[ind] - cum_days[mid] >= m:
			res = mid
			low = mid + 1
		else:
			high = mid - 1
	now = cum_days[ind] - cum_days[res]
	besi = now - m
	return cum_month_day[ind] - cum_month_day[res] - besi * (besi + 1) // 2

def main():
	global n, m, ar, month_day, cum_days, cum_month_day
	(n, m) = input2()
	ar = input_array()
	month_day = [n * (n + 1) // 2 for n in ar]
	month_day += month_day
	ar += ar
	cum_month_day = [0]
	cum_days = [0]
	for i in range(n + n):
		cum_month_day.append(cum_month_day[-1] + month_day[i])
		cum_days.append(cum_days[-1] + ar[i])
	res = 0
	for i in range(n + 1, n + n + 1):
		res = max(res, end_here(i))
	print(res)
	pass
READ('in.txt')
main()


from collections import defaultdict
from collections import OrderedDict
from collections import deque
from itertools import combinations
from itertools import permutations
from itertools import accumulate
import bisect
import math
import heapq
import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, x) = map(int, input().split())
arr = list(map(int, input().split()))
arr = arr + arr

def summa(n):
	return (n + 1) * n // 2
ptr1 = 0
ptr2 = -1
days = 0
hugs = 0
ans = 0
while ptr2 < 2 * n - 1:
	ptr2 += 1
	days += arr[ptr2]
	hugs += summa(arr[ptr2])
	while days > x:
		if days - arr[ptr1] < x:
			break
		days -= arr[ptr1]
		hugs -= summa(arr[ptr1])
		ptr1 += 1
	diff = max(days - x, 0)
	ans = max(ans, hugs - summa(diff))
print(ans)


from bisect import bisect_left

def rangeSum(n):
	return n * (n + 1) // 2

def solve():
	(n, x) = map(int, input().split())
	days = list(map(int, input().split()))
	daySum = [days[0]]
	totalSum = [rangeSum(days[0])]
	for d in days[1:] + days:
		daySum.append(daySum[-1] + d)
		totalSum.append(totalSum[-1] + d * (d + 1) // 2)
	days *= 2
	maxDay = -float('inf')
	for i in range(len(daySum)):
		if daySum[i] < x:
			continue
		leftDays = daySum[i] - x
		if leftDays == 0:
			maxDay = max(maxDay, totalSum[i])
			continue
		j = bisect_left(daySum, leftDays, hi=i)
		fromDay = lambda n: (days[j] - n) * n + rangeSum(n)
		maxDay = max(maxDay, totalSum[i] - totalSum[j] + fromDay(daySum[j] - leftDays))
	print(maxDay)
solve()


def sum_to_n(v):
	return v * (v + 1) // 2

def search(f, l, r, i, x):
	m = (l + r) // 2
	if m >= 1 and f[i] - f[m - 1] >= x and (f[i] - f[m] <= x):
		return m
	elif m == 0 and f[i] >= x and (f[i] - f[m] <= x):
		return m
	elif m >= 1 and f[i] - f[m - 1] <= x:
		return search(f, l, m, i, x)
	elif f[i] - f[m] > x:
		return search(f, m + 1, r, i, x)
(n, x) = list(map(int, input().split()))
a = list(map(int, input().split()))
a = a + a
n = len(a)
f = [a[0]]
for i in range(1, n):
	f.append(f[i - 1] + a[i])
g = [sum_to_n(a[0])]
for i in range(1, n):
	g.append(g[i - 1] + sum_to_n(a[i]))
ans = 0
for i in range(n):
	if f[i] < x:
		continue
	j = search(f, 0, i, i, x)
	res = g[i] - g[j]
	r = x - (f[i] - f[j])
	res += sum_to_n(a[j]) - sum_to_n(a[j] - r)
	ans = max(ans, res)
print(ans)


def rs():
	return input().strip()

def ri():
	return int(input())

def ria():
	return list(map(int, input().split()))

def ia_to_s(a):
	return ' '.join([str(s) for s in a])

def nn2(n):
	return n * (n + 1) // 2

def solve(n, x, d):
	d = d + d
	ans = 0
	i = 0
	j = 0
	days = 0
	cnt = 0
	while i < 2 * n:
		while j < 2 * n and days < x:
			days += d[j]
			cnt += nn2(d[j])
			j += 1
		ans = max(ans, cnt - nn2(days - x))
		days -= d[i]
		cnt -= nn2(d[i])
		i += 1
	return ans

def main():
	(n, x) = ria()
	d = ria()
	print(solve(n, x, d))
main()


from sys import stdin, stdout
import bisect as bs
from itertools import accumulate
nmbr = lambda : int(stdin.readline())
lst = lambda : list(map(int, stdin.readline().split()))
fn = lambda x: x * (x + 1) >> 1
for _ in range(1):
	(n, d) = lst()
	a = lst() * 2
	ans = 0
	ps = list(accumulate(a))
	ps1 = list(accumulate([fn(v) for v in a]))
	for i in range(2 * n):
		pos = bs.bisect_left(ps, ps[i] - d)
		cur = ps1[i] - ps1[pos]
		extra_days = ps[pos] - ps[i] + d
		cur += fn(a[pos]) - fn(a[pos] - extra_days)
		ans = max(ans, cur)
	print(ans)


from sys import stdin
input = stdin.buffer.readline

def f(a, d, n):
	return (2 * a + d * (n - 1)) * n // 2

def bs1(x, ll):
	(l, r) = (ll, 2 * n)
	while l < r:
		m = l + r + 1 >> 1
		if dd[m] > x:
			r = m - 1
		else:
			l = m
	return l

def bs2(x, rr):
	(l, r) = (0, rr)
	while l < r:
		m = l + r >> 1
		if dd[m] < x:
			l = m + 1
		else:
			r = m
	return l
(n, k) = map(int, input().split())
ans = 0
(*d,) = map(int, input().split())
d = d + d
(pref, dd) = ([0] * (2 * n + 1), [0] * (2 * n + 1))
for i in range(2 * n):
	dd[i] = dd[i - 1] + d[i]
for i in range(2 * n):
	pref[i] = pref[i - 1] + f(1, 1, d[i])
for i in range(n):
	if k - 1 < d[i]:
		ans = max(ans, f(1, 1, k - 1) + d[i - 1])
		continue
	x = bs1(k - 1 + dd[i] - 1, i)
	tmp = pref[x] - pref[i]
	ans = max(ans, tmp + f(1, 1, k - 1 - dd[x] + dd[i]) + d[i])
for i in range(n, 2 * n):
	if k < d[i]:
		ans = max(ans, f(d[i], -1, k))
		continue
	x = bs2(dd[i] - k + 1, i)
	tmp = pref[i] - pref[x]
	ans = max(ans, tmp + f(dd[x] - dd[x - 1], -1, k - dd[i] + dd[x]))
print(ans)


num1 = list(map(int, input().split()))
num2 = list(map(int, input().split()))
arr = 2 * num2
n = num1[0]
x = num1[1]
pref1 = [arr[0] * (arr[0] + 1) // 2]
pref2 = [arr[0]]
for i in range(1, 2 * n):
	s = arr[i] * (arr[i] + 1) // 2
	pref1.append(pref1[-1] + s)
	pref2.append(pref2[-1] + arr[i])
i = 2 * n - 1
max1 = 0
while i >= n:
	l = 0
	r = i
	ans = i
	while l <= r:
		mid = (l + r) // 2
		if pref2[i] - pref2[mid] < x:
			ans = mid
			r = mid - 1
		else:
			l = mid + 1
	b = pref2[i] - pref2[ans - 1] - x
	c = b * (b + 1) // 2
	d = pref1[i] - pref1[ans - 1] - c
	max1 = max(max1, d)
	i -= 1
print(max1)


def vacation(n, x, days):
	hugs = 0
	pref = [0]
	for i in range(n):
		pref.append(pref[-1] + days[i])
	for i in range(n):
		pref.append(pref[-1] + days[i])
	ds = [i * (i + 1) // 2 for i in days]
	pref_hugs = [0]
	for i in range(n):
		pref_hugs.append(pref_hugs[-1] + ds[i])
	for i in range(n):
		pref_hugs.append(pref_hugs[-1] + ds[i])
	for i in range(n):
		lo = i
		hi = 2 * n + 1
		while lo < hi:
			mid = (lo + hi) // 2
			if pref[mid] - pref[i] < x:
				lo = mid + 1
			else:
				hi = mid
		lo -= 1
		remain = x + pref[i] - pref[lo]
		s = pref_hugs[lo] - pref_hugs[i] + remain * (remain + 1) // 2
		hugs = max(hugs, s)
	for i in range(n + 1, 2 * n + 1):
		lo = 0
		hi = i
		while lo < hi:
			mid = (lo + hi) // 2
			if pref[i] - pref[mid] <= x:
				hi = mid
			else:
				lo = mid + 1
		remain = x + pref[lo] - pref[i]
		s = pref_hugs[i] - pref_hugs[lo] + (2 * days[(lo - 1) % n] - remain + 1) * remain // 2
		hugs = max(hugs, s)
	return hugs
(n, x) = map(int, input().split())
days = [int(s) for s in input().split()]
print(vacation(n, x, days))


from sys import stdout, stdin
import io
import os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, x) = map(int, input().split())
a = list(map(int, input().split()))
a = a + a
i = j = ma = b = d = 0
while i < n:
	while d < x:
		d += a[j]
		b += a[j] * (a[j] + 1) // 2
		j = j + 1
	ma = max(ma, b - (d - x) * (d - x + 1) // 2)
	d -= a[i]
	b -= a[i] * (a[i] + 1) // 2
	i = i + 1
stdout.write(str(ma))


import bisect
l = input().split()
n = int(l[0])
x = int(l[1])
l = input().split()
li = [int(i) for i in l]
pref = [0 for i in range(n)]
total = [0 for i in range(n)]
sumi = 0
tot = 0
for i in range(n):
	sumi += li[i]
	tot = tot + li[i] * (li[i] + 1) // 2
	pref[i] = sumi
	total[i] = tot
maxa = []
po = sum(li)
for i in range(n):
	so = 0
	curr = pref[i] - x
	if curr >= 0:
		z = bisect.bisect(pref, curr)
		last = pref[z] - curr
		so += total[i] - total[z]
		so = so + last * (2 * li[z] + 1 - last) // 2
		maxa.append(so)
	else:
		z = bisect.bisect(pref, po + curr)
		last = pref[z] - po - curr
		so += total[-1] - total[z]
		so += total[i]
		so = so + last * (2 * li[z] + 1 - last) // 2
		maxa.append(so)
print(max(maxa))


import sys, heapq
from collections import *
from functools import lru_cache
sys.setrecursionlimit(10 ** 6)
import operator as op
from functools import reduce
import bisect

def main():
	(n, x) = map(int, input().split(' '))
	arr = list(map(int, input().split(' ')))
	arr += arr.copy()
	(days, hugs) = ([0] + arr.copy(), [0] + list(map(lambda x: x * (x + 1) // 2, arr)))
	for i in range(1, 2 * n + 1):
		days[i] += days[i - 1]
		hugs[i] += hugs[i - 1]
	res = 0
	for i in range(1, 2 * n + 1):
		y = days[i] - x
		j = bisect.bisect_right(days, y, 0, i)
		y -= days[j - 1]
		res = max(res, hugs[i] - hugs[j - 1] - y * (y + 1) // 2)
	print(res)
main()


(n, x) = map(int, input().split())
(*d,) = map(int, input().split())
d = 2 * d
d.reverse()
(j, ans, total_days, hugs) = (0, 0, 0, 0)
for i in range(n):
	while total_days < x:
		hugs += d[j] * (d[j] + 1) // 2
		total_days += d[j]
		j += 1
	tri = (total_days - x) * (total_days - x + 1) // 2
	ans = max(ans, hugs - tri)
	total_days -= d[i]
	hugs -= d[i] * (d[i] + 1) // 2
print(ans)


def f(n):
	return n * (n + 1) // 2

def rf(n, k):
	return f(n) - f(n - k)

def search(a: list, x: int) -> int:
	n = len(a)
	i = 0
	j = n // 2
	while j >= 1:
		while i + j < n and a[i + j] <= x:
			i += j
		j //= 2
	return i
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
a = [0]
b = [0]
for y in d:
	a += (y + a[-1],)
	b += (f(y) + b[-1],)
l = d[-1]
i = 0
while l < x:
	a += (d[i] + a[-1],)
	b += (f(d[i]) + b[-1],)
	l += d[i]
	i += 1
ans1 = 0
for i in range(n):
	z = x - d[i]
	if z <= 0:
		ans1 = max(ans1, f(x))
		continue
	t = a[i + 1] + z
	j = search(a, t)
	if a[j] < t:
		j += 1
	k = a[j] - t
	ans1 = max(ans1, b[j] - b[i] - rf(d[(j - 1) % n], k))
d = d[::-1]
a = [0]
b = [0]
for y in d:
	a += (y + a[-1],)
	b += (f(y) + b[-1],)
l = d[-1]
i = 0
while l < x:
	a += (d[i] + a[-1],)
	b += (f(d[i]) + b[-1],)
	l += d[i]
	i += 1
ans2 = 0
for i in range(n):
	z = x - d[i]
	if z <= 0:
		ans2 = max(ans2, rf(d[i], x))
		continue
	t = a[i + 1] + z
	j = search(a, t)
	if a[j] < t:
		j += 1
	k = a[j] - t
	ans2 = max(ans2, b[j] - b[i] - f(k))
print(max(ans1, ans2))


import sys
input = lambda : sys.stdin.readline().strip()
ipnut = input
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d = d + d
d.reverse()
pref = [0]
pref1 = [0]
for i in range(n * 2):
	pref.append(pref[-1] + d[i])
	pref1.append(pref1[-1] + d[i] * (d[i] + 1) // 2)
l = 0
r = 1
ans = x
for i in range(n):
	l = i
	while r <= 2 * n and pref[r] - pref[l] <= x:
		r += 1
	r -= 1
	dx = x - (pref[r] - pref[l])
	ans = max(ans, pref1[r] - pref1[l] + dx * (2 * d[r] - dx + 1) // 2)
print(ans)


from collections import *
from bisect import *
from math import *
from heapq import *
import sys
input = sys.stdin.readline
t = 1

def su(n):
	if n <= 0:
		return 0
	return n * (n + 1) // 2
while t:
	t -= 1
	(n, x) = map(int, input().split())
	a = list(map(int, input().split()))
	a = a + a
	preh = [su(a[0])]
	for i in range(1, 2 * n):
		preh.append(preh[-1] + su(a[i]))
	days = [a[0]]
	for i in range(1, 2 * n):
		days.append(days[-1] + a[i])
	r = 0
	pre = 0
	for i in range(n):
		r1 = 0
		pos = bisect_left(days, pre + x)
		if pos - i == 0:
			le = a[i] - x
			r = max(r, su(a[i]) - su(le))
		else:
			r1 = preh[pos - 1] - preh[i]
			newx = x - days[pos - 1] + days[i]
			if newx > a[pos]:
				limi = su(a[pos])
				limi1 = su(a[i]) - su(a[i] - newx + a[pos])
			else:
				limi = su(a[pos]) - su(a[pos] - newx)
				limi1 = 0
			r1 += limi + limi1
		pre += a[i]
		r = max(r, r1)
	print(r)


def find_max(i, ds, x, total):
	integ = 0
	resid = 0
	yint = 0
	yres = 0
	m = 0
	while x > 0:
		d = ds[i]
		if d <= x:
			x -= d
			integ += total[i]
			yint += d
			m += 1
		else:
			resid += d * (d + 1) // 2
			resid -= (d - x) * (d - x + 1) // 2
			yres = x
			break
		i -= 1
		if i < 0:
			i = len(ds) - 1
	return (integ, resid, yint, yres, m)
(n, x) = [int(x) for x in input().split()]
ds = [int(x) for x in input().split()]
total = []
for d in ds:
	total.append(d * (d + 1) // 2)
hugs = []
(integ, resid, yint, yres, m) = find_max(n - 1, ds, x, total)
hugs.append(integ + resid)
for i in range(n - 2, -1, -1):
	integ -= total[i + 1]
	yint -= ds[i + 1]
	m -= 1
	y = x - yint
	resid = 0
	yres = 0
	j = (i - m + n) % n
	while y > 0:
		d = ds[j]
		if d <= y:
			y -= d
			integ += total[j]
			yint += d
			m += 1
		else:
			resid += d * (d + 1) // 2
			resid -= (d - y) * (d - y + 1) // 2
			yres = y
			break
		j -= 1
		if j < 0:
			j = n - 1
	hugs.append(integ + resid)
print(max(hugs))


def hugs(m, d, N, X, D, md):
	acc = 0
	while True:
		if X >= D[m] - (d - 1):
			acc += D[m] * (D[m] + 1) // 2 - (d - 1) * d // 2
			X -= D[m] - (d - 1)
			m = 0 if m == N - 1 else m + 1
			d = 1
		else:
			end = X + (d - 1)
			acc += end * (end + 1) // 2 - (d - 1) * d // 2
			d = end
			break
	if d == D[m]:
		m = 0 if m == N - 1 else m + 1
		d = 1
	else:
		d += 1
	md[0] = m
	md[1] = d
	return acc

def arrival_date_to_leave_at_first_month_end(N, X, D):
	m = 0
	while True:
		if X <= D[m]:
			return [m, D[m] - (X - 1)]
		else:
			X -= D[m]
			m = N - 1 if m == 0 else m - 1
(N, X) = map(int, input().split())
D = list(map(int, input().split()))
(m, d) = arrival_date_to_leave_at_first_month_end(N, X, D)
md = [0, 0]
best_hugs = hugs(m, d, N, X, D, md)
curr_hugs = best_hugs
for j in range(1, N):
	hugs_to_add = hugs(j, 1, N, D[j], D, md)
	hugs_to_remove = hugs(m, d, N, D[j], D, md)
	(m, d) = md
	curr_hugs = curr_hugs + hugs_to_add - hugs_to_remove
	best_hugs = max(best_hugs, curr_hugs)
print(best_hugs)


import sys
from itertools import accumulate
from bisect import bisect_left

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 19
MOD = 10 ** 9 + 7

def get_sum(a, d, n):
	return (2 * a + (n - 1) * d) * n // 2
(N, x) = MAP()
A = LIST()
mxA = max(A)
if x <= mxA:
	ans = get_sum(mxA - x + 1, 1, x)
	print(ans)
	exit()
B = [0] * N
for i in range(N):
	B[i] = get_sum(1, 1, A[i])
A = A + A
B = B + B
accA = list(accumulate(A))
accB = list(accumulate(B))
ans = 0
for i in range(N, N * 2):
	cnt = B[i]
	remain = x - A[i]
	idx = bisect_left(accA, accA[i - 1] - remain)
	cnt += accB[i - 1] - accB[idx]
	remain -= accA[i - 1] - accA[idx]
	cnt += get_sum(A[idx] - remain + 1, 1, remain)
	ans = max(ans, cnt)
print(ans)


def sm(a, b):
	val = (a + b) * (b - a + 1) // 2
	return val
(n, x) = [int(x) for x in input().split()]
d = [int(x) for x in input().split()] * 2
(mx, i, j, day, hug) = (0, 0, 0, 0, 0)
while i < n:
	if day + d[j] <= x:
		day += d[j]
		hug += sm(1, d[j])
		j += 1
	else:
		mx = max(mx, hug + sm(d[j] - (x - day) + 1, d[j]))
		hug -= sm(1, d[i])
		day -= d[i]
		i += 1
print(mx)


(n, m) = map(int, input().split())

def sol(a):
	a += a
	b = list(map(lambda x: (1 + x) * x // 2, a))
	for i in range(1, len(b)):
		b[i] += b[i - 1]
	j = n * 2 - 1
	i = n * 2
	days = 0
	hugs = 0
	ans = 0
	while j >= 0:
		while i >= 0 and a[i - 1] + days <= m:
			days += a[i - 1]
			i -= 1
		hugs = b[j]
		if i > 0:
			hugs -= b[i - 1]
		cur = hugs
		if days < m and i > 0:
			t = m - days
			cur = hugs + t * (a[i - 1] - t + 1 + a[i - 1]) // 2
		ans = max(ans, cur)
		days -= a[j]
		j -= 1
	return ans
print(sol(list(map(int, input().split()))))


from sys import stdin, stdout
nsum = lambda x: x * (x + 1) >> 1
(n, x) = map(int, stdin.readline().split())
d = list(map(int, stdin.readline().split()))
presum_hugs = [nsum(d[0])]
presum_days = [d[0]]
for i in range(1, n):
	presum_hugs.append(presum_hugs[-1] + nsum(d[i]))
	presum_days.append(presum_days[-1] + d[i])
for i in range(n):
	presum_hugs.append(presum_hugs[-1] + nsum(d[i]))
	presum_days.append(presum_days[-1] + d[i])
ans = 0
for start in range((n << 1) - 1, n - 1, -1):
	hi = start
	lo = hi - n + 1
	while lo + 1 < hi:
		mid = lo + hi >> 1
		if presum_days[start] - presum_days[mid - 1] > x:
			lo = mid
			if presum_days[start] - presum_days[mid - 1] == x:
				break
		else:
			hi = mid - 1
	if presum_days[start] - presum_days[hi - 1] >= x:
		lo = hi
	temp = presum_hugs[start] - presum_hugs[lo - 1]
	extra = presum_days[start] - presum_days[lo - 1] - x
	if extra > 0:
		temp -= nsum(extra)
	ans = max(ans, temp)
stdout.write(str(ans) + '\n')


(n, k) = map(int, input().split())
l = [int(x) for x in input().split()]
l = l + l
pre1 = [0] * (2 * n + 1)
pre2 = [0] * (2 * n + 1)
for i in range(1, 2 * n + 1):
	pre1[i] = pre1[i - 1] + l[i - 1]
	pre2[i] = pre2[i - 1] + l[i - 1] * (l[i - 1] + 1) // 2
mx = 0
for i in range(2 * n, n, -1):
	low = 1
	high = i
	c = i
	while low <= high:
		mid = (low + high) // 2
		if pre1[i] - pre1[mid] >= k:
			low = mid + 1
		else:
			high = mid - 1
			c = mid
	t = pre2[i] - pre2[c - 1]
	nd = pre1[i] - pre1[c - 1]
	t -= (nd - k) * (nd - k + 1) // 2
	mx = max(mx, t)
print(mx)


from sys import stdin, stdout
import heapq
import cProfile
from collections import Counter, defaultdict, deque
from functools import reduce
import math

def get_int():
	return int(stdin.readline().strip())

def get_tuple():
	return map(int, stdin.readline().split())

def get_list():
	return list(map(int, stdin.readline().split()))

def solve():
	(n, x) = get_tuple()
	ls = get_list()
	month_total_days = dict([[i, val * (val + 1) // 2] for (i, val) in enumerate(ls, 1)])
	if max(ls) >= x:
		ans = 0
		days = max(ls)
		while x > 0:
			ans += days
			days -= 1
			x -= 1
		print(ans)
	else:
		(stack, hugs, ans, ind) = (deque(), 0, 0, 2 * n - 1)
		arr = defaultdict(list)
		ls = ls[:] + ls[:]
		for val in reversed(ls):
			f = 0
			while ans + val > x:
				(i, temp) = stack.popleft()
				if i == n:
					f = 1
					break
				rem_hugs = x - ans
				newans = 0
				if rem_hugs > 0:
					newans = val * (val + 1) // 2 - (val - rem_hugs) * (val - rem_hugs + 1) // 2
				arr[i] = [hugs + newans, ans]
				ans -= temp
				hugs -= month_total_days[i % n + 1]
			if f == 1:
				break
			ans += val
			hugs += month_total_days[ind % n + 1]
			stack.append((ind % n, val))
			ind -= 1
		final_ans = 0
		for (key, val) in arr.items():
			final_ans = max(final_ans, val[0])
		print(final_ans)

def main():
	solve()
TestCases = False
if TestCases:
	for i in range(get_int()):
		main()
else:
	main()


from bisect import bisect_right as bi
(n, x) = list(map(int, input().split()))
d = list(map(int, input().split()))
s = 0
a = []
for i in range(n - 1, -1, -1):
	s = s - d[i]
	a.append(s)
a.sort()
a.append(0)
s = 0
for i in range(n):
	s = s + d[i]
	a.append(s)
b = [0]
s = 0
for i in range(len(d)):
	s = s + d[i] * (d[i] + 1) // 2
	b.append(s)
s = 0
for i in range(len(d) - 1, -1, -1):
	s = s + d[i] * (d[i] + 1) // 2
	b.append(-s)
b.sort()
g = []
for i in range(n):
	c = bi(a, a[i + n + 1] - x)
	e = a[i + n + 1] - a[c]
	f = b[i + n + 1] - b[c]
	e = x - e
	u = a[c] - a[c - 1]
	f += u * (u + 1) // 2 - (u - e) * (u - e + 1) // 2
	g.append(f)
print(max(g))


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d.reverse()
start = 0
have = 0
i = 0
S = 0
ans = 0
while start < n:
	i %= n
	if d[i] <= x - have:
		have += d[i]
		S += d[i] * (d[i] + 1) // 2
		i += 1
	else:
		l1 = d[i]
		S += (l1 + l1 - (x - have - 1)) * (x - have) // 2
		if ans < S:
			ans = S
		S -= (l1 + l1 - (x - have - 1)) * (x - have) // 2
		S -= d[start] * (d[start] + 1) // 2
		have -= d[start]
		start += 1
print(ans)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d += d[:]
p = [0] * (2 * n)
p[0] = d[0]
for i in range(1, 2 * n):
	p[i] = p[i - 1] + d[i]
s = [0] * (2 * n)
s[0] = (1 + d[0]) * d[0] // 2
for i in range(1, 2 * n):
	s[i] = s[i - 1] + (1 + d[i]) * d[i] // 2
ans = 0
for i in range(n):
	l = i
	r = 2 * n
	j = i
	while l <= r:
		m = (l + r) // 2
		if p[m] - (p[i - 1] if i > 0 else 0) >= x:
			r = m - 1
			j = m
		else:
			l = m + 1
	if j == i:
		ans = max(ans, (d[i] - x + 1 + d[i]) * x // 2)
	else:
		k = x - (p[j - 1] - (p[i - 1] if i > 0 else 0))
		delta = min(d[j] - k, d[i] - 1)
		ans = max(ans, (1 + delta + d[i]) * (d[i] - delta) // 2 + s[j - 1] - s[i] + (1 + k + delta) * (k + delta) // 2)
print(ans)


def seg(l, r):
	global pref
	if l == 0:
		return pref[r]
	return pref[r] - pref[l - 1]

def Bin(day, l, r):
	global pref
	if l == r:
		return l
	mid = (l + r) // 2
	if mid == 0 and pref[mid] >= day:
		return mid
	elif mid != 0 and pref[mid] >= day and (pref[mid - 1] < day):
		return mid
	elif pref[mid] >= day:
		return Bin(day, l, mid - 1)
	else:
		return Bin(day, mid + 1, r)
(n, x) = map(int, input().split())
n *= 2
d = list(map(int, input().split())) * 2
pref = [0] * n
pref[0] = d[0]
for i in range(1, n):
	pref[i] = pref[i - 1] + d[i]
res = [0] * n
res[0] = d[0] * (d[0] + 1) // 2
for i in range(1, n):
	res[i] = res[i - 1] + d[i] * (d[i] + 1) // 2
ans = -1
for i in range(n // 2, n):
	ind = Bin(pref[i] - x + 1, 0, i)
	s = pref[i] - pref[ind]
	y = d[ind] - (x - s) + 1
	ans = max(ans, res[i] - res[ind] + (y + d[ind]) * (x - s) // 2)
print(ans)


from bisect import bisect_left
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d = d + d
pre1 = [d[0]]
for i in range(1, 2 * n):
	pre1.append(pre1[-1] + d[i])
temp = [i * (i + 1) // 2 for i in d]
pre2 = [temp[0]]
for i in range(1, 2 * n):
	pre2.append(pre2[-1] + temp[i])
ans = -1
for i in range(2 * n - 1, -1, -1):
	index = bisect_left(pre1, pre1[i] - x)
	val = pre1[i] - pre1[max(index - 1, 0)] - x
	factor = val * (val + 1) // 2
	ans = max(ans, pre2[i] - pre2[max(index - 1, 0)] - factor)
print(ans)


from bisect import bisect_left, bisect_right

def solution():
	(n, x) = map(int, input().split())
	d = list(map(int, input().split()))
	for i in range(n):
		d.append(d[i])
	n *= 2
	c = [d[0]] * n
	dd = [d[0] * (d[0] + 1) // 2] * n
	answer = 0
	for i in range(1, n):
		c[i] = c[i - 1] + d[i]
		dd[i] = dd[i - 1] + d[i] * (d[i] + 1) // 2
	for i in range(n):
		if c[i] >= x:
			z = bisect_right(c, c[i] - x)
			days = c[i] - c[z]
			too = x - days
			cnt = dd[i] - dd[z]
			cnt += d[z] * (d[z] + 1) // 2
			cnt -= (d[z] - too) * (d[z] - too + 1) // 2
			answer = max(answer, cnt)
	print(answer)
solution()


def sm(x):
	return x * (x + 1) // 2

def get_sum(l, r):
	return sm(r) - sm(l - 1)
(n, x) = list(map(int, input().split()))
d = [int(i) for i in input().split()]
d = d[:] + d[:]
n *= 2
pre = [d[0]]
(month, day, days, tot) = (n - 1, d[n - 1] + 1, 0, 0)
ans = 0
for i in range(n - 1, -1, -1):
	while days < x and month >= 0:
		if day > 1:
			cnt = min(x - days, day - 1)
			tot += get_sum(day - cnt, day - 1)
			days += cnt
			day -= cnt
		else:
			month -= 1
			day = d[month] + 1
	ans = max(ans, tot)
	tot -= get_sum(1, d[i])
	days -= d[i]
print(ans)


rr = lambda : input().strip()
rri = lambda : int(rr())
rrm = lambda : [int(x) for x in rr().split()]
from sys import stdin, stdout

def sol():
	(n, td) = rrm()
	v = rrm()
	res = 0
	curr = 0
	(i, j) = (0, 0)
	while j < 2 * n:
		if td > 0:
			curr += v[j % n] * (v[j % n] + 1) // 2
			td -= v[j % n]
			j += 1
		else:
			while td + v[i % n] < 0:
				curr -= v[i % n] * (v[i % n] + 1) // 2
				td += v[i % n]
				i += 1
			x = -td
			res = max(res, curr - x * (x + 1) // 2)
			curr -= v[i % n] * (v[i % n] + 1) // 2
			td += v[i % n]
			i += 1
	print(res)
	return
sol()


import sys
input = sys.stdin.buffer.readline

def func(n):
	return n * (n + 1) // 2

def solution():
	(n, x) = map(int, input().split())
	li = list(map(int, input().split()))
	li += li
	sumd = [0] * (2 * n + 1)
	cntd = [0] * (2 * n + 1)
	for i in range(2 * n - 1, -1, -1):
		sumd[i] = sumd[i + 1] + func(li[i])
		cntd[i] = cntd[i + 1] + li[i]
	pos = 2 * n - 1
	ans = 0
	while pos >= n:
		l = 0
		r = pos
		while l <= r:
			mid = (l + r) // 2
			if cntd[mid] - cntd[pos + 1] < x:
				r = mid - 1
			else:
				beg = mid
				l = mid + 1
		temp = 0
		if beg != pos:
			temp += sumd[beg + 1] - sumd[pos + 1]
		z = li[beg] - x + cntd[beg + 1] - cntd[pos + 1]
		temp += func(li[beg]) - func(z)
		ans = max(ans, temp)
		pos -= 1
	print(ans)
solution()


from bisect import bisect_left, bisect_right

class Result:

	def __init__(self, index, value):
		self.index = index
		self.value = value

class BinarySearch:

	def __init__(self):
		pass

	@staticmethod
	def greater_than(num: int, func, size: int=1):
		if isinstance(func, list):
			index = bisect_right(func, num)
			if index == len(func):
				return Result(None, None)
			else:
				return Result(index, func[index])
		else:
			(alpha, omega) = (0, size - 1)
			if func(omega) <= num:
				return Result(None, None)
			while alpha < omega:
				if func(alpha) > num:
					return Result(alpha, func(alpha))
				if omega == alpha + 1:
					return Result(omega, func(omega))
				mid = (alpha + omega) // 2
				if func(mid) > num:
					omega = mid
				else:
					alpha = mid

	@staticmethod
	def less_than(num: int, func, size: int=1):
		if isinstance(func, list):
			index = bisect_left(func, num) - 1
			if index == -1:
				return Result(None, None)
			else:
				return Result(index, func[index])
		else:
			(alpha, omega) = (0, size - 1)
			if func(alpha) >= num:
				return Result(None, None)
			while alpha < omega:
				if func(omega) < num:
					return Result(omega, func(omega))
				if omega == alpha + 1:
					return Result(alpha, func(alpha))
				mid = (alpha + omega) // 2
				if func(mid) < num:
					alpha = mid
				else:
					omega = mid
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def pre(s):
	n = len(s)
	pi = [0] * n
	for i in range(1, n):
		j = pi[i - 1]
		while j and s[i] != s[j]:
			j = pi[j - 1]
		if s[i] == s[j]:
			j += 1
		pi[i] = j
	return pi

def prod(a):
	ans = 1
	for each in a:
		ans = ans * each
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y

def smm(a, b):
	k = b - a
	return a * (k + 1) + k * (k + 1) // 2
for _ in range(int(input()) if not True else 1):
	(n, x) = map(int, input().split())
	d = list(map(int, input().split()))
	d += d
	pred = [d[0]]
	for i in range(1, len(d)):
		pred += [pred[-1] + d[i]]
	predd = [d[0] * (d[0] + 1) // 2]
	for i in range(1, len(d)):
		predd += [predd[-1] + d[i] * (d[i] + 1) // 2]
	total = 0
	bs = BinarySearch()

	def sm(l, r):
		if l == 0:
			return pred[r]
		else:
			return pred[r] - pred[l - 1]

	def smmm(l, r):
		if l == 0:
			return predd[r]
		else:
			return predd[r] - predd[l - 1]
	ans = 0
	for i in range(n):
		if i != 0:
			total = pred[i - 1]
		next = bs.greater_than(total + x - 1, pred)
		if not next:
			break
		next = next.index
		diff = sm(i, next) - x
		if diff > d[i]:
			continue
		start_from = diff + 1
		anss = smm(start_from, d[i]) + smmm(i + 1, next)
		ans = max(ans, anss)
	print(ans)


def sa(b, k):
	start = 0
	j = 0
	sum = 0
	e = 0
	f = -1
	while j < len(b) and start < len(b) // 2:
		if sum >= k:
			r = sum - k
			u = e - r * (r + 1) // 2
			if u > f:
				f = u
			sum += -b[start]
			e += -b[start] * (b[start] + 1) // 2
			start += 1
		else:
			sum += b[j]
			e += b[j] * (b[j] + 1) // 2
			j += 1
	return f
(n, k) = map(int, input().split())
b = list(map(int, input().split()))
for j in range(n):
	b.append(b[j])
print(sa(b, k))


def main():
	import sys
	from collections import deque
	input = sys.stdin.readline
	sys.setrecursionlimit(10 ** 6)
	(n, x) = [int(x) for x in input().strip().split()]
	dn = [int(x) for x in input().strip().split()]
	dn_hug = [d * (d + 1) // 2 for d in dn]
	days = 0
	hugs = 0
	i = 0
	if days < x:
		for i in range(-1, -1 - n, -1):
			days += dn[i]
			hugs += dn_hug[i]
			if days >= x:
				break
	j = i % n
	ans = 0
	for i in range(n):
		days += dn[i]
		hugs += dn_hug[i]
		while days - dn[j] >= x:
			days -= dn[j]
			hugs -= dn_hug[j]
			j = (j + 1) % n
		if days != x:
			ans = max(ans, hugs - (days - x) * (days - x + 1) // 2)
		else:
			ans = max(ans, hugs)
	print(ans)
main()


def li():
	return [int(i) for i in input().rstrip().split()]

def st():
	return str(input().rstrip())[2:-1]

def val():
	return int(input().rstrip())

def li2():
	return [str(i)[2:-1] for i in input().rstrip().split()]

def li3():
	return [int(i) for i in st()]
(n, x) = li()
l = li()
l = l + l
startindices = [0 for i in l]
i = j = ans = curr = days = 0
while j < 2 * n:
	if days + l[j] <= x:
		days += l[j]
		curr += l[j] * (l[j] + 1) // 2
	else:
		while l[j] + days - (l[i] - startindices[i]) > x:
			left = startindices[i]
			days -= l[i] - left
			curr -= l[i] * (l[i] + 1) // 2 - left * (left + 1) // 2
			i += 1
		deletetill = l[j] + days - x
		left = startindices[i]
		curr -= (left + deletetill) * (left + deletetill + 1) // 2 - left * (left + 1) // 2
		startindices[i] += deletetill
		days = x
		curr += l[j] * (l[j] + 1) // 2
	ans = max(ans, curr)
	j += 1
print(ans)


import io
import os
from collections import Counter, defaultdict, deque

def hugs(n):
	return n * (n + 1) // 2

def solve(N, X, D):
	best = 0
	window = deque()
	windowDays = 0
	windowScore = 0
	for i in range(2 * N):
		days = D[i % N]
		window.append(days)
		windowDays += days
		windowScore += hugs(days)
		while windowDays > X:
			removed = window.popleft()
			windowDays -= removed
			windowScore -= hugs(removed)
		prevMonthDays = D[(i - len(window)) % N]
		overflow = X - windowDays
		score = hugs(prevMonthDays) - hugs(prevMonthDays - overflow) + windowScore
		best = max(best, score)
	return best
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N, X) = [int(x) for x in input().split()]
D = [int(x) for x in input().split()]
ans = solve(N, X, D)
print(ans)


(n, x) = [int(y) for y in input().split()]
d = [int(y) for y in input().split()]

def getHugs(start, end):
	return (start + end) * (end - start + 1) // 2

def getMonthDay(day):
	lo = 0
	hi = len(dCumu) - 1
	while True:
		m = (lo + hi) // 2
		endOfMonth = dCumu[m]
		if endOfMonth >= day and (m == 0 or dCumu[m - 1] < day):
			break
		elif endOfMonth > day:
			hi = m - 1
		else:
			lo = m + 1
	return (m, d2[m] - (endOfMonth - day))
d2 = d + d
dCumu = [d2[0]]
for i in range(1, len(d2)):
	dCumu.append(dCumu[-1] + d2[i])
totalHugsByMonthCumu = [-1 for _ in range(len(d2))]
for i in range(len(d2)):
	if i == 0:
		totalHugsByMonthCumu[i] = getHugs(1, d2[i])
	else:
		totalHugsByMonthCumu[i] = getHugs(1, d2[i]) + totalHugsByMonthCumu[i - 1]
for endMonth in range(len(dCumu)):
	if dCumu[endMonth] >= x:
		break
res = 0
for month in range(endMonth, len(d) + endMonth):
	(startMonth, startDay) = getMonthDay(dCumu[month] - x + 1)
	total = getHugs(startDay, d2[startMonth]) + totalHugsByMonthCumu[month] - totalHugsByMonthCumu[startMonth]
	res = max(res, total)
print(res)


import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import factorial
from collections import Counter, defaultdict, deque
from heapq import heapify, heappop, heappush

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def comb(n, m):
	return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0

def perm(n, m):
	return factorial(n) // factorial(n - m) if n >= m else 0

def mdis(x1, y1, x2, y2):
	return abs(x1 - x2) + abs(y1 - y2)
mod = 998244353
INF = float('inf')
from bisect import bisect

def main():
	(n, x) = RL()
	arr = RLL()
	narr = [(i, (i + 1) * i // 2) for i in arr]
	sm = [(0, 0)]
	for (d, num) in narr:
		(nowd, nown) = sm[-1]
		sm.append((nowd + d, nown + num))
	res = 0
	total = sm[-1][0]
	for i in range(1, len(sm)):
		(d, num) = sm[i]
		tar = d - x
		if tar < 0:
			num = sm[-1][1] + num
			tar = total + tar
		p = bisect(sm, (tar, 0))
		pred = tar - sm[p - 1][0]
		now = num - sm[p - 1][1] - pred * (pred + 1) // 2
		res = max(res, now)
	print(res)
main()


(n, x) = map(int, input().split())
D = list(map(int, input().split()))
D.reverse()
D = D + D
S = [0] * (2 * n)
for i in range(2 * n):
	S[i] = D[i] * (D[i] + 1) // 2
from itertools import accumulate
D = [0] + D
D = list(accumulate(D))
S = [0] + S
S = list(accumulate(S))
import bisect
ans = -1
for i in range(1, n + 1):
	j = bisect.bisect_right(D, x + D[i - 1])
	r = x + D[i - 1] - D[j - 1]
	k = D[j] - D[j - 1]
	temp = S[j - 1] - S[i - 1] + S[j] - S[j - 1] - (k - r) * (k - r + 1) // 2
	ans = max(ans, temp)
print(ans)


def Sum(a):
	return a * (a + 1) // 2
(m, x) = map(int, input().split())
month = list(map(int, input().split())) * 2
(ans, days, start) = (0, 0, 0)
hugs = 0
for i in range(len(month)):
	hugs += Sum(month[i])
	days += month[i]
	while days > x:
		if days - month[start] < x:
			break
		days -= month[start]
		hugs -= Sum(month[start])
		start += 1
	diff = max(0, days - x)
	ans = max(ans, hugs - Sum(diff))
print(ans)


import math
(n, x) = map(int, input().split())
a = list(map(int, input().split()))
ans = 0
r = []
s = []
currsum = 0
currsum2 = 0
for i in range(n):
	currsum += a[i]
	currsum2 += (a[i] + 1) * a[i] // 2
	r.append(currsum)
	s.append(currsum2)
total1 = r[n - 1]
total2 = s[n - 1]
pointer = -n
for i in range(n):
	if pointer < 0:
		while r[n - 1] + r[i] - r[pointer % n] > x and pointer < 0:
			pointer += 1
	while r[i] - r[pointer % n] > x:
		pointer += 1
	if pointer <= 0:
		k = x - (r[n - 1] + r[i] - r[(pointer - 1) % n])
		ans = max(ans, total2 + s[i] - s[(pointer - 1) % n] - k * (k - 1) // 2)
	else:
		k = x - (r[i] - r[(pointer - 1) % n])
		ans = max(ans, s[i] - s[(pointer - 1) % n] - k * (k - 1) // 2)
print(ans)


def right_m(me, num):
	k = min(me, num)
	return k * (k + 1) // 2

def left_m(me, num):
	k = me
	if me <= num:
		return k * (k + 1) // 2
	l = me - num
	return k * (k + 1) // 2 - l * (l + 1) // 2

def ans(lm, rm, num):
	if num <= lm:
		return left_m(lm, num)
	ans = right_m(rm, num)
	num -= rm
	if num > 0:
		ans += left_m(lm, num)
	return ans
(n, x) = map(int, input().split())
lst = list(map(int, input().split()))
daysnum = [0] * n * 2
ansnum = [0] * n * 2
daysnum[0] = lst[0]
ansnum[0] = (lst[0] + 1) * lst[0] // 2
for i in range(1, 2 * n):
	daysnum[i] = daysnum[i - 1] + lst[i % n]
	ansnum[i] = ansnum[i - 1] + (lst[i % n] + 1) * lst[i % n] // 2
leftnum = 0
rightnum = 1
maxans = 0
while leftnum < n and rightnum < 2 * n:
	if leftnum == rightnum:
		rightnum += 1
		continue
	ihave = x - daysnum[rightnum - 1] + daysnum[leftnum]
	if ihave < 0:
		leftnum += 1
		continue
	ansnow = ansnum[rightnum - 1] - ansnum[leftnum]
	ansnow += ans(lst[leftnum % n], lst[rightnum % n], ihave)
	maxans = max(maxans, ansnow)
	rightnum += 1
print(maxans)


import sys, math, os
from io import BytesIO, IOBase
from bisect import bisect_left as bl, bisect_right as br, insort
from collections import defaultdict as dd, deque, Counter

def data():
	return sys.stdin.readline().strip()

def mdata():
	return list(map(int, data().split()))

def outl(var):
	sys.stdout.write(' '.join(map(str, var)) + '\n')

def out(var):
	sys.stdout.write(str(var) + '\n')
sys.setrecursionlimit(100000)
INF = float('inf')
mod = int(1000000000.0) + 7

def main():
	(n, x) = mdata()
	d = mdata()
	cnt1 = 0
	cnt2 = 0
	m = 0
	ind = 2 * n - 1
	i = 2 * n - 1
	d += d
	while i > -1:
		if d[i] >= x - cnt1:
			cnt2 += (d[i] * d[i] + d[i]) // 2 - (d[i] - x + cnt1) * (d[i] - x + cnt1 + 1) // 2
			m = max(cnt2, m)
			if ind != i:
				cnt2 -= (d[ind] * d[ind] + d[ind]) // 2 + (d[i] * d[i] + d[i]) // 2 - (d[i] - x + cnt1) * (d[i] - x + cnt1 + 1) // 2
				cnt1 -= d[ind]
				i += 1
			else:
				cnt2 -= (d[i] * d[i] + d[i]) // 2 - (d[i] - x + cnt1) * (d[i] - x + cnt1 + 1) // 2
			if cnt2 < 0:
				break
			ind -= 1
		else:
			cnt1 += d[i]
			cnt2 += (d[i] * d[i] + d[i]) // 2
		i -= 1
	out(m)
main()


def brute(a, x):
	arr = []
	for num in a:
		arr += list(range(1, num + 1))
	arr += arr
	currSum = sum(arr[:x])
	result = currSum
	for i in range(x, len(arr)):
		currSum += arr[i] - arr[i - x]
		result = max(result, currSum)
	return result

def fast(arr, x):
	arr += arr
	result = 0
	(left, right) = (0, 0)
	daysInWindow = 0
	allDaysSum = 0
	while right < len(arr):
		allDaysSum += arr[right] * (arr[right] + 1) // 2
		daysInWindow += arr[right]
		while daysInWindow - arr[left] > x:
			allDaysSum -= arr[left] * (arr[left] + 1) // 2
			daysInWindow -= arr[left]
			left += 1
		if daysInWindow >= x:
			noHugDays = daysInWindow - x
			candidate = allDaysSum - noHugDays * (noHugDays + 1) // 2
			if candidate > result:
				result = candidate
		right += 1
	return result

def randomTest():
	import random
	t = 100
	for _ in range(t):
		n = random.randint(1, 10 ** 3)
		arr = [random.randint(1, 10 ** 3) for _ in range(n)]
		x = random.randint(1, sum(arr))
		print(arr, x)
		b = brute(arr, x)
		f = fast(arr, x)
		if b != f:
			print('Broken!')
			print(b, f)
			return

def stressTest():
	import random
	t = 100
	for i in range(1, t + 1):
		n = random.randint(1, 2 * 10 ** 5)
		arr = [random.randint(1, 10 ** 6) for _ in range(n)]
		x = random.randint(1, sum(arr))
		print(i)
		f = fast(arr, x)

def main():
	(n, x) = [int(x) for x in input().split()]
	arr = [int(x) for x in input().split()]
	result = fast(arr, x)
	print(result)
main()


import sys

def input():
	return sys.stdin.readline().rstrip()

def sum_first_n_numbers(a):
	return a * (a + 1) // 2
(n, x) = [int(i) for i in input().split()]
n = 2 * n
days_per_month = [int(i) for i in input().split()]
days_per_month = days_per_month + days_per_month
hugs = [sum_first_n_numbers(i) for i in days_per_month]
pre_sum_hugs = [0]
pre_sum_days = [0]
for (days, hug) in zip(days_per_month, hugs):
	pre_sum_days.append(pre_sum_days[-1] + days)
	pre_sum_hugs.append(pre_sum_hugs[-1] + hug)
left_partial = 0
right_partial = 0
best = 0
while True:
	if right_partial == left_partial:
		right_partial += 1
	if right_partial == n:
		break
	in_between_days = pre_sum_days[right_partial] - pre_sum_days[left_partial + 1]
	in_between_hugs = pre_sum_hugs[right_partial] - pre_sum_hugs[left_partial + 1]
	d_left = days_per_month[left_partial]
	d_right = days_per_month[right_partial]
	cap = d_left + d_right + in_between_days
	if cap < x:
		right_partial += 1
	elif cap >= x:
		overflow = x - in_between_days
		if overflow >= d_left:
			if overflow >= d_right:
				pending = overflow - d_right
				additional = sum_first_n_numbers(d_right) + sum_first_n_numbers(d_left) - sum_first_n_numbers(d_left - pending)
			else:
				additional = sum_first_n_numbers(d_right) - sum_first_n_numbers(d_right - overflow)
		else:
			additional = sum_first_n_numbers(d_left) - sum_first_n_numbers(d_left - overflow)
		best = max(best, additional + in_between_hugs)
		left_partial = left_partial + 1
print(best)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
a = [i * (i + 1) // 2 for i in d]
inf = 100000000000
ans = 0
now1 = inf
now2 = 0
add1 = 0
add2 = 0
for i in range(n - 1, -1, -1):
	if now1 == inf or now1 == i + 1:
		check = x
		now1 = inf
		now2 = 0
		add1 = 0
		add2 = 0
		if check < d[i]:
			now2 = 0
			add1 = check
			add2 = (2 * d[i] - check + 1) * check // 2
		else:
			now1 = i
			now2 = a[i]
			check -= d[i]
			while check >= d[now1 - 1]:
				check -= d[now1 - 1]
				now2 += a[now1 - 1]
				now1 -= 1
			add1 = check
			add2 = (2 * d[now1 - 1] - check + 1) * check // 2
	else:
		check = add1 + d[i + 1]
		add1 = 0
		add2 = 0
		now2 -= a[i + 1]
		if check < d[now1 - 1]:
			add1 = check
			add2 = (2 * d[now1 - 1] - check + 1) * check // 2
		else:
			while check >= d[now1 - 1]:
				check -= d[now1 - 1]
				now2 += a[now1 - 1]
				now1 -= 1
			add1 = check
			add2 = (2 * d[now1 - 1] - check + 1) * check // 2
	ans = max(now2 + add2, ans)
print(ans)


def fsm(d):
	return d * (d + 1) // 2

def rsm(x, y):
	return (x + (x - y + 1)) * y // 2
(N, K) = map(int, input().split())
D = list(map(int, input().split()))[::-1]
D = D * 2
sm = 0
ssm = 0
j = 0
R = 0
for i in range(N):
	if i > 0:
		sm -= D[i - 1]
		ssm -= fsm(D[i - 1])
	while sm + D[j] <= K:
		sm += D[j]
		ssm += fsm(D[j])
		j += 1
	tr = ssm
	tr += rsm(D[j], K - sm)
	R = max(tr, R)
print(R)


class Solution:

	def __init__(self):
		(n, x) = list(map(int, input().split()))
		d = list(map(int, input().split()))
		self.solve(n, x, d)

	def f(self, n):
		return int(n * (n + 1) / 2)

	def getRange(self, a, l, r):
		return a[r] - (0 if l == 0 else a[l - 1])

	def calc(self, ad, sd, i, x, n):
		(l, r) = (0, i)
		pos = None
		while l <= r:
			m = l + r >> 1
			s = self.getRange(ad, m, i)
			if s >= x:
				(pos, l) = (m, m + 1)
			else:
				r = m - 1
		if pos is not None:
			days = self.getRange(ad, pos, i)
			return self.getRange(sd, pos, i) - self.f(days - x)
		else:
			return self.getRange(sd, 0, i) + self.calc(ad, sd, n - 1, x - self.getRange(ad, 0, i), n)

	def solve(self, n, x, d):
		ad = [i for i in d]
		sd = [self.f(i) for i in d]
		for i in range(1, n):
			ad[i] += ad[i - 1]
			sd[i] += sd[i - 1]
		res = 0
		for i in range(0, n):
			temp = self.calc(ad, sd, i, x, n)
			res = max(res, temp)
		print(res)
Solution()


[N, X] = list(map(int, input().split()))
MONTHS = list(map(int, input().split()))
MONTHS = MONTHS + MONTHS
prefix_days = [0]
prefix_hugs = [0]
for num_days in MONTHS:
	prefix_days.append(prefix_days[-1] + num_days)
	num_hugs = num_days * (num_days + 1) // 2
	prefix_hugs.append(prefix_hugs[-1] + num_hugs)
prefix_days.pop(0)
prefix_hugs.pop(0)
ans = -1
for right in range(len(MONTHS)):
	idx = right
	jump = len(MONTHS)

	def nextIdx(idx):
		if idx < 0:
			return False
		return prefix_days[right] - prefix_days[idx] < X
	while jump != 0:
		while nextIdx(idx - jump):
			idx -= jump
		jump //= 2
	hugs_month_not_including_left = prefix_hugs[right] - prefix_hugs[idx]
	days_taken = prefix_days[right] - prefix_days[idx]
	days_this_month = X - days_taken
	foo = MONTHS[idx] - days_this_month
	hugs_left_month_subtract = foo * (foo + 1) // 2
	hugs_left_month = MONTHS[idx] * (MONTHS[idx] + 1) // 2 - hugs_left_month_subtract
	ans = max(ans, hugs_left_month + hugs_month_not_including_left)
print(ans)


import sys
input = sys.stdin.readline
flush = sys.stdout.flush

def psum(a, i, j):
	if i <= j:
		return a[j + 1] - a[i]
	else:
		return a[-1] - a[i] + a[j + 1]

def start(i, x):
	l = 0
	r = n - 1
	while l < r:
		m = l + r >> 1
		if psum(S, i, (i + m) % n) >= x:
			r = m
		else:
			l = m + 1
	if l == 0:
		return x * (x + 1) >> 1
	else:
		x -= psum(S, i, (i + l - 1) % n)
		return (x * (x + 1) >> 1) + psum(SS, i, (i + l - 1) % n)

def end(i, x):
	l = 0
	r = n - 1
	while l < r:
		m = l + r >> 1
		if psum(S, (i - m) % n, i) >= x:
			r = m
		else:
			l = m + 1
	if l == 0:
		return x * (2 * d[i] - x + 1) >> 1
	else:
		x -= psum(S, (i - l + 1) % n, i)
		return (x * (2 * d[(i - l) % n] - x + 1) >> 1) + psum(SS, (i - l + 1) % n, i)
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
S = [0] * (n + 1)
SS = [0] * (n + 1)
for i in range(1, n + 1):
	S[i] = S[i - 1] + d[i - 1]
	SS[i] = SS[i - 1] + (d[i - 1] * (d[i - 1] + 1) >> 1)
print(max(max((start(i, x) for i in range(n))), max((end(i, x) for i in range(n)))))


from itertools import accumulate
from bisect import bisect_left, bisect_right
(n, x) = map(int, input().split())
a = list(map(int, input().split()))
a *= 2
pf = [0] + list(accumulate(a))
score_pf = [0]
for i in range(2 * n):
	score_pf.append(score_pf[-1] + a[i] * (a[i] + 1) // 2)
ans = 0
for i in range(n):
	pos = bisect_left(pf, pf[i] + x)
	cur = score_pf[pos] - score_pf[i]
	rem = pf[pos] - pf[i] - x
	cur -= a[pos - 1] * (a[pos - 1] + 1) // 2
	cur += (a[pos - 1] - rem) * (a[pos - 1] - rem + 1) // 2
	ans = max(ans, cur)
for i in range(2 * n, n, -1):
	pos = bisect_right(pf, pf[i] - x) - 1
	cur = score_pf[i] - score_pf[pos]
	rem = pf[i] - pf[pos] - x
	cur -= rem * (rem + 1) // 2
	ans = max(ans, cur)
print(ans)


from __future__ import division, print_function
import sys
if sys.version_info[0] < 3:
	from __builtin__ import xrange as range
	from future_builtins import ascii, filter, hex, map, oct, zip
import os, sys, bisect, copy
from collections import defaultdict, Counter, deque
if os.path.exists('in.txt'):
	sys.stdin = open('in.txt', 'r')
if os.path.exists('out.txt'):
	sys.stdout = open('out.txt', 'w')

def input():
	return sys.stdin.readline()

def mapi(arg=0):
	return map(int if arg == 0 else str, input().split())
(n, x) = mapi()
a = list(mapi())
dp1 = [0] * 2 * n
dp2 = [0] * 2 * n
for i in range(2 * n):
	dp1[i] = dp1[i - 1] + a[i % n]
	dp2[i] = dp2[i - 1] + a[i % n] * (a[i % n] + 1) // 2
res = 0
for i in range(n):
	nxt = bisect.bisect_right(dp1, dp1[i] + x)
	if nxt == 2 * n:
		nxt -= 1
	val = dp1[nxt] - dp1[i] - x
	res = max(res, dp2[nxt] - dp2[i] - (val + 1) * val // 2)
print(res)


import sys
input = sys.stdin.readline

def binary_search():
	(l, r) = (i, 2 * n - 1)
	while l <= r:
		m = (l + r) // 2
		if acc1[m + 1] - acc1[i] <= x:
			l = m + 1
		else:
			r = m - 1
	return r
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
d.reverse()
d += d
acc1 = [0]
for di in d:
	acc1.append(acc1[-1] + di)
acc2 = [0]
for di in d:
	acc2.append(acc2[-1] + di * (di + 1) // 2)
ans = 0
for i in range(n):
	b = binary_search()
	amari = x - (acc1[b + 1] - acc1[i])
	top = d[(b + 1) % n]
	ans = max(ans, acc2[b + 1] - acc2[i] + amari * (2 * top - amari + 1) // 2)
print(ans)


(n, x) = map(int, input().split())
d = [int(i) for i in input().split()]
d += d
(ans, spent, end, ss) = (-1, 0, 0, 0)
for i in range(0, n):
	while spent < x:
		check = d[end]
		spent += check
		ss += check * (check + 1) // 2
		end += 1
	more = spent - x
	ans = max(ans, ss - more * (more + 1) // 2)
	spent -= d[i]
	ss -= d[i] * (d[i] + 1) // 2
print(ans)


(n, x) = list(map(int, input().split()))
d = list(map(int, input().split()))
accum = 3 * n * [0]
accum2 = 3 * n * [0]
for i in range(3 * n):
	if i > 0:
		accum[i] = accum[i - 1]
		accum2[i] = accum2[i - 1]
	accum[i] += (d[i % n] + 1) * d[i % n] // 2
	accum2[i] += d[i % n]
ans = 0
temp_ans = (d[0] + 1) * d[0] // 2
j = 0
days = d[0]
for i in range(n):
	while days < x:
		j += 1
		days += d[j % n]
		temp_ans += (d[j % n] + 1) * d[j % n] // 2
	dif = days - x
	if dif == 0:
		ans = max(temp_ans, ans)
	else:
		ans = max(temp_ans - (dif + 1) * dif // 2, ans)
	days -= d[i]
	temp_ans -= (d[i] + 1) * d[i] // 2
print(ans)


import sys
import math
import collections
from sys import stdin, stdout, setrecursionlimit
import bisect as bs
setrecursionlimit(2 ** 20)
M = 10 ** 9 + 7
T = 1

def f(x):
	return x * (x + 1) // 2
for _ in range(T):
	(n, x) = list(map(int, stdin.readline().split()))
	d = list(map(int, stdin.readline().split()))
	d = 2 * d
	su = list(map(f, d))
	l = 0
	r = -1
	s = 0
	ans = 0
	mx = 0
	while r < 2 * n:
		if s < x:
			r += 1
			if r == 2 * n:
				continue
			s += d[r]
			ans += su[r]
		else:
			rem = s - x
			while 1:
				if d[l] > rem:
					ans -= rem * (rem + 1) // 2
					if mx < ans:
						mx = ans
					ans += rem * (rem + 1) // 2
					ans -= su[l]
					s -= d[l]
					l += 1
					break
				ans -= su[l]
				rem -= d[l]
				s -= d[l]
				l += 1
	if mx == 0:
		print(ans)
		continue
	print(mx)


import sys
input = sys.stdin.buffer.readline

def check(num):
	for i in range(n):
		if values[i] >= num:
			return True
	return False

def calc():
	curr = days[0]
	j = -1
	while curr <= x:
		curr += days[j]
		j -= 1
	left = curr - x
	left = left * (left + 1) // 2
	a = pref[0] + (pref[-1] - pref[j])
	ans = a - left
	values[0] = ans
	j += 1
	for i in range(1, n):
		curr += days[i]
		curr -= days[j]
		while curr > x:
			j += 1
			curr -= days[j]
		curr = max(curr, 0)
		curr += days[j]
		left = curr - x
		left = left * (left + 1) // 2
		if j < 0:
			a = pref[i] + (pref[-1] - pref[j - 1])
		elif j == 0:
			a = pref[i]
		else:
			a = pref[i] - pref[j - 1]
		values[i] = a - left
(n, x) = map(int, input().split())
days = list(map(int, input().split()))
count = []
for i in days:
	count.append(i * (i + 1) // 2)
prefix = [days[0]]
pref = [count[0]]
for i in range(1, n):
	prefix.append(prefix[-1] + days[i])
	pref.append(pref[-1] + count[i])
if x == sum(days):
	print(pref[-1])
	exit()
values = [0] * n
calc()
maxx = sum(count)
low = 0
high = 10 ** 18
while low < high:
	mid = (low + high) // 2
	if check(mid):
		low = mid + 1
	else:
		high = mid - 1
if check(low):
	print(low)
else:
	print(low - 1)


import sys
input = sys.stdin.readline
from collections import *

def binary_search():
	(l, r) = (i, 2 * N - 1)
	while l <= r:
		m = (l + r) // 2
		if acc[m + 1] - acc[i] <= x:
			l = m + 1
		else:
			r = m - 1
	return r
(N, x) = map(int, input().split())
d = list(map(int, input().split()))
M = max(d)
if x <= M:
	print(x * (M + M - (x - 1)) // 2)
	exit()
d.reverse()
d += d
acc = [0]
for di in d:
	acc.append(acc[-1] + di)
acc2 = [0]
for di in d:
	acc2.append(acc2[-1] + di * (di + 1) // 2)
ans = 0
for i in range(N):
	b = binary_search()
	ans_cand = acc2[b + 1] - acc2[i]
	ama = x - (acc[b + 1] - acc[i])
	t = d[(b + 1) % N]
	ans_cand += ama * (t + t - (ama - 1)) // 2
	ans = max(ans, ans_cand)
print(ans)


from sys import stdin, stdout
import sys
from math import *
input = stdin.readline
(n, m) = map(int, input().split())
ar = list(map(int, input().split()))
ar = ar + ar
d = [0]
h = [0]
for i in range(2 * n):
	d.append(d[-1] + ar[i])
	h.append(h[-1] + ar[i] * (ar[i] + 1) // 2)
ans = 0
for i in range(1, 2 * n + 1):
	if d[i] >= m:
		req = d[i] - m
		l = 0
		r = i + 1
		ind = 0
		while l <= r:
			mid = (l + r) // 2
			if d[mid] < req:
				l = mid + 1
			else:
				ind = mid
				r = mid - 1
		if ind == 0 or d[i] - d[ind] == m:
			ans = max(ans, h[i] - h[ind])
		else:
			rslt = h[i] - h[ind]
			req = m - (d[i] - d[ind])
			temp = ar[ind - 1] * (ar[ind - 1] + 1) // 2 - (ar[ind - 1] - req) * (ar[ind - 1] - req + 1) // 2
			ans = max(ans, rslt + temp)
print(ans)


import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
import bisect
(n, x) = map(int, input().split())
d = [int(i) for i in input().split()]
d += d
pref = [d[0]]
for i in d[1:]:
	pref.append(pref[-1] + i)
hug_l = [d[0] * (d[0] + 1) // 2]
for i in d[1:]:
	hug_l.append(hug_l[-1] + i * (i + 1) // 2)
maxd = max(d)
diff1 = maxd - x
ans = maxd * (maxd + 1) // 2 - diff1 * (diff1 + 1) // 2
for i in range(n, len(d)):
	hugs = 0
	if pref[i] - x < 0:
		continue
	ind = bisect.bisect_left(pref, pref[i] - x)
	hugs = hug_l[i] - hug_l[ind - 1]
	diff = max(0, pref[i] - pref[ind - 1] - x)
	hugs -= diff * (diff + 1) // 2
	ans = max(ans, hugs)
sys.stdout.write(str(ans) + '\n')


def sume(x):
	return x * (x + 1) // 2
(n, x) = map(int, input().split())
z = list(map(int, input().split()))
m = len(z)
z = z + z
maxa = 0
pair = [-1, -1]
t1 = [0 for i in range(m)]
for i in range(m, len(z)):
	if i == m:
		if z[m] >= x:
			pair[0] = m
			pair[1] = z[m] - x + 1
			maxa = max(maxa, sume(z[i]) - sume(pair[1]))
			t1[i - m] = sume(z[i]) - sume(pair[1] - 1)
		else:
			t = m
			r = x
			total = 0
			while z[t] < r:
				total += sume(z[t])
				r -= z[t]
				t -= 1
			pair[0] = t
			pair[1] = z[t] - r + 1
			t1[i - m] = total + sume(z[t]) - sume(pair[1] - 1)
	elif z[i] >= x:
		pair[0] = i
		pair[1] = z[i] - x + 1
		t1[i - m] = sume(z[i]) - sume(pair[1] - 1)
	else:
		add = z[i]
		if add <= z[pair[0]] - pair[1]:
			re = pair[1]
			pair[1] += add
			t1[i - m] = t1[i - m - 1] + sume(z[i]) - (sume(pair[1] - 1) - sume(re - 1))
		else:
			add = z[i]
			add -= z[pair[0]] - pair[1]
			sub = sume(z[pair[0]]) - sume(pair[1] - 1)
			ie = pair[0]
			ie += 1
			while add:
				if z[ie] < add:
					sub += sume(z[ie])
					add -= z[ie]
					ie += 1
				else:
					sub += sume(add - 1)
					pair[0] = ie
					pair[1] = add
					add = 0
					break
			t1[i - m] = t1[i - m - 1] + sume(z[i]) - sub
print(max(t1))


import sys
from bisect import bisect_left
input = sys.stdin.buffer.readline

def nsum(n):
	return n * (n + 1) // 2

def prog():
	(n, x) = map(int, input().split())
	days = list(map(int, input().split()))
	hugs = [nsum(day) for day in days]
	tdays = [0]
	thugs = [0]
	for i in range(n):
		tdays.append(days[i] + tdays[i])
	for i in range(n):
		tdays.append(days[i] + tdays[i + n])
	for i in range(n):
		thugs.append(hugs[i] + thugs[i])
	for i in range(n):
		thugs.append(hugs[i] + thugs[i + n])
	maxes = []
	for i in range(n):
		end = bisect_left(tdays, x + tdays[i])
		diff = tdays[end] - (x + tdays[i])
		if diff <= days[i]:
			maxes.append(thugs[end] - thugs[i] - nsum(diff))
	print(max(maxes))
prog()


import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
import sys
from itertools import accumulate
from bisect import bisect_left

def main():
	(n, x) = map(int, input().split())
	D = list(map(int, input().split()))
	D.reverse()
	D += D
	Q = [d * (d + 1) // 2 for d in D]
	Acc_d = [0] + list(accumulate(D))
	Acc_q = [0] + list(accumulate(Q))
	ans = 0
	for i in range(n):
		d = D[i]
		days = Acc_d[i] + x
		idx = bisect_left(Acc_d, days)
		edge_days = D[idx - 1]
		remove = Acc_d[idx] - days
		tmp = Acc_q[idx] - Acc_q[i]
		tmp -= remove * (remove + 1) // 2
		ans = max(ans, tmp)
	sys.stdout.write(str(ans) + '\n')
main()


import sys
import heapq
import random
import collections

def solve(lst, k):
	console('----- solving ------')
	n_months = len(lst)
	lst = lst[::-1]
	lst = lst + lst + lst
	val = [x * (x + 1) // 2 for x in lst]
	days = 0
	hugs = 0
	for (i, x) in enumerate(lst):
		days += x
		hugs += val[i]
		if days > k:
			break
	res = 0
	for (d, v) in zip(lst[:n_months], val[:n_months]):
		overshot_days = days - k
		overshot_hugs = overshot_days * (overshot_days + 1) // 2
		current_hugs = hugs - overshot_hugs
		res = max(res, current_hugs)
		days -= d
		hugs -= v
		for z in range(i + 1, n_months * 2):
			if days > k:
				break
			i = z
			days += lst[i]
			hugs += val[i]
	return res

def console(*args):
	print('\x1b[36m', *args, '\x1b[0m', file=sys.stderr)
	return
(_, k) = list(map(int, input().split()))
lst = list(map(int, input().split()))
res = solve(lst, k)
print(res)


(n, x) = map(int, input().split())
d = list(map(int, input().split())) * 2
d.reverse()
ans = 0
nxt = 0
cur = 0
cnt = 0
for i in range(n):
	if i > 0:
		cnt -= d[i - 1]
		cur -= d[i - 1] * (d[i - 1] + 1) >> 1
	while cnt + d[nxt] <= x:
		cnt += d[nxt]
		cur += d[nxt] * (d[nxt] + 1) >> 1
		nxt += 1
	rem = x - cnt
	val = (d[nxt] + d[nxt] - rem + 1) * rem >> 1
	ans = max(ans, cur + val)
print(ans)


import bisect
(n, x) = map(int, input().rstrip().split())
arr = list(map(int, input().rstrip().split()))
arr = [0] + arr + arr
prefixSum1 = [0] * (2 * n + 1)
prefixSum2 = [0] * (2 * n + 1)
for pos in range(1, 2 * n + 1):
	prefixSum1[pos] = prefixSum1[pos - 1] + arr[pos]
	prefixSum2[pos] = prefixSum2[pos - 1] + arr[pos] * (arr[pos] + 1) // 2
maxHugs = 0
for pos in range(2 * n, n, -1):
	leftLimit = bisect.bisect_left(prefixSum1, prefixSum1[pos] - x, 1, pos)
	temp = prefixSum1[pos] - prefixSum1[leftLimit - 1] - x
	sumTemp = prefixSum2[pos] - prefixSum2[leftLimit - 1]
	sumTemp -= temp * (temp + 1) // 2
	maxHugs = max(maxHugs, sumTemp)
print(maxHugs)


from sys import stdin
(n, m) = map(int, stdin.readline().strip().split())
s = list(map(int, stdin.readline().strip().split()))

def sum(n):
	return n * (n + 1) // 2
s = s[::-1]
s = s + s + s
acum = [0 for i in range(n + n + 10)]
acum[0] = s[0]
for i in range(len(acum)):
	acum[i] = acum[i - 1] + s[i % n]
pon = 0
ans = 0
tot = 0
aux = 0
for i in range(n):
	if i != 0:
		tot -= s[i - 1]
		aux -= sum(s[i - 1])
	while tot < m:
		tot += s[pon]
		aux += sum(s[pon])
		pon += 1
	y = tot - m
	ans = max(ans, aux - sum(y))
print(ans)


import sys
from collections import deque
input = sys.stdin.readline

def t(n):
	return n * (n + 1) // 2
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
tw = 0
tv = 0
ans = -1
queue = deque([])
for i in range(-1, -n - 1, -1):
	queue.appendleft(d[i])
	tw += d[i]
	tv += t(d[i])
	if tw >= x:
		break
for i in range(n):
	tw += d[i]
	tv += t(d[i])
	queue.append(d[i])
	c = int(tv)
	while tw > x:
		curr = queue.popleft()
		tw -= curr
		tv -= t(curr)
		c -= t(curr)
	c += t(curr) - t(curr - (x - tw))
	ans = max(c, ans)
print(ans)


import sys
from bisect import bisect_left as bl
input = sys.stdin.readline
(N, x) = map(int, input().split())
a = list(map(int, input().split()))
mx = max(a)
if x <= mx:
	print(mx * (mx + 1) // 2 - (mx - x) * (mx - x + 1) // 2)
	exit(0)
a = a + a
cs = [0] * (2 * N + 1)
for i in range(2 * N):
	cs[i + 1] = cs[i] + a[i]
cscalc = [0] * (2 * N + 1)
for i in range(2 * N):
	cscalc[i + 1] = cscalc[i] + a[i] * (a[i] + 1) // 2
res = 0
for i in range(N + 1):
	r = bl(cs, cs[i] + x)
	t = x - (cs[r - 1] - cs[i])
	res = max(res, t * (t + 1) // 2 + cscalc[r - 1] - cscalc[i])
	ttt = x - (cs[r] - cs[i + 1])
	if a[i] >= ttt and ttt >= 0:
		tt = a[i] * (a[i] + 1) // 2 - (a[i] - ttt) * (a[i] - ttt + 1) // 2
		res = max(res, tt + cscalc[r] - cscalc[i + 1])
print(res)


(n, x) = map(int, input().split())
l = list(map(int, input().split()))
l *= 2
num = 0
ans = 0
val = 0
j = 0
for i in range(n):
	while num < x:
		num += l[j]
		val += l[j] * (l[j] + 1) // 2
		j += 1
		if j == n:
			j = 0
	ans = max(ans, val - (num - x) * (num - x + 1) // 2)
	num -= l[i]
	val -= l[i] * (l[i] + 1) // 2
print(ans)


def task(n, x, d):
	size = 1000001
	table = [0] * size
	suma = 0
	for i in range(1, size):
		suma += i
		table[i] = suma
	start_month = n * 2 - 1
	current_month = start_month
	total = 0
	best = 0
	days = 0
	while current_month >= 0:
		days += d[current_month % n]
		if days < x:
			total += table[d[current_month % n]]
			current_month -= 1
		else:
			total += table[d[current_month % n]] - table[days - x]
			best = max(best, total)
			total -= table[d[current_month % n]] - table[days - x]
			days -= d[current_month % n]
			if start_month != current_month:
				days -= d[start_month % n]
				total -= table[d[start_month % n]]
				start_month -= 1
			else:
				current_month -= 1
				start_month -= 1
	print(best)
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
task(n, x, d)


import sys
input = sys.stdin.readline
(a, b) = list(map(int, input().split()))
n = list(map(int, input().split()))
n = n + n
best = 0
left = 0
right = 0
total_cost = 0
total_days = 0
for i in range(len(n)):
	x = n[i]
	total_cost += x * (x + 1) // 2
	total_days += x
	if total_days > b:
		over = total_days - b
		over_cost = over * (over + 1) // 2
		while over > n[left]:
			x = n[left]
			reduce = x * (x + 1) // 2
			total_cost -= reduce
			total_days -= x
			left += 1
			over = total_days - b
			over_cost = over * (over + 1) // 2
		if over <= n[left]:
			best = max(best, total_cost - over_cost)
print(best)


import math

def summ(p):
	return p * (p + 1) // 2
[n, x] = list(map(int, input().split()))
p = list(map(int, input().split()))
m = [0] * (2 * n)
for i in range(n):
	m[i] = p[i]
	m[n + i] = p[i]
m_sum = [0] * (2 * n + 1)
mm = m_sum[:]
for i in range(1, 2 * n + 1):
	m_sum[i] = m_sum[i - 1] + summ(m[i - 1])
	mm[i] = mm[i - 1] + m[i - 1]
ans = 0
for i in range(n + 1, 2 * n + 1):
	up = i
	down = 1
	mid = (1 + i) // 2
	while True:
		if mm[i] - mm[mid - 1] >= x > mm[i] - mm[mid]:
			z = mid
			break
		elif mm[i] - mm[mid - 1] > x:
			down = mid + 1
			mid = (up + down) // 2
		elif mm[i] - mm[mid - 1] < x:
			up = mid - 1
			mid = (up + down) // 2
	k = mm[i] - mm[z - 1] - x
	temp = m_sum[i] - m_sum[z - 1] - summ(k)
	if temp > ans:
		ans = temp
print(ans)


def findMonth(days, d):
	if d <= days[0]:
		return 0
	low = 0
	high = len(days)
	while True:
		mid = (low + high) // 2
		if d <= days[mid] and (mid >= 0 and d > days[mid - 1]):
			return mid
		elif d > days[mid]:
			low = mid + 1
		else:
			high = mid - 1

def s(x, y):
	return (y - x + 1) * (x + y) // 2

def total(days, hugs, n, d, x):
	currentDay = days[n]
	startDay = (currentDay - d + 1) % (days[-1] + 1)
	startMonth = findMonth(days, startDay)
	leftOverDays = days[startMonth] - startDay + 1
	startMonthDays = x[startMonth]
	leftover = s(startMonthDays - leftOverDays + 1, startMonthDays)
	if startMonth <= n:
		return hugs[n] - hugs[startMonth] + leftover
	else:
		return hugs[n] + hugs[-1] - hugs[startMonth] + leftover

def f(arr, x):
	totalDays = -1
	days = []
	totalHugs = 0
	hugs = []
	for i in arr:
		totalDays += i
		days.append(totalDays)
		totalHugs += i * (i + 1) // 2
		hugs.append(totalHugs)
	m = 0
	for i in range(len(arr)):
		m = max(m, total(days, hugs, i, x, arr))
	return m
nx = input().rstrip().split()
n = nx[0]
x = int(nx[1])
arr = input().rstrip().split()
arr = [int(i) for i in arr]
print(f(arr, x))


from bisect import bisect_left
(n, m) = map(int, input().split())
l = list(map(int, input().split()))
l = l + l
p = [0, l[0]]
s = [0, l[0] * (l[0] + 1) // 2]
for i in range(2, 2 * n):
	p.append(p[i - 1] + l[i - 1])
	s.append(s[i - 1] + l[i - 1] * (l[i - 1] + 1) // 2)
an = 0
for i in range(1, n + 1):
	le = m + p[i - 1]
	ind = bisect_left(p, le)
	di = p[ind] - p[i - 1] - m
	can = s[ind] - s[i - 1] - di * (di + 1) // 2
	an = max(an, can)
print(an)


import sys
input = sys.stdin.readline

def ceil(x):
	if x != int(x):
		x = int(x) + 1
	return x

def swaparr(arr, a, b):
	temp = arr[a]
	arr[a] = arr[b]
	arr[b] = temp

def gcd(a, b):
	if b == 0:
		return a
	return gcd(b, a % b)

def nCr(n, k):
	if k > n - k:
		k = n - k
	res = 1
	for i in range(k):
		res = res * (n - i)
		res = res / (i + 1)
	return int(res)

def upper_bound(a, x, lo=0, hi=None):
	if hi == None:
		hi = len(a)
	while lo < hi:
		mid = (lo + hi) // 2
		if a[mid] < x:
			lo = mid + 1
		else:
			hi = mid
	return lo

def primefs(n):
	primes = {}
	while n % 2 == 0 and n > 0:
		primes[2] = primes.get(2, 0) + 1
		n = n // 2
	for i in range(3, int(n ** 0.5) + 2, 2):
		while n % i == 0 and n > 0:
			primes[i] = primes.get(i, 0) + 1
			n = n // i
	if n > 2:
		primes[n] = primes.get(n, 0) + 1
	return primes

def power(x, y, p):
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def swap(a, b):
	temp = a
	a = b
	b = temp
	return (a, b)

def find(x, link):
	p = x
	while p != link[p]:
		p = link[p]
	while x != p:
		nex = link[x]
		link[x] = p
		x = nex
	return p

def union(x, y, link, size):
	x = find(x, link)
	y = find(y, link)
	if size[x] < size[y]:
		(x, y) = swap(x, y)
	if x != y:
		size[x] += size[y]
		link[y] = x

def sieve(n):
	prime = [True for i in range(n + 1)]
	p = 2
	while p * p <= n:
		if prime[p] == True:
			for i in range(p * p, n + 1, p):
				prime[i] = False
		p += 1
	return prime
MAXN = int(100000.0 + 5)

def spf_sieve():
	spf[1] = 1
	for i in range(2, MAXN):
		spf[i] = i
	for i in range(4, MAXN, 2):
		spf[i] = 2
	for i in range(3, ceil(MAXN ** 0.5), 2):
		if spf[i] == i:
			for j in range(i * i, MAXN, i):
				if spf[j] == j:
					spf[j] = i

def factoriazation(x):
	ret = {}
	while x != 1:
		ret[spf[x]] = ret.get(spf[x], 0) + 1
		x = x // spf[x]
	return ret

def int_array():
	return list(map(int, input().strip().split()))

def float_array():
	return list(map(float, input().strip().split()))

def str_array():
	return input().strip().split()
MOD = int(1000000000.0) + 7
CMOD = 998244353
INF = float('inf')
NINF = -float('inf')
(n, x) = int_array()
a = int_array()
a += a
i = 0
j = n - 1
ans = 0
cnt = sum(a) // 2
val = 0
for pk in a:
	val += pk * (pk + 1) // 2
val //= 2
while j < 2 * n:
	if cnt - a[i] >= x:
		cnt -= a[i]
		val -= a[i] * (a[i] + 1) // 2
		i += 1
	else:
		not_take = cnt - x
		not_val = not_take * (not_take + 1) // 2
		ans = max(ans, val - not_val)
		j += 1
		if j < 2 * n:
			cnt += a[j]
			val += a[j] * (a[j] + 1) // 2
print(ans)


from bisect import bisect
from queue import LifoQueue

def print_sol(c, sol):
	print('Case #{}: {}'.format(c, sol))

def rd_int():
	return int(input())

def rd_str():
	return input()

def rd_str_lst():
	return input().split(' ')

def sp_str_lst():
	return list(input())

def rd_int_lst():
	return [int(i) for i in rd_str_lst()]

def sp_int_lst():
	return [int(i) for i in sp_str_lst()]

def dfs(g, i, v):
	v[i] = True
	for j in g[i]:
		if not v[j]:
			dfs(g, j, v)
	print(i)

def dfs_iter(g, i, n):
	v = [False] * n
	stack = LifoQueue()
	stack.put(i)
	while stack.not_empty:
		u = stack.get()
		v[u] = True
		print(u)
		for i in g[u]:
			if not v[i]:
				stack.put(i)

def calc_psum1(n, d):
	psum1 = [0] * (2 * n + 1)
	for i in range(1, 2 * n + 1):
		hugs = d[i - 1] * (d[i - 1] + 1) // 2
		psum1[i] = psum1[i - 1] + hugs
	return psum1[1:]

def calc_psum2(n, d):
	psum2 = [0] * (2 * n + 1)
	for i in range(1, 2 * n + 1):
		psum2[i] = psum2[i - 1] + d[i - 1]
	return psum2[1:]

def calc_hugs(x, end, psum1, psum2):
	op = psum2[end] - x
	opi = bisect(psum2, op, 0, end)
	tdays = psum2[end] - psum2[opi - 1]
	thugs = psum1[end] - psum1[opi - 1]
	edays = tdays - x
	ehugs = edays * (edays + 1) // 2
	return thugs - ehugs

def best_vacation(n, x, d):
	psum1 = calc_psum1(n, d)
	psum2 = calc_psum2(n, d)
	max_hugs = 0
	for end in range(2 * n - 1, n - 1, -1):
		hugs = calc_hugs(x, end, psum1, psum2)
		max_hugs = max(max_hugs, hugs)
	return max_hugs

def main():
	(n, x) = rd_int_lst()
	s = rd_int_lst()
	d = s + s
	sol = best_vacation(n, x, d)
	print(sol)
main()


from sys import stdin
input = stdin.readline
(n, x) = map(int, input().split())
arr = list(map(int, input().split()))
arr += arr
n = len(arr)
parr = []
p = 0
mc = 0
for i in reversed(range(n)):
	j = i - mc
	while j >= 0 and x - arr[j] >= 0:
		d = arr[j]
		mc += 1
		p += d * (d + 1) // 2
		x -= d
		j -= 1
	dl = 0
	if j >= 0 and x:
		d = arr[j]
		dl = d - x
		p += d * (d + 1) // 2 - dl * (dl + 1) // 2
		x = 0
	parr.append(p)
	d = arr[i]
	p -= d * (d + 1) // 2
	mc -= 1
	x += d
	if dl:
		d = arr[j]
		p -= d * (d + 1) // 2 - dl * (dl + 1) // 2
		x += d - dl
print(max(parr))


from itertools import accumulate

def binary_search(arr, v):
	l = 0
	r = len(arr) - 1
	ans = 0
	while l <= r:
		m = l + (r - l) // 2
		if arr[m] >= v:
			ans = m
			r = m - 1
		else:
			l = m + 1
	return ans
(m, x) = map(int, input().split())
arr = list(map(int, input().split()))
arr = arr[:] + arr[:]
m_length = list(accumulate(arr))
m_hugs = [0] * len(m_length)
for i in range(len(m_length)):
	m_hugs[i] = arr[i] * (arr[i] + 1) // 2
m_hugs = list(accumulate(m_hugs))
ans = 0
for i in range(m):
	end = -i - 1
	start = binary_search(m_length, m_length[-i - 1] - x + 1)
	remainder_day = x - (m_length[end] - m_length[start])
	arrival = arr[start] - remainder_day + 1
	start_hugs = (arrival + arr[start]) * (arr[start] - arrival + 1) // 2
	total_hugs = start_hugs + m_hugs[end] - m_hugs[start]
	ans = max(ans, total_hugs)
print(ans)


(n, x) = tuple(map(int, input().split()))
arr = list(map(int, input().split()))
arr += arr[:]
arr2 = [i * (i + 1) // 2 for i in arr]
ans = 0
for now_month in range(n, n * 2):
	if now_month == n:
		last_month = now_month
		count_obnim = 0
		count_days = 0
		while count_days + arr[last_month] <= x:
			count_days += arr[last_month]
			count_obnim += arr2[last_month]
			last_month -= 1
		dop_days = x - count_days
		nodop_days = arr[last_month] - dop_days
		dop_obnim = arr2[last_month] - nodop_days * (nodop_days + 1) // 2
		count_days += dop_days
		count_obnim += dop_obnim
	else:
		count_days += arr[now_month]
		count_days -= dop_days
		count_obnim += arr2[now_month]
		count_obnim -= dop_obnim
		while count_days > x:
			count_days -= arr[last_month + 1]
			count_obnim -= arr2[last_month + 1]
			last_month += 1
		dop_days = x - count_days
		nodop_days = arr[last_month] - dop_days
		dop_obnim = arr2[last_month] - nodop_days * (nodop_days + 1) // 2
		count_days += dop_days
		count_obnim += dop_obnim
	ans = max(ans, count_obnim)
print(ans)


(n, x) = map(int, input().split())
d = list(map(int, input().split()))
for i in range(n):
	d.append(d[i])
s = 0
s_hug = 0
st = 0
sum_day = [0]
month_hug = [0]
for i in range(len(d)):
	s += d[i]
	hug = (d[i] + 1) * d[i] // 2
	s_hug += hug
	month_hug.append(s_hug)
	sum_day.append(s)
	if st == 0 and s >= x:
		st = i + 1
le = 0
maxx = 0
for i in range(st, len(sum_day)):
	while sum_day[i] - sum_day[le + 1] >= x:
		le += 1
	hug = month_hug[i] - month_hug[le]
	day = sum_day[i] - sum_day[le]
	hug -= (day - x) * (day - x + 1) // 2
	maxx = max(maxx, hug)
print(maxx)


import math
(n, k) = map(int, input().split())
arr = list(map(int, input().split()))
for i in range(n):
	arr.append(arr[i])
pre1 = [0] * (2 * n)
pre2 = [0] * (2 * n)
pre1[0] = arr[0] * (arr[0] + 1) // 2
pre2[0] = arr[0]
for i in range(1, 2 * n):
	pre1[i] = pre1[i - 1] + arr[i] * (arr[i] + 1) // 2
	pre2[i] = pre2[i - 1] + arr[i]
maxim = 0
i = 2 * n - 1
while i >= n:
	ans = 0
	start = 0
	end = i
	mid = 0
	while start <= end:
		mid = (start + end) // 2
		if pre2[i] - pre2[mid] <= k:
			ans = mid
			end = mid - 1
		else:
			start = mid + 1
	temp = pre2[i] - pre2[ans - 1] - k
	summ = pre1[i] - pre1[ans - 1] - temp * (temp + 1) // 2
	maxim = max(maxim, summ)
	i -= 1
if n == 1 and k == 1:
	print('1')
else:
	print(maxim)


import os
import heapq
import sys
import math
from collections import defaultdict
from io import BytesIO, IOBase

def main():
	(n, d) = map(int, input().split())
	lis = [int(k) for k in input().split()]
	arr = [0] * (2 * n + 1)
	prefixsum = [0] * (2 * n + 1)
	prefixday = [0] * (2 * n + 1)
	for i in range(1, n + 1):
		arr[i] = lis[i - 1]
		arr[i + n] = lis[i - 1]
	for i in range(1, 2 * n + 1):
		prefixsum[i] = prefixsum[i - 1] + arr[i] * (arr[i] + 1) // 2
		prefixday[i] = prefixday[i - 1] + arr[i]
	result = 0
	for i in range(2 * n, n, -1):
		l = 1
		r = i
		index = i
		while l <= r:
			mid = (l + r) // 2
			if prefixday[i] - prefixday[mid] < d:
				index = mid
				r = mid - 1
			else:
				l = mid + 1
		rem = prefixday[i] - prefixday[index - 1] - d
		sm = prefixsum[i] - prefixsum[index - 1]
		minus = rem * (rem + 1) // 2
		sm -= minus
		result = max(result, sm)
	print(result)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


from bisect import bisect_left as bl
from bisect import bisect_right as br
from heapq import heappush, heappop
import math
from collections import *
from functools import reduce, cmp_to_key, lru_cache
from itertools import accumulate
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
M = mod = 10 ** 9 + 7

def factors(n):
	return sorted(set(reduce(list.__add__, ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0))))

def inv_mod(n):
	return pow(n, mod - 2, mod)

def li():
	return [int(i) for i in input().rstrip().split()]

def st():
	return str(input().rstrip())[2:-1]

def val():
	return int(input().rstrip())

def li2():
	return [str(i)[2:-1] for i in input().rstrip().split()]

def li3():
	return [int(i) for i in st()]
(n, x) = li()
l = li()
l = l + l
startindices = [0 for i in l]
i = j = ans = curr = days = 0
while j < 2 * n:
	if days + l[j] <= x:
		days += l[j]
		curr += l[j] * (l[j] + 1) // 2
	else:
		while l[j] + days - (l[i] - startindices[i]) > x:
			left = startindices[i]
			days -= l[i] - left
			curr -= l[i] * (l[i] + 1) // 2 - left * (left + 1) // 2
			i += 1
		deletetill = l[j] + days - x
		left = startindices[i]
		curr -= (left + deletetill) * (left + deletetill + 1) // 2 - left * (left + 1) // 2
		startindices[i] += deletetill
		days = x
		curr += l[j] * (l[j] + 1) // 2
	ans = max(ans, curr)
	j += 1
print(ans)


def main():
	(n, x) = map(int, input().split())
	d = list(map(int, input().split()))
	all_ob = list(map(lambda di: di * (di + 1) // 2, d))
	current_period = 0
	start_month = 0
	while current_period + d[start_month] < x:
		current_period += d[start_month]
		start_month -= 1
	z = x - current_period
	start_month_ob = z * (2 * d[start_month] - z + 1) // 2
	sum_ob = 0
	for i in range(start_month + 1, 1):
		sum_ob += all_ob[i]
	best_ans = start_month_ob + sum_ob
	for i in range(1, n):
		current_period += d[i]
		lm_ob = d[i] * (d[i] + 1) // 2
		sum_ob += lm_ob
		while current_period > x:
			start_month += 1
			current_period -= d[start_month]
			sum_ob -= all_ob[start_month]
		z = x - current_period
		start_month_ob = z * (2 * d[start_month] - z + 1) // 2
		best_ans = max(best_ans, start_month_ob + sum_ob)
	print(best_ans)
main()


import sys, random, math
from bisect import bisect_left, bisect_right
input = sys.stdin.readline

def main():
	inf = 10 ** 20
	t = 1
	for _ in range(1, t + 1):
		(n, x) = map(int, input().split())
		d = [int(x) for x in input().split()]
		d = d + d
		ps = [0]
		th = []
		tps = [0]

		def abc(l, r):
			return (l + r) * (r - l + 1) // 2
		for y in d:
			ps.append(ps[-1] + y)
			th.append(abc(1, y))
			tps.append(tps[-1] + th[-1])
		ans = -inf
		(l, r) = (0, 1)
		while r < 2 * n:
			mid = ps[r] - ps[l + 1]
			if mid >= x:
				l += 1
				continue
			if tps[r + 1] - tps[l] >= x:
				total = tps[r] - tps[l + 1]
				need = x - mid
				if need <= d[l]:
					total += abc(d[l] - need + 1, d[l])
				else:
					total += abc(1, min(need, d[r]))
					need -= min(need, d[r])
					if need:
						total += abc(d[l] - need + 1, d[l])
				ans = max(total, ans)
			r += 1
		print(ans)
main()


def countGreater(arr, n, k):
	l = 0
	r = n - 1
	leftGreater = n
	while l <= r:
		m = int(l + (r - l) / 2)
		if arr[m] >= k:
			leftGreater = m
			r = m - 1
		else:
			l = m + 1
	return n - leftGreater
(n, m) = map(int, input().split())
l = list(map(int, input().split()))
l = l + l
pre1 = [0] * (2 * n + 1)
t = 1
pre2 = [0] * (2 * n + 1)
for i in range(2 * n):
	pre1[t] = pre1[t - 1] + l[i % n]
	pre2[t] = pre2[t - 1] + (l[i % n] * l[i % n] + l[i % n]) // 2
	t += 1
tot = 0
for i in range(n):
	ans = 0
	c = 2 * n + 1 - countGreater(pre1, 2 * n + 1, pre1[i + n + 1] - m)
	ans = pre2[i + n + 1] - pre2[c]
	left = m - pre1[i + n + 1] + pre1[c]
	r = l[c - 1] - left
	ans += (l[c - 1] * l[c - 1] + l[c - 1]) // 2 - (r * r + r) // 2
	tot = max(tot, ans)
print(tot)


from bisect import *

def rnum():
	return int(input())

def rnums():
	return map(int, input().split())

def rlist():
	return list(map(int, input().split()))

def solve():
	(n, x) = rnums()
	mas = rlist()
	mas += mas
	(res1, res2) = (0, 0)
	pref = [0] * (2 * n)
	ans = [0] * (2 * n)
	for i in range(2 * n):
		if i == 0:
			pref[i] = mas[i]
			ans[i] = mas[i] * (mas[i] + 1) // 2
			continue
		pref[i] = pref[i - 1] + mas[i]
		ans[i] = ans[i - 1] + mas[i] * (mas[i] + 1) // 2
	for i in range(n):
		pos = bisect_left(pref, pref[i] + x)
		res1 = max(res1, mas[i] + ans[pos - 1] - ans[i] + (x + pref[i] - pref[pos - 1] - 1) * (x + pref[i] - pref[pos - 1]) // 2)
	mas.reverse()
	for i in range(2 * n):
		if i == 0:
			pref[i] = mas[i]
			ans[i] = mas[i] * (mas[i] + 1) // 2
			continue
		pref[i] = pref[i - 1] + mas[i]
		ans[i] = ans[i - 1] + mas[i] * (mas[i] + 1) // 2
	for i in range(n):
		if i == 0:
			pos = bisect_left(pref, x + 1)
			res2 = max(res2, ans[pos - 1] + mas[pos] * (mas[pos] + 1) // 2 - (mas[pos] - x + pref[pos - 1] + 1) * (mas[pos] - x + pref[pos - 1]) // 2)
		else:
			pos = bisect_left(pref, pref[i - 1] + x + 1)
			res2 = max(res2, ans[pos - 1] - ans[i - 1] + mas[pos] * (mas[pos] + 1) // 2 - (mas[pos] - x - pref[i - 1] + pref[pos - 1] + 1) * (mas[pos] - x - pref[i - 1] + pref[pos - 1]) // 2)
	print(max(res1, res2))

def main():
	t = 1
	for i in range(t):
		solve()
main()


import sys
import heapq

def input():
	return sys.stdin.readline().strip()

def iinput():
	return int(input())

def rinput():
	return map(int, input().split())

def rlinput():
	return list(map(int, input().split()))

def srlinput():
	return sorted(list(map(int, input().split())))

def main():
	(n, x) = rinput()
	q = rlinput()
	q = q + q
	q.reverse()
	(w, e) = ([0 for i in range(n * 2 + 1)], [0 for i in range(n * 2 + 1)])
	for i in range(n * 2):
		w[i + 1] = w[i] + q[i]
		e[i + 1] = e[i] + q[i] * (q[i] + 1) // 2
	r = 1
	res = x
	for i in range(n):
		while r <= 2 * n and w[r] <= x + w[i]:
			r += 1
		r -= 1
		res = max(res, e[r] - e[i] + (x - w[r] + w[i]) * (2 * q[r] - x + w[r] - w[i] + 1) // 2)
	print(res)
for i in range(1):
	main()


import math
from collections import *

def query():
	pass

def solve(n, x, A):
	ans = 0
	cur_month = 0
	days = 0
	hugs = 0
	for i in range(n):
		while days + A[cur_month] <= x:
			days += A[cur_month]
			hugs += A[cur_month] * (A[cur_month] + 1) // 2
			cur_month = (cur_month + 1) % n
		extra_hugs = (x - days) * (x - days + 1) // 2
		ans = max(ans, hugs + extra_hugs)
		if days == 0:
			cur_month = (cur_month + 1) % n
		days = max(0, days - A[i])
		hugs = max(0, hugs - A[i] * (A[i] + 1) // 2)
	cur_month = n - 1
	days = 0
	hugs = 0
	for i in range(n - 1, -1, -1):
		while days + A[cur_month] <= x:
			days += A[cur_month]
			hugs += A[cur_month] * (A[cur_month] + 1) // 2
			cur_month = (cur_month - 1) % n
		extra_hugs = (x - days) * (x - days + 1) // 2 + (A[cur_month] - x + days) * (x - days)
		ans = max(ans, hugs + extra_hugs)
		if days == 0:
			cur_month = (cur_month - 1) % n
		days = max(0, days - A[i])
		hugs = max(0, hugs - A[i] * (A[i] + 1) // 2)
	return ans
t = 1
for test_num in range(t):
	(n, x) = list(map(int, input().split()))
	A = list(map(int, input().split()))
	output_string = solve(n, x, A)
	print('{}'.format(output_string))


from sys import stdin
from collections import Counter, deque
from bisect import bisect_left
input = stdin.buffer.readline
(n, x) = map(int, input().split())
day = list(map(int, input().split())) * 2
(dcc, hsm) = ([], [])
for d in day:
	dcc.append(d if not dcc else dcc[-1] + d)
	hsm.append(d * (d + 1) // 2 if not hsm else hsm[-1] + d * (d + 1) // 2)
mx = 0
for i in range(2 * n):
	if dcc[i] < x:
		continue
	r = dcc[i] - x
	p = bisect_left(dcc, r)
	pday = r - (0 if p == 0 else dcc[p - 1])
	psm = (0 if p == 0 else hsm[p - 1]) + pday * (pday + 1) // 2
	mx = max(mx, hsm[i] - psm)
print(mx)


(n, m) = map(int, input().split())
arr = list(map(int, input().split()))
arr = arr * 2
i = j = ans = td = days = 0
while i < n:
	while days < m:
		days += arr[j]
		td += arr[j] * (arr[j] + 1) // 2
		j = j + 1
	ans = max(ans, td - (days - m) * (days - m + 1) // 2)
	days -= arr[i]
	td -= arr[i] * (arr[i] + 1) // 2
	i = i + 1
print(ans)


from sys import stdin, stdout
input = stdin.readline

def binarySearch(daysPrefix, target, low, high):
	while low < high:
		mid = low + (high - low + 1) // 2
		if daysPrefix[mid] == target:
			return mid
		elif daysPrefix[mid] < target:
			low = mid
		else:
			high = mid - 1
	return low
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
days = d + d
(score, day) = (0, 0)
scorePrefix = []
daysPrefix = []
for value in days:
	score += value * (value + 1) // 2
	scorePrefix.append(score)
	day += value
	daysPrefix.append(day)
mx = 0
for index in range(2 * n - 1, n - 1, -1):
	search = daysPrefix[index] - x
	ind = binarySearch(daysPrefix, search, 0, index - 1)
	daysValue = daysPrefix[index] - daysPrefix[ind]
	scoreValue = scorePrefix[index] - scorePrefix[ind]
	dayDiff = daysValue - x
	scoreDiff = dayDiff * (dayDiff + 1) // 2
	mx = max(scoreValue - scoreDiff, mx)
print(mx)


def binary_search(p, lo, hi, val, arr):
	while hi - lo > 1:
		mid = lo + (hi - lo) // 2
		if arr[p] - arr[mid] == x:
			break
		elif arr[p] - arr[mid] > x:
			lo = mid
		else:
			hi = mid
	return lo
(n, x) = list(map(int, input().split()))
arr = list(map(int, input().split()))
arr = arr * 2
pre = [0] * (2 * n)
for i in range(2 * n):
	pre[i] = arr[i] * (arr[i] + 1) // 2
for i in range(1, 2 * n):
	arr[i] += arr[i - 1]
	pre[i] += pre[i - 1]
ans = 0
for i in range(2 * n - 1, -1, -1):
	l = binary_search(i, 0, 2 * n - 1, x, arr)
	e = arr[i] - arr[l] - x
	total = pre[i] - pre[l]
	total -= e * (e + 1) // 2
	ans = max(ans, total)
print(ans)


import sys
input = sys.stdin.readline
import bisect
(n, x) = map(int, input().split())
d = list(map(int, input().split()))
cd = [d[i] for i in range(n)] + [d[i] for i in range(n)] + [d[0]]
c_score = [d[i] * (d[i] + 1) // 2 for i in range(n)] + [d[i] * (d[i] + 1) // 2 for i in range(n)] + [d[0] * (d[0] + 1) // 2]
for i in range(1, 2 * n + 1):
	cd[i] += cd[i - 1]
	c_score[i] += c_score[i - 1]
rev_cd = [d[i] for i in range(n)[::-1]] + [d[i] for i in range(n)[::-1]] + [d[-1]]
rev_c_score = [d[i] * (d[i] + 1) // 2 for i in range(n)[::-1]] + [d[i] * (d[i] + 1) // 2 for i in range(n)[::-1]] + [d[-1] * (d[-1] + 1) // 2]
for i in range(1, 2 * n + 1):
	rev_cd[i] += rev_cd[i - 1]
	rev_c_score[i] += rev_c_score[i - 1]
ans = 0
for i in range(n):
	idx = bisect.bisect_right(cd, cd[i] + x) - 1
	delta_day = x - (cd[idx] - cd[i])
	res = delta_day * (delta_day + 1) // 2 + c_score[idx] - c_score[i]
	ans = max(ans, res)
	idx2 = bisect.bisect_right(rev_cd, rev_cd[i] + x) - 1
	delta_day2 = x - (rev_cd[idx2] - rev_cd[i])
	t1 = rev_cd[idx2 + 1] - rev_cd[idx2]
	t2 = t1 - delta_day2
	res2 = t1 * (t1 + 1) // 2 - t2 * (t2 + 1) // 2 + rev_c_score[idx2] - rev_c_score[i]
	ans = max(ans, res2)
print(ans)


import sys
import math
import collections

def set_debug(debug_mode=False):
	if debug_mode:
		fin = open('input.txt', 'r')
		sys.stdin = fin
t = 1
for ti in range(1, t + 1):
	(n, x) = map(int, input().split())
	l = list(map(int, input().split()))
	l *= 2
	num = 0
	res = 0
	val = 0
	j = 0
	for i in range(n):
		while num < x:
			num += l[j]
			val += l[j] * (l[j] + 1) // 2
			j += 1
			if j == n:
				j = 0
		res = max(res, val - (num - x) * (num - x + 1) // 2)
		num -= l[i]
		val -= l[i] * (l[i] + 1) // 2
	print(res)


from sys import stdin, stdout
from bisect import bisect_left

def find(arr, N, X, arms):
	RR = 0
	S = sum(arr)
	SS = sum([arms[x] for x in arr])
	RR += SS * (X // S)
	X = X % S
	cf = [0]
	for i in arr:
		cf.append(cf[-1] + i)
	for i in arr:
		cf.append(cf[-1] + i)
	cf.pop(0)
	nod = [0]
	for i in arr:
		nod.append(nod[-1] + arms[i])
	for i in arr:
		nod.append(nod[-1] + arms[i])
	nod.pop(0)
	res = 0
	for i in range(N, len(cf)):
		K = cf[i] - X
		Z = bisect_left(cf, K)
		Y = cf[Z] - K
		R = nod[i] - nod[Z]
		if Y > 0:
			R += arms[arr[Z - N]] - arms[arr[Z - N] - Y]
		res = max(res, R)
	return RR + res

def main():
	arms = [0]
	for i in range(1, 10 ** 6 + 2):
		arms.append(arms[-1] + i)
	(N, X) = list(map(int, stdin.readline().split()))
	arr = list(map(int, stdin.readline().split()))
	print(find(arr, N, X, arms))
main()


from math import *
from sys import stdin, stdout
input = stdin.buffer.readline
(n, x) = [int(x) for x in input().split()]
d = [int(x) for x in input().split()]
s = sum(d)
mul = x // s
x = x % s
n1 = n
a = []
for i in range(n1):
	a.append([d[i], d[i] * (d[i] + 1) // 2])
a = a + a
l = 0
r = 0
m = 0
total = 0
days = 0
a.reverse()
n = len(a)
while l < n and r < n:
	while l < n and r < n and (days + a[r][0] <= x):
		days += a[r][0]
		total += a[r][1]
		r += 1
	rem = x - days
	if r < n:
		temp = a[r][1]
		rem = a[r][0] - rem
		total = total + (temp - rem * (rem + 1) // 2)
		if m < total:
			m = total
		total = total - (temp - rem * (rem + 1) // 2)
	l += 1
	days = days - a[l - 1][0]
	total = total - a[l - 1][1]
year = 0
for i in range(n1):
	year += a[i][1]
print(m + mul * year)


def BS(arr, l, n, tar, mo):
	r = n + l - 1
	const = arr[l] - mo[l]
	while l < r:
		mid = l + (r - l) // 2
		if arr[mid] - const >= tar:
			r = mid
		else:
			l = mid + 1
	return l
(n, x) = list(map(int, input().split(' ')))
arr = list(map(int, input().split(' ')))
month = arr[:]
month += month
days = [0 for i in range(2 * n)]
days[0] = month[0]
for i in range(1, 2 * n):
	days[i] += days[i - 1] + month[i]
for i in range(n):
	arr[i] = arr[i] * (arr[i] + 1) // 2
new = arr + arr
hug = [0 for i in range(2 * n)]
hug[0] = new[0]
for i in range(1, 2 * n):
	hug[i] += hug[i - 1] + new[i]
MAX = 0
for i in range(n):
	r = BS(days, i, n, x, month)
	tt = hug[r] - hug[i + 1] + new[i + 1]
	temp = days[r] - days[i + 1] + month[i + 1]
	temp = x - temp
	temp = month[i] - temp
	tt += new[i] - temp * (temp + 1) // 2
	MAX = max(MAX, tt)
print(MAX)


import sys
lines = sys.stdin.readlines()
(n, x) = map(int, lines[0].strip().split(' '))
days = list(map(int, lines[1].strip().split(' ')))

def cal(x):
	return x * (x + 1) // 2
val = 0
D = x
pt = 0
while D - days[pt] >= 0:
	D -= days[pt]
	val += cal(days[pt])
	pt = (pt + 1) % n
val += cal(D)
endM = pt
endD = D
maxi = val
for i in range(n):
	move = days[i]
	val -= cal(days[i])
	val -= cal(endD)
	move += endD
	while move - days[endM] >= 0:
		val += cal(days[endM])
		move -= days[endM]
		endM = (endM + 1) % n
	val += cal(move)
	endD = move
	maxi = max(maxi, val)
val = 0
D = x
pt = n - 1
while D - days[pt] >= 0:
	D -= days[pt]
	val += cal(days[pt])
	pt = (pt - 1) % n
val += cal(days[pt]) - cal(days[pt] - D)
endM = pt
endD = D
maxi = max(maxi, val)
for i in range(n - 1, -1, -1):
	move = days[i]
	val -= cal(days[i])
	val -= cal(days[endM]) - cal(days[endM] - endD)
	move += endD
	while move - days[endM] >= 0:
		val += cal(days[endM])
		move -= days[endM]
		endM = (endM - 1) % n
	val += cal(days[endM]) - cal(days[endM] - move)
	endD = move
	maxi = max(maxi, val)
print(maxi)