Problem:
スコーン配達計画

愛歌さんの家は、小さな喫茶店を経営しています。愛歌さんのお母さんが焼くスコーンはとても美味しくて、店はとても繁盛していました。

ウェイトレスである愛歌さんの仕事の一つは、次々と焼き上がるスコーンを、お客様の席まで届けることです。焼きあがったスコーンはお盆の上に乗せられ、カウンターの上に一列に並べられます。i 番目のお盆の上に乗っているスコーンの数を Ki としましょう。愛歌さんは、それぞれのお客様にちょうど m 個のスコーンを運ばなければなりません。愛歌さんは一度にいくつでもお盆を持つことができ、また複数のお盆から 1 人のお客様にスコーンを配ったり、１つのお盆から複数のお客様に配っても構いません。

喫茶店にはとてもたくさんのお客様がやってくるので、カウンターに置いてある全てのスコーンを運んでも、全てのお客様に届けることはできません。しかし、できるだけ多くのお客様に届けた後で、m 個に満たない数のスコーンが余ることもあるかもしれません。そのようなスコーンは、お手伝いのご褒美として、愛歌さんが貰えることになりました。

ここでふと、愛歌さんは考えました。一度に全てのお盆を持つのではなく、一部のお盆だけを持ってお客様にスコーンを届けると、余るスコーンの数も違ってくるはずです。適切にお盆を選ぶことで、より多くのスコーンが余るようにできるかもしれません。愛歌さんは、作為的にお盆を選んでいることをお母さんに見抜かれないように、カウンターの上の1つの連続した範囲のお盆を選ぶことにしました。また、残ったお盆はお父さんやお母さんが運んでしまうので、愛歌さんがスコーンをもらうチャンスは一度しかありません。

さて、愛歌さんは最大いくつのスコーンを貰えるでしょうか？計算するプログラムを書いてください。お盆の数 n は 1 以上 30,000以下、 m は 1 以上 100,000 以下です。また数列の各要素 Ki は 0 以上 232-1 です。

入力

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下のとおりです。

1行目 n m（整数 整数；半角空白区切り）

2行目 お盆上のスコーンの情報 K1 K2 ... Kn（すべて整数 ; 半角空白区切り）

Ki: i番目のお盆上のスコーンの数

データセットの数は 50 を超えません。

出力

データセットごとに、もらえるスコーンの最大数を１行に出力します。

入力例

5 11
11 27 34 45 56
8 5
0 2 1 5 4 6 8 3
5 2
2 4 2 4 6
10 18
10 15 12 31 12 50 11 23 43 181
1 100
5
0 0

出力例

8
4
0
17
5

Solution in C (judge verdict: Time Limit Exceeded)

#include <stdio.h>

int main(void) {
	int n, m;
	
	while (scanf("%d%d", &n, &m), n) {
		int i, j, max = 0;
		int l[100000], r[100000];
		
		long long s = 0;
		
		l[0] = 0;
		r[0] = 0;

		for (i = 1; i < m; ++i) {
			l[i] = 30001; // ??????????????????
			r[i] = -1;    // ??????????????????
		}
		
		for (i = 1; i <= n; ++i) {
			unsigned int t;
			scanf("%u", &t);
			s = (s + t) % m;
			
			l[s] = i < l[s] ? i : l[s]; // ??????
			r[s] = i > r[s] ? i : r[s]; // ??????
			
			max = max < s ? s : max;
		}
		
		// ????????????????????°???
		for (i = 1; i < m; ++i) {
			if (r[i] > 0) {
				// ??????????????????????????´????????°???
				for (j = 1; j < m - max; ++j) {
					// ?????´????????¢???????????°OK
					if (l[i + j] < r[i]) {
						max = m - j;
						break;
					}
				}
			}
		}

		printf("%d\n", max);
	}
	
	return 0;
}