Problem:
ゲームバランス
あなたは冒険ゲームを作成している．このゲームのプレイヤーは，主人公を操作して敵モンスターを倒し，主人公のレベルを上げることで冒険を進めていく．主人公の初期レベルは 1 である．
このゲームには
N
種類の敵モンスターが用意されており，弱い順で
i
番目の種類の敵モンスターの強さは
s
i
である．主人公が 1 回の戦闘を行うときには，次に戦う敵モンスターの種類を自由に選び，ちょうど 1 体の敵モンスターと戦闘を行う．主人公は同じ種類の敵モンスターと何回でも戦うことができ，何回でも倒すことができる．
あなたはいま，このゲームのバランスを調整するために，あるパラメーター
X
を決めようとしている．パラメーター
X
は正の整数であり下記のように使われる．
主人公のレベルが
L
のとき，強さ
s
i
が
L+X
未満の敵は倒せるが，それより強い敵モンスターは倒せない．
主人公のレベルが
L
のとき，強さ
s
i
の敵を倒すと
max(1, X-|L-s
i
|)
だけ主人公のレベルが上がる．
このゲームは，最も強い（
N
種類目の）敵モンスターを初めて倒したときにゲームクリアとなる．あなたは，ゲームクリアまでに必要となる戦闘の回数が最低でも
M
回以上となるようにパラメーター
X
を決めたいと考えている．ただし，敵モンスターの強さの設定によっては，
X
をどのように設定しても
M
回未満の戦闘回数でゲームクリアできてしまうか，ゲームをクリアできなくなってしまう場合があることに注意せよ．
パラメーター
X
を決めるとき，上記の条件を満たす範囲で最大のパラメーター値
X
max
を計算するプログラムを作ってほしい．
Input
入力は複数のデータセットから構成される．データセットの個数は最大でも 50 を超えない．各データセットは次の形式で表される．
N
M
s
1
s
2
...
s
N
1 行目は空白で区切られた 2 つの整数
N, M
からなる．
N
は用意した敵モンスターの種類の数，
M
はゲームクリアまでに必要となるべき最小の戦闘の数であり，
1 ≤ N ≤ 100,000
,
2 ≤ M ≤1,000,000
を満たす．
2 行目は空白で区切られた
N
個の整数
s
1
, s
2
, ..., s
N
からなり，
N
種類の敵モンスターそれぞれの強さを表す．各
s
i
は
1 ≤ s
i
≤ 1,000,000
を満たし，また
s
i
< s
i+1
(
1 ≤ i ≤ N-1
) である．
入力の終わりは空白で区切られた 2 つのゼロからなる行で表される．
Output
各データセットについて，ゲームクリアまでに必要となる戦闘の回数が
M
回以上となるパラメーター
X
の内の最大値
X
max
を整数で出力せよ．
X
をどのように設定しても
M
回未満の戦闘回数でゲームクリアできてしまうかゲームをクリアできなくなってしまうテストケースの場合には
-1
のみからなる行を出力せよ．
Sample Input
3 4
1 5 9
1 2
1
2 10
1 1000000
2 4
1 10
0 0
Output for Sample Input
3
-1
499996
4
2 番目のテストケースでは，
X
= 1 と設定すると 1 回の戦闘でゲームをクリアできてしまう．
    このケースでは，必要となる戦闘の回数が
M
回以上であり，かつゲームをクリアできるように
X
を設定することが出来ない．
    よって -1 のみからなる行を出力する．

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define FOR(i,s,t ) for (int i = s; i < t ; i++)
using LL = long long; using VI = vector<int>;
using VL = vector<LL>; using VVI = vector<VI>;
const LL LINF = 1e18; const int INF = 1e9;
#define SZ(a) (int)a.size()


int f(LL x, VL a) {

	LL lv = 1;
	int cnt = 1;
	while (lv + x <= a.back()) {
		LL uplv = 1;
		// あがるのはにとおりのみ
		int over = lower_bound(a.begin(), a.end(), lv)-a.begin();
		if (over != SZ(a)) {
			uplv = max(uplv, x - abs(lv-a[over]));
		}
		if (over) {
			uplv = max(uplv, x - abs(lv - a[over - 1]));
		}
		lv += uplv;
		cnt++;
	}
	return cnt;


}



void solve() {

	int N, M;
	while (cin >> N >> M, N || M) {
		VL a(N);
		FOR(i, 0, N) {
			cin >> a[i];
		}

		int L = a[0], R = INF;
		if (f(L,a)<M) { //条件を満たせない
			cout << -1 << endl;
		}
		else {
			FOR(i, 0, 40) {
				int mid = (R + L) / 2;
				if (f(mid, a)>=M) {
					L = mid;
				}
				else {
					R = mid;
				}
			}
			cout << L << endl;
		}
	}


}


int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);

	solve();
	return 0;
}
accuracy: 1
time_ms: 930
memory_kb: 4804
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#include <unordered_map>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
//constexpr ll MOD = 1000000007;
constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}


ll gcd(ll a, ll b){
    if(a%b == 0){
      return b;
    }else{
      return gcd(b, a%b);
    }
}

ll lcm(ll a, ll b){
    return a*b / gcd(a, b);
}

ll powMod(ll x, ll n) {
    if (n == 0) return 1 % MOD;
    ll val = powMod(x, n / 2);
    val *= val;
    val %= MOD;
    if (n % 2 == 1) val *= x;
    return val % MOD;
}

int main() {
    while(true){
        ll n, m; cin >> n >> m;
        if(n == 0) break;
        vector<ll> s(n);
        rep(i,0,n) cin >> s[i];

        ll ok = s[0]-1, ng = IINF;
        auto e = [&](ll x, ll l, ll si) -> ll {
            return max(1LL, x-abs(l-si));
        };

        while(ng-ok > 1){
            ll mid = (ok+ng)/2;
            ll cnt = 1;
            ll level = 1;
            ll l = 0;
            while(s[n-1] >= level+mid){
                while(l < n && s[l] < level) l++;
                ll pos = l;
                if(l == n){
                    pos = n-1;
                }else if(l == 0 && level+mid <= s[l]){
                    cnt = IINF;
                    break;
                }else if(0 < l && e(mid, level, s[l-1]) > e(mid, level, s[l])){
                    pos = l-1;
                }
                level += e(mid, level, s[pos]);
                cnt++;
            }
            // cout << mid << ' ' << l << ' ' << cnt << endl;
            if(cnt >= m) ok = mid;
            else ng = mid;
        }

        if(ok == s[0]-1) cout << -1 << endl;
        else cout << ok << endl;

    }
    return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 4304
final_rank: 9

code_snippet: #include <bits/extc++.h>

using ll = long long;
using namespace std;
#define REP(i, n) for (ll i = 0; i < ll(n); i++)
#define ALL(n) (n).begin(), (n).end()

pair<bool, ll> solve2(ll n, ll x, vector<ll> &s) {
  ll l = 1, cnt = 0;
  // cout << x << " !!" << endl;
  while (1) {
    cnt++;
    if (l + x > s[n - 1]) break;
    ll i = lower_bound(ALL(s), l) - s.begin();
    ll j = -1;
    if (i != 0) j = i - 1;
    ll nmax = 1;
    bool nok = false;
    if (s[i] < l + x) {
      nmax = max(nmax, x - abs(l - s[i]));
      nok = true;
    }
    if (j >= 0 and s[j] < l + x) {
      nmax = max(nmax, x - abs(l - s[j]));
      nok = true;
    }
    if (!nok) {
      return pair<bool, ll>(false, -1);
    }
    l += nmax;
  }
  // cout << cnt << " okk" << endl;
  return pair<bool, ll>(true, cnt);
}

bool solve() {
  ll n, m;
  cin >> n >> m;
  if (n == 0 and m == 0) return false;
  vector<ll> s(n);
  REP(i, n) cin >> s[i];
  ll ok = 10000000, ng = 0;
  while (ok - ng > 1) {
    ll x = (ok + ng) / 2;
    pair<bool, ll> res;
    bool ook;
    ll cnt;
    res = solve2(n, x, s);
    ook = res.first, cnt = res.second;
    if (ook and cnt < m) {
      ok = x;
    } else {
      ng = x;
    }
  }
  cout << (solve2(n, ng, s).first ? ng : -1) << endl;
  return true;
}
int main() {
  while (solve());
}
accuracy: 1
time_ms: 1410
memory_kb: 4368
final_rank: 15

code_snippet: #pragma region Macros
#include <bits/stdc++.h>

using namespace std;
using lint = long long;
using ull = unsigned long long;
using ld = long double;
using int128 = __int128_t;
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define uniqv(v) v.erase(unique(all(v)), v.end())
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define log(x) cout << x << endl
#define logfixed(x) cout << fixed << setprecision(10) << x << endl;
#define logy(bool)         \
  if (bool) {              \
    cout << "Yes" << endl; \
  } else {                 \
    cout << "No" << endl;  \
  }

ostream &operator<<(ostream &dest, __int128_t value) {
  ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(ios_base::badbit);
    }
  }
  return dest;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    os << v[i] << (i + 1 != (int)v.size() ? " " : "");
  }
  return os;
}

template <typename T>
ostream &operator<<(ostream &os, const set<T> &set_var) {
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    ++itr;
    if (itr != set_var.end()) os << " ";
    itr--;
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << itr->first << " -> " << itr->second << "\n";
  }
  return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}

void out() { cout << '\n'; }
template <class T, class... Ts>
void out(const T &a, const Ts &...b) {
  cout << a;
  (cout << ... << (cout << ' ', b));
  cout << '\n';
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}

inline void in(void) { return; }
template <typename First, typename... Rest>
void in(First &first, Rest &...rest) {
  cin >> first;
  in(rest...);
  return;
}

template <typename T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

vector<lint> dx8 = {1, 1, 0, -1, -1, -1, 0, 1};
vector<lint> dy8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<lint> dx4 = {1, 0, -1, 0};
vector<lint> dy4 = {0, 1, 0, -1};

#pragma endregion

bool check(const vector<lint> &s, lint x, lint m) {
  lint cnt = 0;
  lint l = 1;
  lint n = s.size();
  while (s[n - 1] >= l + x) {
    auto it = lower_bound(all(s), l);
    lint min_abs = 1e15;
    if (*it < l + x) {
      chmin(min_abs, abs(l - *it));
    }
    if (it != s.begin()) {
      it--;
      if (*it < l + x) {
        chmin(min_abs, abs(l - *it));
      }
    }

    if (min_abs == 1e15) {
      return false;
    }

    lint add_l = max(1ll, x - min_abs);
    l += add_l;
    cnt++;
  }
  cnt++;

  return m <= cnt;
}

int main() {
  cin.tie(0)->sync_with_stdio(0);

  int n, m;
  while (1) {
    in(n, m);
    if (n == 0 and m == 0) break;

    vector<lint> s(n);
    in(s);

    // m<=cnt
    // s_0 < 1+X
    lint ok = s[0] - 1;
    lint ng = s[n - 1];
    lint mid;
    bool suc = false;
    while (abs(ok - ng) > 1) {
      mid = (ok + ng) / 2;
      if (check(s, mid, m)) {
        ok = mid;
        suc = true;
      } else {
        ng = mid;
      }
    }
    if (suc) {
      out(ok);
    } else {
      out(-1);
    }
  }
}
accuracy: 1
time_ms: 1730
memory_kb: 4256
final_rank: 17

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define inf 4000000000000000000LL
#define mod 998244353LL
#define eps 0.000000001
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード

//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int

//#include<atcoder/lazysegtree>

//√の値が整数かを調べる
bool isSqrt(ll n) {
	if (n < 0) return false;
	ll sqrtN = static_cast<ll>(sqrt(n));
	return sqrtN * sqrtN == n;
}

//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

//素因数分解
vector<ll> makePrime(ll n){
	vector<ll> factors;
	while (n % 2 == 0) {
		factors.push_back(2);
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors.push_back(i);
			n /= i;
		}
	}
	if (n > 2) {
		factors.push_back(n);
	}
	return factors;
}

//map形式で、nを素因数分解した値を返す
map<ll,ll> makeMapPrime(ll n){
	map<ll,ll> factors;
	while (n % 2 == 0) {
		factors[2]++;
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors[i]++;
			n /= i;
		}
	}
	if (n > 2) {
		factors[n]++;
	}
	return factors;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}

//mod mにおけるaの逆元を計算
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m; 
	if (u < 0) u += m;
	return u;
}

//場合の数 nCr を求める
ll ncr(ll n,ll r) {
	if(n<r)return 0;
	vvl dp(n+1,vl(r+1));
	rep (i,n+1)dp[i][0] = 1;
	rep (i,r+1)dp[i][i] = 1;
	loop (i,1,n){
		loop (j,1,min((ll)i-1,r)) {
			//nCr= n-1Cr-1 + n-1Cr
			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
		}
	}
	return dp[n][r];
}

//受け取った文字列を、第2引数が0なら全て小文字に、1なら大文字に変換する関数
string cnvString(const string &str, int mode) {
	string result = str;
	if (mode == 0) {
		// 小文字に変換
		for (char &c : result) {
			c = tolower(c);
		}
	} else if (mode == 1) {
		// 大文字に変換
		for (char &c : result) {
			c = toupper(c);
		}
	}
	return result;
}

//第一引数で受け取った数を、第二引数で受け取った数の進数と見做して、第三引数の進数へ変換する。
string cnvBase(const string &str, ll from_base, ll to_base) {
	ll num = 0;
	//小文字があったら大文字に変換
	string num_str=cnvString(str,1);
	// 数値を10進数に変換
	for (char digit : num_str) {
		num = num * from_base + (isdigit(digit) ? digit - '0' : digit - 'A' + 10);
	}
	string result;
	// 数値を目的の基数に変換
	while (num > 0) {
		ll remainder = num % to_base;
		result.push_back(remainder < 10 ? remainder + '0' : remainder - 10 + 'A');
		num /= to_base;
	}
	// 結果を逆順にして返す
	reverse(result.begin(), result.end());
	return result.empty() ? "0" : result;
}

//底がaの対数xを計算。ただし小数点は繰り上げ。
ll logax(ll a, ll x){
	if(x<=1)return 0;
	ll result = 1;
	ll power = 1;
	while (power < (x+a-1) / a){
		power *= a;
		result++;
	}
	return result;
}

//第一引数を第二引数で割った余りを計算、割る数はint範囲
ll bigmd(const string &num, int md) {
	ll ans = 0;
	ll SIZ = 9; //9桁のチャンク
	ll base = 1000000000;//SIZ個の0
	rep(i,(num.size()-1)/SIZ+1){
		ll chunk = 0;
		ll l = i*SIZ;
		ll r = min((ll)num.size(),l+SIZ);
		if(r!=num.size()){
			ans = (ans*base+stoll(num.substr(l,r-l)))%md;
		}else{
			rep(i,r-l)ans*=10;
			ans=(ans+stoll(num.substr(l,r-l)))%md;
		}
	}
	return ans;
}

//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

//ax+by=cの整数解を得る ただし、cはgcd(a,b)の倍数でない場合、0,0になる
pair<ll,ll> ex_euclid(ll a,ll b,ll c){
	if(a<0||b<0||c<0){
		pair<ll,ll>ans=ex_euclid(abs(a),abs(b),abs(c));
		if(a<0)ans.first*=-1;
		if(b<0)ans.second*=-1;
		if(c<0)ans.first*=-1,ans.second*=-1;
		return ans;
	}
	if(c!=1){
		ll d=gcd(a,b);
		if(c%d!=0)return make_pair(0,0);
		pair<ll,ll>ans = ex_euclid(a/d,b/d,1);
		ans.first*=c/d;
		ans.second*=c/d;
		return ans;
	}
	if(a<b){
		pair<ll,ll>ans=ex_euclid(b,a,c);
		swap(ans.first,ans.second);
		return ans;
	}
	if(a==1&&b==0)return make_pair(1,0);
	else if(b==0) return make_pair(0,0);
	ll x,y;
	tie(x,y)=ex_euclid(b,a%b,c);
	pair<ll,ll> ans=make_pair(y,x-(a/b)*y);
	return ans;
}

//オイラーのトーシェント関数。N以下のNと互いに素な物の数を返す。
ll euler(ll n){
	unordered_map<ll,ll> factors;
	ll tmp=n;
	while (tmp % 2 == 0) {
		factors[2]++;
		tmp /= 2;
	}
	for (ll i=3; i*i<=tmp;i+=2) {
		while (tmp%i == 0) {
			factors[i]++;
			tmp/= i;
		}
	}
	if (tmp > 2)factors[tmp]++;
	ll ans=1;
	for(const auto & val:factors){
		ans*=power(val.first,val.second-1)*(val.first-1);
	}
	return ans;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false; 
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};

//重み付きUF
struct PotentialUnionFind {
	ll n;
	vl par, siz, pot;
	PotentialUnionFind(ll N) : par(N,-1) , siz(N,1) , pot(N,0){n=N;}
	// 根を求める
	ll root(ll x) {
		if (par[x] == -1) return x;
		ll tmp = root(par[x]);
		pot[x] += pot[par[x]];
		par[x] = tmp;
		return par[x];
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(ll x, ll y) {
		return root(x) == root(y);
	}
	//x よりいくつ大きい所に y があるか。根が一致しない場合は"0"
	ll potential(ll x,ll y){
		if(root(x) != root(y)) return 0;
		else return pot[y]-pot[x];
	}
	//x より w だけ大きい状態として y を併合。
	bool unite(ll x, ll y, ll w) {
		ll rx = root(x),ry = root(y);
		if (rx == ry) return false;
		w += pot[x]-pot[y];
		if (siz[rx] < siz[ry]) swap(rx, ry),w*=-1;
		par[ry] = rx;
		siz[rx] += siz[ry];
		siz[ry] = 0;
		pot[ry] = w;
		return true;
	}
	// x を含むグループのサイズ
	ll size(ll x) {
		return siz[root(x)];
	}
	//小さい順にUnionFindグラフを調整、O(n log n)
	void regulation(){
		vvl r(n);
		rep(i,n)r[root(i)].push_back(i);
		rep(i,n){
			if(r[i].size()==0)continue;
			ll mn = i;
			rep(j,r[i].size())if(pot[mn]>pot[r[i][j]])mn=r[i][j];
			siz[mn]=siz[i];
			siz[i]=0;
			ll tmp = pot[mn];
			rep(j,r[i].size()){
				pot[r[i][j]]-=tmp;
				par[r[i][j]] = mn;
			}
			par[mn]=-1;
		}
	}
	void debug(){
		rep(i,n)cout<<setw(4)<<left<<par[i]<<" ";
		cout<<endl;
		rep(i,n)cout<<setw(4)<<left<<pot[i]<<" ";
		cout<<endl;
	}
};

//分離可能UnionFind、経路圧縮をしない。
struct CuttingFind{
	vector<int> par, siz;
	CuttingFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	//根x と 根y のグループを併合する(お互い根ではない時、falseで何もしない)
	bool unite(int x, int y) {
		if (issame(x,y) || par[x] != -1 || par[y] != -1) {
			cout<<"error"<<endl;
			return false;
		}
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	//根の側から、その直系の子供を分離する。片方が根でもう片方が直系の子でなければならない。
	bool separate(int x,int y){
		if(par[y]==-1)swap(x,y);
		if(par[y]!=x||par[x]!=-1){
			cout<<"error2"<<endl;
			return false;
		}
		siz[x] -= siz[y];
		par[y]=-1;
		return true;
	}
	// x を含むグループのサイズを求める
	int size(int x) {
		return siz[root(x)];
	}
};
//セグ木,乗せる値の型が必要
template<typename T>
struct SegTree{
	ll size;
	ll tall;
	vector<T> data;
	function<T(T,T)> p;
	//セグ木に乗せる値の初期値をa配列にし、putの関数をセグ木に乗せる、dをデフォルト値に。
	SegTree(vector<T> a,function<T(T,T)> put,T d) : data(power(2,logax(2,a.size())+1)) {
		size = data.size()/2;
		tall=logax(2,size)+1;
		p=put;
		ll tmp=size;
		data = vector<T>(size*2,d);
		while(tmp!=0){
			if(tmp==size)rep(i,a.size())data[tmp+i]=a[i];
			else rep(i,tmp) data[tmp+i]=p(data[2*(tmp+i)],data[2*(tmp+i)+1]);
			tmp/=2;
		}
	}
	//更新、t番目の値をxにする。
	void update(ll t,T x){
		t+=size;
		while(t!=0){
			if(t>=size)data[t]=x;
			else data[t]=p(data[2*t],data[2*t+1]);
			t/=2;
		}
	}
	//取得、l~r区間内の評価値を取得する。
	T get(ll l,ll r){
		//lとrが範囲外なら範囲内に正す
		l=max(0LL,l);
		r=min(r,size-1);
		r++;
		T ans=data[0];
		ll pos=l+size;
		ll wid=1;
		//出来る限り上に上げきる。
		while(l+(wid*2)<=r){
			while(l%(wid*2)==0&&l+(wid*2)<=r)pos/=2,wid*=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		//上げ終わったので今度は下げる
		while(l!=r){
			while(l+wid>r)pos*=2,wid/=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		return ans;
	}
	//セグ木デバッグ用、丸ごと出力
	void print(){
		rep(i,size)cout<<setw(7)<<left<<i;
		cout<<endl;
		ll pos=size;
		rep(i,tall){
			rep(j,size){
				if(j%power(2,i)==0)cout<<setw(7)<<left<<data[pos],pos++;
				else cout<<"       ";
			}
			pos/=4;
			cout<<endl;
		}
	}
};

//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};


ll solve(){
	ll n,m;
	cin>>n>>m;
	if(n==0&&m==0){return 1;}

	vl s(n);
	rep(i,n)cin>>s[i];

	ll mn=s[0],mx=s[n-1];
	while(mn<mx){
		ll mid=(mn+mx+1)/2;
		ll cnt=1;
		ll lv=1;
		ll best=0;
		while(lv<=s[n-1]-mid){
			while(abs(lv-s[best])>abs(lv-s[best+1])&&lv+mid>s[best+1])best++;
			lv += max(1LL,mid-abs(lv-s[best]));
			cnt++;
		}
		if(cnt>=m)mn=mid;
		else mx=mid-1;
	}

	if(mn==s[0]){
		//s[0]で条件を満たすか判定
		ll mid=(mn+mx+1)/2;
		ll cnt=1;
		ll lv=1;
		ll best=0;
		while(lv<=s[n-1]-mid){
			while(abs(lv-s[best])>abs(lv-s[best+1])&&lv+mid>s[best+1])best++;
			lv += max(1LL,mid-abs(lv-s[best]));
			cnt++;
		}
		if(cnt<m){
			cout<<-1<<endl;
			return 0;
		}
	}
	
	cout<<mn<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 570
memory_kb: 4184
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
#define rep3(i, a, b, c) for (ll i = (a); i < (b); i += (c))
#define rep2(i, a, b) rep3(i, a, b, 1)
#define rep1(i, n) rep2(i, 0, n)
#define rep0(n) rep1(aaaaa, n)
#define ov4(a, b, c, d, name, ...) name
#define rep(...) ov4(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define per(i, a, b) for (ll i = (a) - 1; i >= (b); i--)
#define fore(e, v) for (auto&& e : v)
#define all(a) begin(a), end(a)
#define sz(a) (int)(size(a))
#define lb(v, x) (lower_bound(all(v), x) - begin(v))
#define eb emplace_back

template <typename T, typename S>
bool chmin(T& a, const S& b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T, typename S>
bool chmax(T& a, const S& b) {
  return a < b ? a = b, 1 : 0;
}
const int INF = 1e9 + 100;
const ll INFL = 3e18 + 100;
#define i128 __int128_t
struct _ {
  _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

int main(){
  int N,M;
  while(1){
    cin>>N>>M;
    if(N==0)break;
    vi S(N);
    fore(i,S)cin>>i;
    // X in [l,r)
    int l=S[0],r=S[N-1];
    // -1 
    {
      int cnt=1;
      int X=l, L=1;
      while(L+X<=S[N-1]){
        cnt++;
        auto idx=lb(S,L);
        int d=1;
        if(idx<N&&S[idx]<L+X)d=max(d,X-(S[idx]-L));
        if(idx>0)d=max(d,X-(L-S[idx-1]));
        L+=d;
      }
      if(cnt<M){
        cout<<"-1\n";
        continue;
      }
    }
    while(r-l>1){
      int X=(l+r)/2;
      int cnt=1,L=1;
      // cerr<<"X:"<<X<<' ';
      while(L+X<=S[N-1]){
        cnt++;
        auto idx=lb(S,L);
        int d=1;
        if(idx<N&&S[idx]<L+X)d=max(d,X-(S[idx]-L));
        if(idx>0)d=max(d,X-(L-S[idx-1]));
        L+=d;
        // cerr<<"L:"<<L<<' ';
      }
      // cerr<<endl;
      if(cnt<M)r=X;
      else l=X;
    }
    cout<<l<<'\n';
  }
}
accuracy: 1
time_ms: 340
memory_kb: 3972
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;

//* ATCODER
#include<atcoder/all>
using namespace atcoder;
typedef modint998244353 mint;
//*/

/* BOOST MULTIPRECISION
#include<boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
//*/

typedef long long ll;

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) begin(v),end(v)

template <typename T> bool chmin(T &a, const T &b) {
	if (a <= b) return false;
	a = b;
	return true;
}

template <typename T> bool chmax(T &a, const T &b) {
	if (a >= b) return false;
	a = b;
	return true;
}

template <typename T> T max(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
	return ret;
}

template <typename T> T min(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
	return ret;
}

template <typename T> T sum(vector<T> &a){
	T ret = 0;
	for (int i=0; i<(int)a.size(); i++) ret += a[i];
	return ret;
}

// importbisect
template <typename T>
int bisect_left(vector<T> &X, T v){
	return lower_bound(X.begin(), X.end(), v) - X.begin();
}

template <typename T>
int bisect_right(vector<T> &X, T v){
	return upper_bound(X.begin(), X.end(), v) - X.begin();
}
// ----

// defcomp
template <typename T>
vector<T> compress(vector<T> &X) {
	vector<T> vals = X;
	sort(vals.begin(), vals.end());
	vals.erase(unique(vals.begin(), vals.end()), vals.end());
	return vals;
}
// -----

//defmodfact
const int COMinitMAX = 1100000;
mint fact[COMinitMAX+1], factinv[COMinitMAX+1];

void modfact(){
	fact[0] = 1;
	for (int i=1; i<=COMinitMAX; i++){
		fact[i] = fact[i-1] * i;
	}
	factinv[COMinitMAX] = fact[COMinitMAX].inv();
	for (int i=COMinitMAX-1; i>=0; i--){
		factinv[i] = factinv[i+1] * (i+1);
	}
}

mint cmb(int a, int b){
	if (a<b || b<0) return mint(0);
	return fact[a]*factinv[b]*factinv[a-b];
}
//--------

// makediv
vector<ll> makediv(ll n){
	vector<ll> ld, ud;
	for (ll i=1; i*i<=n; i++){
		if (n%i == 0){
			ld.push_back(i);
			if (i != n/i){
				ud.push_back(n/i);
			}
		}
	}
	reverse(ud.begin(), ud.end());
	ld.insert(ld.end(), ud.begin(), ud.end());
	return ld;
}
// -----

// Fast Factorization
// https://judge.yosupo.jp/submission/38126
// !!! CHANGED THE PRIMARY TEST !!!
typedef unsigned int uint;

struct Mint {
	uint64_t n;
	static uint64_t mod, inv, r2;
	Mint() : n(0) { }
	Mint(const uint64_t &x) : n(init(x)) { }
	static uint64_t init(const uint64_t &w) { return reduce(__uint128_t(w) * r2); }
	static void set_mod(const uint64_t &m) {
		mod = inv = m;
		for(int i = 0; i < 5; i++)	inv *= 2 - inv * m;
		r2 = -__uint128_t(m) % m;
	}
	static uint64_t reduce(const __uint128_t &x) {
		uint64_t y = uint64_t(x >> 64) - uint64_t((__uint128_t(uint64_t(x) * inv) * mod) >> 64);
		return int64_t(y) < 0 ? y + mod : y;
	}
	Mint& operator+= (const Mint &x) { n += x.n - mod; if(int64_t(n) < 0) n += mod; return *this; }
	Mint& operator+ (const Mint &x) const { return Mint(*this) += x; }
	Mint& operator*= (const Mint &x) { n = reduce(__uint128_t(n) * x.n); return *this; }
	Mint& operator* (const Mint &x) const { return Mint(*this) *= x; }
	uint64_t val() const { return reduce(n); }
};

uint64_t Mint::mod, Mint::inv, Mint::r2;

bool suspect(const uint64_t &a, const uint64_t &s, uint64_t d, const uint64_t &n) {
	if(Mint::mod != n)	Mint::set_mod(n);
	Mint x(1), xx(a), o(x), m(n - 1);
	while(d > 0) {
		if(d & 1)	x *= xx;
		xx *= xx;
		d >>= 1;
	}
	if(x.n == o.n)	return true;
	for(uint r = 0; r < s; r++) {
		if(x.n == m.n)	return true;
		x *= x;
	}
	return false;
}

bool is_prime(const uint64_t &n) {
	if(n <= 1 || (n > 2 && (~n & 1)))	return false;
	uint64_t d = n - 1, s = 0;
	while(~d & 1)	s++, d >>= 1;
	static const uint64_t a_big[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
	static const uint64_t a_smo[] = {2, 7, 61};
	if(n < 4759123141LL) {
		for(auto &&p : a_smo) {
			if(p >= n)	break;
			if(!suspect(p, s, d, n))	return false;
		}
	} else {
		for(auto &&p : a_big) {
			if(p >= n)	break;
			if(!suspect(p, s, d, n))	return false;
		}
	}
	return true;
}

uint64_t rho_pollard(const uint64_t &n) {
	if(~n & 1)	return 2u;
	static random_device rng;
	uniform_int_distribution<uint64_t> rr(1, n - 1);
	if(Mint::mod != n)	Mint::set_mod(n);
	for(;;) {
		uint64_t c_ = rr(rng), g = 1, r = 1, m = 500;
		Mint y(rr(rng)), xx(0), c(c_), ys(0), q(1);
		while(g == 1) {
			xx.n = y.n;
			for(uint i = 1; i <= r; i++)	y *= y, y += c;
			uint64_t k = 0; g = 1;
			while(k < r && g == 1) {
				for(uint i = 1; i <= (m > (r - k) ? (r - k) : m); i++) {
					ys.n = y.n;
					y *= y; y += c;
					uint64_t xxx = xx.val(), yyy = y.val();
					q *= Mint(xxx > yyy ? xxx - yyy : yyy - xxx);
				}
				g = __gcd<uint64_t>(q.val(), n);
				k += m;
			}
			r *= 2;
		}
		if(g == n)	g = 1;
		while(g == 1) {
			ys *= ys; ys += c;
			uint64_t xxx = xx.val(), yyy = ys.val();
			g = __gcd<uint64_t>(xxx > yyy ? xxx - yyy : yyy - xxx, n);
		}
		if(g != n && is_prime(g))	return g;
	}
	assert(69 == 420);
}

template <typename T>
vector<T> inter_factor(const T &n) {
	if(n < 2)	return { };
	if(is_prime(n))	return {n};
	T d = rho_pollard(static_cast<uint64_t>(n));
	vector<T> l = inter_factor(d), r = inter_factor(n / d);
	l.insert(l.end(), r.begin(), r.end());
	return l;
}

template <typename T>
vector<T> factor(T n) {
	vector<T> f1;
	for(uint i = 2; i < 100; i += (i & 1) + 1)
		while(n % i == 0)	f1.push_back(i), n /= i;
	vector<T> f2 = inter_factor(n);
	f1.insert(f1.end(), f2.begin(), f2.end());
	sort(f1.begin(), f1.end());
	return f1;
}

void solve(int n,int m){

	vector<int>s(n);
	rep(i,0,n)cin>>s[i];
	auto check=[&](int x)->int {
		int cnt = 0;
		int lv = 1;
		int piv = 0;
		while(lv+x <= s[n-1]){
			while(
				piv+1 < n
				&& x+lv > s[piv+1]
				&& x-abs(lv-s[piv]) < x-abs(lv-s[piv+1])
			){
				piv++;
			}

			if (x+lv <= s[piv]) return (int)1e9;
			int upper = max(1,x-abs(lv-s[piv]));
			lv += upper;
			cnt++;
			if(upper==0) return (int)1e9;
		}
		cnt++;
		return cnt;
	};

	int ub=2e6;
	int lb=1;
	while(ub-lb>1){
		int t = (ub+lb) / 2;
		if (check(t) >= m) lb=t;
		else ub=t;
	}
	if(check(lb) == (int)1e9)cout<<-1<<'\n';
	else{
		if(check(lb) < m) cout<<-1<<'\n';
		else cout<<lb<<'\n';
	}
	
}


int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	while(true){
		int n,m;
		cin>>n>>m;
		if(n==0)break;
		solve(n,m);
	}
	
}
accuracy: 1
time_ms: 300
memory_kb: 12560
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long

int solve(){
  ll n,m;cin>>n>>m;
  if(n==0&&m==0)return 0;
  vector<ll> s(n);
  for(int i=0;i<n;i++)cin>>s[i];
  ll u=1e10+9,d=s[0],x,level,ene=0,sentou;
  bool gameover=false;
  while(u-d>1){
    level=1;
    sentou=0;
    x=(u+d)/2;
    gameover=false;
    while(true){
      //最後の敵を倒せるか
      if(x+level>s.at(n-1)){
        sentou+=1;
        break;
      }

      ene=lower_bound(s.begin(),s.end(),level)-s.begin();

      if(ene==0){
        if(level+x<=s[0]){
          gameover=true;
          break;
        }
        level+=max(1LL,x-abs(level-s[ene]));
      }
      else{
        if(level+x<=s[ene])level+=max(1LL,x-abs(level-s[ene-1]));
        else level+=max(1LL,max(x-abs(level-s[ene]),x-abs(level-s[ene-1])));
      }
      sentou+=1;
    }
    if(sentou>=m||gameover)d=x;
    else u=x;
  }
  if(d==0){
    cout<<-1<<endl;
    return 1;
  }
  
  level=1;
  sentou=0;
  x=d;
  gameover=false;
  while(true){
    //最後の敵を倒せるか
    if(x+level>s.at(n-1)){
      sentou+=1;
      break;
    }
    ene=lower_bound(s.begin(),s.end(),level)-s.begin();
    if(ene==0){
      if(level+x<=s[0]){
        gameover=true;
        break;
      }
      level+=max(1LL,x-abs(level-s[ene]));
    }
    else{
      if(level+x<=s[ene])level+=max(1LL,x-abs(level-s[ene-1]));
      else level+=max(1LL,max(x-abs(level-s[ene]),x-abs(level-s[ene-1])));
    }
    sentou+=1;
  }
  if(sentou>=m||gameover)cout<<d<<endl;
  else cout<<-1<<endl;

  return 1;
  cout<<endl;
}

int main(){
	while(solve()){};
}
accuracy: 1
time_ms: 2060
memory_kb: 4048
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll =long long;

ll calc(ll X,vector<ll> &S){
	ll L=1;
	ll cnt=0;
	ll N=S.size();
	if(L+X<=S[0])return 1e18;
	while(L+X<=S[N-1]){
		cnt++;
		ll LU=1;
		auto d=lower_bound(S.begin(),S.end(),L);
		if((*d)<L+X)LU=max(LU,X-abs(L-(*d)));
		if(d!=S.begin())d--;
		LU=max(LU,X-abs(L-(*d)));
		// cout<<L<<" "<<X<<" "<<LU<<endl;
		L+=LU;
	}
	return cnt+1;
}

void solve(ll N,ll M){
	vector<ll> S(N);
	for(int i=0;i<N;i++)cin>>S[i];
	if(calc(1,S)<M){
		cout<<-1<<"\n";
		return;
	}
	ll L=0,R=S.back();
	while(R-L>1){
		ll mid=(R+L)/2;
		if(calc(mid,S)>=M)L=mid;
		else R=mid;
	}
	if(calc(L,S)>1e10||calc(L,S)<M){
		cout<<-1<<endl;

	}
	else 
	cout<<L<<endl;
	// cout<<"mada"<<endl;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	ll N,M;
	while(cin>>N>>M,N+M!=0)solve(N,M);
}
accuracy: 1
time_ms: 1210
memory_kb: 4324
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

#define rep(i, n) for(ll i = 0; i < (n); ++i)
#define all(A) A.begin(), A.end()

bool chmin(auto &a, auto b) {return a > b ? a = b, 1 : 0;}
bool chmax(auto &a, auto b) {return a < b ? a = b, 1 : 0;}

template<class T>
void print(vector<T> a) {
  cout << "[";
  for(auto x : a) {
    cout << x << ", ";
  }
  cout << "]" << endl;
}

bool isOK(ll X, vector<ll> &S, ll M) {
  ll N = S.size();
  ll boss = S.back();
  
  ll L = 1;
  rep(i, M) {
    if(i < M-1 && boss < L + X) return false;
    auto itr = lower_bound(all(S), L);
    ll d = 1e18;
    if(*itr < L + X) {
      chmin(d, abs((*itr) - L));
    }
    if(itr != S.begin()) {
      itr--;
      chmin(d, abs((*itr) - L));
    }
    L += max(X - d, 1LL);
  }
  
  return true;
}

int main() {
  
  while(1) {
    ll N, M; cin >> N >> M;
    if(N + M == 0) break;
    vector<ll> S(N);
    for(auto &s : S) cin >> s;
    
    ll ok = S[0];
    ll ng = 1e9;
    
    if(!isOK(ok, S, M)) {
      cout << -1 << '\n';
      continue;
    }
    
    while(abs(ok - ng) > 1) {
      ll mid = (ok + ng) / 2;
      if(isOK(mid, S, M)) ok = mid;
      else ng = mid;
    }
    cout << ok << '\n';
  }
  
  return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 4240
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

#include <atcoder/all>
using namespace atcoder;

using ll = long long;
using mint = modint998244353;

bool solve() {
    int N, M;
    cin >> N >> M;
    if(N == 0 && M == 0) return false;
    vector<int> S(N);
    for(int i = 0; i < N; i++) {
        cin >> S[i];
    }
    auto f = [&](int X) -> bool {
        int L = 1, C = 0;
        while(C < M && S[N - 1] >= L + X) {
            auto it = lower_bound(S.begin(), S.end(), L);
            int x = *it;
            int y = (it != S.begin() ? *prev(it) : *it);
            int d = max(1, max(X - abs(L - x), X - abs(L - y)));
            L += d, C += 1;
        }
        return (C + 1 >= M);
    };
    if(!f(S[0])) {
        cout << -1 << endl;
        return true;
    }
    int ok = S[0], ng = 2e6;
    while(ok + 1 < ng) {
        int X = (ok + ng) / 2;
        (f(X) ? ok : ng) = X;
    }
    cout << ok << endl;
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 400
memory_kb: 3948
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define COMPRO

#ifdef COMPRO
namespace m9::compro {
	template <class T> bool chmin(T& a, const T& b) { return a > b ? (a = b, true) : false; }
	template <class T> bool chmax(T& a, const T& b) { return a < b ? (a = b, true) : false; }
	long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
	long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
} // namespace m9::compro

#endif
#ifdef COMPRO
namespace m9::compro {
	using ll = long long;
	using ull = unsigned long long;
	using usize = size_t;
	using pii = std::pair<int, int>;
	using pll = std::pair<ll, ll>;
} // namespace m9::compro

namespace m9::compro {
	template <class T> using V = std::vector<T>;
	using vc = V<char>;
	using vb = V<int8_t>;
	using vi = V<int>;
	using vll = V<ll>;
	using vd = V<double>;
	using vs = V<std::string>;
	using vpii = V<pii>;
	using vpll = V<pll>;
	using vvc = V<vc>;
	using vvb = V<vb>;
	using vvi = V<vi>;
	using vvll = V<vll>;
	using vvd = V<vd>;
} // namespace m9::compro

#endif
#ifdef COMPRO
namespace m9::compro {
	template <int m, std::enable_if_t<(1 <= m)>* = nullptr> struct static_modint {
		using mint = static_modint;
		static constexpr int mod() { return m; }
		static mint raw(int v) { mint x; x._v = v; return x; }
		static_modint() : _v(0) {}
		template <class T, std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>>* = nullptr> static_modint(T v) {
			long long x = (long long)(v % (long long)(umod()));
			if (x < 0) x += umod();
			_v = (unsigned int)(x);
		}
		template <class T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>* = nullptr> static_modint(T v) {
			_v = (unsigned int)(v % umod());
		}
		unsigned int val() const { return _v; }
		mint& operator++() { _v++; if (_v == umod()) _v = 0; return *this; }
		mint& operator--() { if (_v == 0) _v = umod(); _v--; return *this; }
		mint operator++(int) { mint res = *this; ++*this; return res; }
		mint operator--(int) { mint res = *this; --*this; return res; }
		mint& operator+=(const mint& rhs) { _v += rhs._v; if (_v >= umod()) _v -= umod(); return *this; }
		mint& operator-=(const mint& rhs) { _v -= rhs._v; if (_v >= umod()) _v += umod(); return *this; }
		mint& operator*=(const mint& rhs) { unsigned long long z = _v; z *= rhs._v; _v = (unsigned int)(z % umod()); return *this; }
		mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
		mint operator-() const { return mint() - *this; }
		mint pow(long long n) const {
			assert(0 <= n);
			mint x = *this, r = 1;
			while (n) {
				if (n & 1) r *= x;
				x *= x;
				n >>= 1;
			}
			return r;
		}
		mint inv() const { assert(_v); return pow(umod() - 2); }
		mint operator+(const mint& rhs) { return mint(*this) += rhs; }
		mint operator-(const mint& rhs) { return mint(*this) -= rhs; }
		mint operator*(const mint& rhs) { return mint(*this) *= rhs; }
		mint operator/(const mint& rhs) { return mint(*this) /= rhs; }
		mint operator==(const mint& rhs) { return this->_v == rhs._v; }
		mint operator!=(const mint& rhs) { return this->_v != rhs._v; }
		private:
		unsigned int _v;
		static constexpr unsigned int umod() { return m; }
	};

	using modint1000000007 = static_modint<1000000007>;
	using modint998244353 = static_modint<998244353>;
} // namespace m9::compro

#endif
#ifdef COMPRO
#include <unistd.h>

#define FASTIO
// #define OUTPUT_ONLY

namespace m9::compro::io {
	// standard i/o
	struct StandardIn {
		long long rd_ll() { long long tmp; std::cin >> tmp; return tmp; }
		int rd_int() { int tmp; std::cin >> tmp; return tmp; }
		double rd_dbl() { double tmp; std::cin >> tmp; return tmp; }
		char rd_chr() { char tmp; std::cin >> tmp; return tmp; }
		std::string rd_str() { std::string tmp; std::cin >> tmp; return tmp; }
	};
	struct StandardOut {
		void wt_ll(long long x) { std::cout << x; }
		void wt_ull(unsigned long long x) { std::cout << x; }
		void wt_dbl(double x) { std::cout << x; }
		void wt_chr(char x) { std::cout << x; }
		void wt_str(std::string x) { std::cout << x; }
	};
	// fast i/o
	struct FastIn {
		std::array<char, 1 << 20> buf;
		int width, pos;
		#ifdef OUTPUT_ONLY
		FastIn() noexcept {}
		#else
		FastIn() noexcept { start_reading(); }
		#endif
		long long rd_ll() {
			long long ret = 0, sgn = 1;
			char ch = current_char();
			while (ch == ' ' or ch == '\n') ch = next_char();
			if (ch == '-') { sgn *= -1; ch = next_char(); }
			for (; '0' <= ch and ch <= '9'; ch = next_char()) ret = (ret * 10) + ch - '0';
			return ret * sgn;
		}
		double rd_dbl() {
			double ret = 0, sgn = 1;
			char ch = current_char();
			while (ch == ' ' or ch == '\n') ch = next_char();
			if (ch == '-') { sgn *= -1; ch = next_char(); }
			bool found_dot = false;
			double mul = 1;
			for (; ('0' <= ch and ch <= '9') or ch == '.'; ch = next_char()) {
				if (ch == '.') { found_dot = true; continue; }
				if (found_dot) ret = ret + (ch - '0') / (mul *= 10); else ret = (ret * 10) + ch - '0';
			}
			return ret * sgn;
		}
		int rd_int() {
			int ret = 0, sgn = 1;
			char ch = current_char();
			while (ch == ' ' or ch == '\n') ch = next_char();
			if (ch == '-') { sgn *= -1; ch = next_char(); }
			for (; '0' <= ch and ch <= '9'; ch = next_char()) ret = (ret * 10) + ch - '0';
			return ret * sgn;
		}
		std::string rd_str() {
			std::string res;
			char ch = current_char();
			while (ch == ' ' or ch == '\n') ch = next_char();
			for (; ch != -1 and ch != '\n' and ch != ' '; ch = next_char()) res += ch;
			return res;
		}
		char rd_chr() {
			char ch = current_char();
			while (ch == ' ' or ch == '\n') ch = next_char();
			next_char();
			return ch;
		}
		private:
		void start_reading() {
			auto r = read(0, &buf[0], buf.size());
			assert(r >= 0);
			width = r, pos = 0;
		}
		char next_char() { if (++pos == width) start_reading(); return current_char(); }
		char current_char() { return (pos == width ? -1 : buf[pos]); }
	};
	template <int float_format> struct FastOut {
		void wt_ll(long long x) noexcept {
			std::array<char, 1 << 5> buf;
			int idx = 0;
			if (x < 0) { x *= -1; putchar_unlocked('-'); }
			if (x == 0) putchar_unlocked('0');
			while (x > 0) { buf[idx++] = x % 10 + '0'; x /= 10; }
			while (idx--) putchar_unlocked(buf[idx]);
		}
		void wt_ull(unsigned long long x) noexcept {
			std::array<char, 1 << 5> buf;
			int idx = 0;
			if (x == 0) putchar_unlocked('0');
			while (x > 0) { buf[idx++] = x % 10 + '0'; x /= 10; }
			while (idx--) putchar_unlocked(buf[idx]);
		}
		void wt_chr(char x) noexcept { putchar_unlocked(x); }
		void wt_str(std::string x) noexcept {
			auto len = x.length();
			for (size_t i = 0; i < len; i++) putchar_unlocked(x[i]);
		}
		void wt_dbl(double x) noexcept {
			int k, r = 0;
			double v = 1;
			if (x < 0) { x *= -1; putchar_unlocked('-'); }
			x += 0.5 * pow(0.1, float_format);
			while (x >= 10 * v) { v *= 10; r++; }
			while (r-- >= 0) {
				k = floor(x / v);
				if (k >= 10) k = 9;
				if (k <= -1) k = 0;
				x -= k * v;
				v *= 0.1;
				putchar_unlocked(k + '0');
			}
			if (float_format > 0) {
				putchar_unlocked('.');
				v = 1;
				for (int _ = 0; _ < float_format; _++) {
					v *= 0.1;
					k = floor(x / v);
					if (k >= 10) k = 9;
					if (k <= -1) k = 0;
					x -= k * v;
					putchar_unlocked(k + '0');
				}
			}
		}
	};
} // namespace m9::compro::io

namespace m9::compro::io {
	template <class, class = std::void_t<>> struct has_all_rd_functions : std::false_type {};
	template <class T> struct has_all_rd_functions<T, std::void_t<
	decltype(std::declval<T>().rd_ll()),
	decltype(std::declval<T>().rd_int()),
	decltype(std::declval<T>().rd_dbl()),
	decltype(std::declval<T>().rd_chr()),
	decltype(std::declval<T>().rd_str())>> : std::true_type {};
	template <class, class = std::void_t<>> struct has_all_wt_functions : std::false_type {};
	template <class T> struct has_all_wt_functions<T, std::void_t<
	decltype(std::declval<T>().wt_ll(std::declval<long long>())),
	decltype(std::declval<T>().wt_ull(std::declval<unsigned long long>())),
	decltype(std::declval<T>().wt_dbl(std::declval<double>())),
	decltype(std::declval<T>().wt_chr(std::declval<char>())),
	decltype(std::declval<T>().wt_str(std::declval<std::string>()))>> : std::true_type {};
	template <class Input, class Output> struct IOPair {
		static_assert(has_all_rd_functions<Input>::value); static_assert(has_all_wt_functions<Output>::value);
		Input is; Output os;
		long long rd_ll() { return is.rd_ll(); }
		int rd_int() { return is.rd_int(); }
		double rd_dbl() { return is.rd_dbl(); }
		char rd_chr() { return is.rd_chr(); }
		std::string rd_str() { return is.rd_str(); }
		void wt_ll(const long long& x) { os.wt_ll(x); }
		void wt_ull(const unsigned long long& x) { os.wt_ull(x); }
		void wt_dbl(const double& x) { os.wt_dbl(x); }
		void wt_chr(const char& x) { os.wt_chr(x); }
		void wt_str(const std::string& x) { os.wt_str(x); }
	};

	IOPair<FastIn, FastOut<15>> io;
	// IOPair<StandardIn, StandardOut> io;
} // namespace m9::compro::io

namespace m9::compro::io {
	// scan
	void scan(int& x) { x = io.rd_int(); }
	void scan(long& x) { x = (long)(sizeof(long) == 32 ? io.rd_int() : io.rd_ll()); }
	void scan(long long& x) { x = io.rd_ll(); }
	void scan(unsigned int& x) { int tmp = io.rd_int(); assert(tmp >= 0); x = tmp; }
	void scan(unsigned long& x) { long tmp; scan(tmp); assert(tmp >= 0l); x = tmp; }
	void scan(unsigned long long& x) { long long tmp = io.rd_ll(); assert(tmp >= 0ll); x = tmp; }
	void scan(double& x) { x = io.rd_dbl(); }
	void scan(long double& x) { x = (long double)(io.rd_dbl()); }
	void scan(char& x) { x = io.rd_chr(); }
	void scan(std::string& x) { x = io.rd_str(); }
	template <class T1, class T2> void scan(std::pair<T1, T2>& x) { scan(x.first); scan(x.second); }
	template <class T> void scan(std::vector<T>& x) { for (auto& e : x) scan(e); }
	void scan() {}
	template <class Car, class... Cdr> void scan(Car&& car, Cdr&&... cdr) { scan(car); scan(std::forward<Cdr>(cdr)...); }
	// wt
	void wt(const bool& x) { io.wt_ull(x ? 1 : 0); }
	void wt(const int& x) { io.wt_ll((long long)(x)); }
	void wt(const long& x) { io.wt_ll((long long)(x)); }
	void wt(const long long& x) { io.wt_ll(x); }
	void wt(const unsigned int& x) { io.wt_ull((unsigned long long)(x)); }
	void wt(const unsigned long& x) { io.wt_ull((unsigned long long)(x)); }
	void wt(const unsigned long long& x) { io.wt_ull(x); }
	void wt(const double& x) { io.wt_dbl(x); }
	void wt(const long double& x) { io.wt_dbl((double)(x)); }
	void wt(const char& x) { io.wt_chr(x); }
	void wt(const char x[]) { int idx = 0; while (x[idx] != '\0') io.wt_chr(x[idx++]); }
	void wt(const std::string& x) { io.wt_str(x); }
	template <class T1, class T2> void wt(const std::pair<T1, T2>& x) { wt(x.first); wt(' '); wt(x.second); }
	template <class T> void wt(const std::vector<T>& x) {
		auto len = (int)x.size();
		for (int i = 0; i < len - 1; i++) { wt(x[i]); wt(' '); }
		if (not x.empty()) wt(x.back());
	}
	template <class T> void wt(const std::set<T>& x) {
		for (auto it = begin(x); it != end(x); ) {
			wt(*it);
			it++;
			if (it != end(x)) wt(' ');
		}
	}
	template <class Car, class... Cdr> void wt(const Car& car, const Cdr&... cdr) { wt(car); wt(cdr...); }
	// print
	int print() { wt('\n'); return 0; }
	template <class T> int print(const T& x) { wt(x); wt('\n'); return 0; }
	template <class T> int print(const std::vector<std::vector<T>>& x) { for (const auto& v : x) print(v); return 0; }
	template <class Car, class... Cdr> int print(const Car& car, const Cdr&... cdr) { wt(car); wt(' '); print(cdr...); return 0; }
	// drop, yn
	template <class... T> void drop(const T&... x) { print(x...); exit(0); }
	void yn(bool f = true) { print(f ? "Yes" : "No"); }
	void dyn(bool f = true) { drop(f ? "Yes" : "No"); }
} // namespace m9::compro::io
namespace m9::compro { using namespace m9::compro::io; } // namespace m9::compro

// macro
#define INT(...)  int __VA_ARGS__; scan(__VA_ARGS__)
#define LL(...)  long long __VA_ARGS__; scan(__VA_ARGS__)
#define ULL(...)  unsigned long long __VA_ARGS__; scan(__VA_ARGS__)
#define DBL(...)  double __VA_ARGS__; scan(__VA_ARGS__)
#define STR(...)  std::string __VA_ARGS__; scan(__VA_ARGS__)
#define CHR(...)  char __VA_ARGS__; scan(__VA_ARGS__)
#define VEC(a, type, n) std::vector<type> (a)(n); scan(a)
#define VVEC(a, type, h, w) std::vector<std::vector<type>> (a)(h, std::vector<type>(w)); scan(a)
#define VI(a, n) VEC(a, int, n)
#define VVI(a, h, w) VVEC(a, int, h, w)
#define VLL(a, n) VEC(a, long long, n)
#define VVLL(a, h, w) VVEC(a, long long, h, w)
#define VC(a, n) VEC(a, char, n)
#define VVC(a, h, w) VVEC(a, char, h, w)
#define VPII(a, n) VEC(a, pii, n)
#define VPLL(a, n) VEC(a, pll, n)
#define VD(a, n) VEC(a, double, n)
#define VS(a, n) VEC(a, std::string, n)

#define PVIVI(a, b, n) std::vector<int> (a)(n); std::vector<int> (b)(n); for (size_t i = 0; i < n; i++) scan(a[i], b[i]);
#define PVLVL(a, b, n) std::vector<long long> (a)(n); std::vector<long long> (b)(n); for (size_t i = 0; i < n; i++) scan(a[i], b[i]);

#endif
#ifdef COMPRO
#ifdef ONLINE_JUDGE
#	define dbg(...) void(0)
#else
#	define dbg(...) debug_impl(#__VA_ARGS__, __VA_ARGS__)
#endif
namespace m9::compro {
	template <class Car, class... Cdr> void debug_impl(const char* s, Car&& car, Cdr&&... cdr) {
		constexpr const char* open_bracket = (sizeof...(cdr) == 0 ? "" : "(");
		constexpr const char* close_bracket = (sizeof...(cdr) == 0 ? "" : ")");
		#ifdef FASTIO
		wt(open_bracket, s, close_bracket, " : ", open_bracket, std::forward<Car>(car));
		(wt(", ", std::forward<Cdr>(cdr)), ...);
		wt(close_bracket, '\n');
		#else
		std::cerr << open_bracket << s << close_bracket << " : " << open_bracket << std::forward<Car>(car);
		((std::cerr << ", " << std::forward<Cdr>(cdr)), ...);
		std::cerr << close_bracket << "\n";
		#endif
	}
} // namespace m9::compro

#endif
#ifdef COMPRO
namespace m9::compro {
	constexpr long long big_mod = (1ll << 61) - 1;
	constexpr long long mod_1000000007 = 1000000007;
	constexpr long long mod_998244353 = 998244353;
	constexpr int iinf = std::numeric_limits<int>::max() / 2;
	constexpr long long linf = std::numeric_limits<long long>::max() / 2;
	constexpr double eps = 1e-8;
	constexpr double pi = 3.141592653589793238462643383279;
} // namespace m9::compro

#endif
#ifdef COMPRO
#pragma GCC optimize("O3")
#define _OVERLOAD(_1, _2, _3, name, ...) name
#define _REP0(q) for ([[maybe_unused]] long long _ = 0; _ < (q); _++)
#define _REP1(i, n) for (long long i = 0; i < (n); i++)
#define _REP2(i, a, b) for (long long i = (a); i < (b); i++)
#define REP(...) _OVERLOAD(__VA_ARGS__, _REP2, _REP1, _REP0)(__VA_ARGS__)
#define FOR(e, v) for (auto&& e : v)
#define CFOR(e, v) for (const auto& e : v)
#define M_P make_pair
#define M_T make_tuple
#define CAUTO const auto&
#define ALL(x) std::begin(x), std::end(x)
#define SORT(x) sort(ALL(x))
#define RSORT(x) ({ sort(ALL(x)); reverse(ALL(x)); })
#define UNIQUE(x) x.erase(unique(ALL(x)), end(x))
#define L_B(v, e) distance(begin(v), lower_bound(ALL(v), (e)))
#define U_B(v, e) distance(begin(v), upper_bound(ALL(v), (e)))

#endif

using namespace m9::compro;
using namespace std;

constexpr int MAX = 1000010;

int check(vector<ll> &s, int x) {
	int l = 1, ans = 0;
	// std::cerr << "[" << x << "]\n";
	while (true) {
		ans++;
		auto iter = std::ranges::lower_bound(s, x + l);
		// std::cerr << l << " " << iter - s.begin() << "\n";

		if (iter >= s.end()) {
			break;
		}
		if (iter == s.begin()) {
			return MAX;
		}

		iter = std::ranges::lower_bound(s, l);
		if (iter != s.begin() && *iter - l > l - *std::prev(iter)) --iter;

		l += std::max(1, static_cast<int>(x - std::abs(l - *iter)));
	}
	return ans;
}

int main() {
	while (true) {
		LL(n, m);
		if (n == 0) return 0;
		VLL(s, n);

		int ng = -1, ok = 1000001;
		while (std::abs(ng - ok) > 1) {
			int mid = (ng + ok) / 2;
			if (check(s, mid) < m) ok = mid;
			else ng = mid;
		}

		if (check(s, ng) == MAX) cout << -1 << std::endl;
		else cout << ng << std::endl;
		// std::cerr << ng << "/" << ok << "/" << check(s, ng) << std::endl;
	}
}
accuracy: 1
time_ms: 2810
memory_kb: 5320
final_rank: 20

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <ranges>
#include <regex>
#include <set>
#include <span>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// #include <atcoder/dsu>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(a) a.begin(), a.end()
using namespace std;

template <class T> inline bool chmin(T &a, T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> inline bool chmax(T &a, T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template <class T1, class T2>
std::ostream &operator<<(std::ostream &out, const pair<T1, T2> &A) {
	cout << "{" << A.first << "," << A.second << "}";
	return out;
}

template <class T1, class T2>
std::ostream &operator<<(std::ostream &out, const map<T1, T2> &M) {
	for (const auto &A : M) {
		cout << "{" << A.first << "," << A.second << "}";
	}
	return out;
}

template <class T1>
std::ostream &operator<<(std::ostream &out, const set<T1> &M) {
	cout << "{";
	for (const auto &A : M) {
		cout << A << ", ";
	}
	cout << "}" << endl;
	return out;
}

template <class T1>
std::ostream &operator<<(std::ostream &out, const multiset<T1> &M) {
	cout << "{";
	for (const auto &A : M) {
		cout << A << ", ";
	}
	cout << "}" << endl;
	return out;
}

template <class T>
std::ostream &operator<<(std::ostream &out, const vector<T> &A) {
	for (const T &a : A) {
		cout << a << " ";
	}
	return out;
}

void print() { cout << endl; }

template <typename Head, typename... Tail> void print(Head H, Tail... T) {
	cout << H << " ";
	print(T...);
}

template <class T> std::istream &operator>>(std::istream &in, vector<T> &A) {
	for (T &a : A) {
		std::cin >> a;
	}
	return in;
}

using ll = long long;
// using mint = modint1000000007;
// using PII = pair<int, int>;
// using PLL = pair<ll, ll>;
// using Graph = vector<vector<int>>;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr ll LINF = numeric_limits<ll>::max() / 2;

// ランレングス圧縮
// イテレータを受け取る
// verify: https://atcoder.jp/contests/abc380/submissions/60002447
template <typename T, typename Iterator>
vector<pair<T, int>> RLE(Iterator begin, Iterator end) {
	vector<pair<T, int>> res;
	for (auto itr = begin; itr != end; ++itr) {
		if (res.empty() || res.back().first != *itr) {
			res.emplace_back(*itr, 1);
		} else {
			res.back().second++;
		}
	}
	return res;
}

// 座標圧縮
// unordered_mapが使えない場合はmapに変更しよう
// https://atcoder.jp/contests/abc213/submissions/60002695
template <typename T> unordered_map<T, int> compress(vector<T> &X) {
	auto tmp = X;
	ranges::sort(tmp);
	tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
	unordered_map<T, int> res;
	for (int i = 0; i < (int)tmp.size(); i++) {
		res[tmp[i]] = i;
	}
	return res;
}
bool solve() {
	// ここからスタート
	int N, M;
	cin >> N >> M;
	if (N == 0)
		return false;
	vector<ll> s(N);

	rep(i, N) cin >> s[i];
	auto calcup = [&](ll l, ll x, ll s) {
		return l + max(1LL, x - abs(l - s));
	};

	auto fx = [&]() {
		for (int x = 1; x <= 1000000; x++) {
			vector<int> levels = {1};
			rep(i, M - 1) {
				if (levels.back() + x > s.back()) {
					return -1;
				}
				vector<int> tmp;
				for (auto &l : levels) {
					for (auto &a : s) {
						tmp.push_back(calcup(l, x, a));
					}
				}
				sort(all(tmp));
				tmp.erase(unique(all(tmp)), tmp.end());
				swap(tmp, levels);
				cout << x << " " << i << " " << levels << endl;
			}
			if (levels.back() + x > s.back()) {
				return x;
			}
		}
		return -1;
	};

	auto check = [&](ll x) {
		// X=xのときM回以上かかるか？
		ll level = 1;
		int cnt = 0;
		while (level + x <= s.back()) {
			ll next = 0;
			// levelに近い数を探す
			int idx = lower_bound(all(s), level) - s.begin();
			if (idx < N && s[idx] < level + x)
				chmax(next, calcup(level, x, s[idx]));
			if (idx > 0 && s[idx - 1] < level + x)
				chmax(next, calcup(level, x, s[idx - 1]));
			if (next == 0) {
				// return true;
				return 2;
			}
			cnt++;
			level = next;
		}
		cnt++;
		return (cnt >= M ? 1 : 0);
	};

	if (not check(1)) {
		cout << -1 << endl;
		return true;
	}

	ll ok = 0;
	ll ng = 1e9;
	while (ng - ok > 1) {
		ll mid = (ok + ng) / 2;
		if (check(mid)) {
			ok = mid;
		} else {
			ng = mid;
		}
	}
	if (check(ok) == 1) {
		cout << ok << endl;
	} else {
		cout << -1 << endl;
	}
	return true;
}

int main(void) {
	std::cin.tie(0)->sync_with_stdio(0);
	while (solve())
		;
}
accuracy: 1
time_ms: 1370
memory_kb: 4256
final_rank: 14

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <algorithm>
//#include <atcoder/all>
#include <bitset>
#include <cassert>
#include <cmath>
#include <deque>
#include <exception>
#include <fstream>
#include <iostream>
#include <map>
#include <mutex>
#include <queue>
#include <ratio>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
// using mint = modint1000000007;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define drep(i, n) for (int i = n - 1; i >= 0; i--)
#define srep(i, j, n) for (int i = j; i < n; i++)
#define sqrep(i, n) for (ll i = 1; i * i <= n; i++)
#define INF (int)(1e9 + 1e8)
#define LINF (ll)(1e18 + 1e17)
#define all(a) a.begin(), a.end()
#define eb emplace_back
#define mkp make_pair
#define mkt make_tuple
using ull = unsigned long long;
using vi = vector<int>;
using vd = vector<double>;
using vl = vector<ll>;
using vi2 = vector<vi>;
using vd2 = vector<vd>;
using vl2 = vector<vl>;
using vi3 = vector<vi2>;
using vl3 = vector<vl2>;
using vs = vector<string>;
using pi = pair<int, int>;
using tp = pair<int, pi>;
// using vm = vector<mint>;
// using vm2 = vector<vm>;
// using vm3 = vector<vm2>;

template <class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> inline void show_vector(vector<T>& a) {
    for (int i = 0; i < a.size(); i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

template <class T> inline void show_vector2(vector<vector<T>>& a) {
    for (int i = 0; i < a.size(); i++) {
        show_vector(a[i]);
    }
    cout << endl;
}

template <class T, class U> inline void show_map(map<T, U>& a) {
    for (pair<T, U> p : a) {
        cout << p.first << ": " << p.second << endl;
    }
}
template <class T, class U> inline void cerr_map(map<T, U>& a) {
    for (pair<T, U> p : a) {
        cerr << p.first << ": " << p.second << endl;
    }
}
template <class T, class U> inline void show_pair(pair<T, U>& a) {
    cout << a.first << " " << a.second << endl;
}
template <class T, class U> inline void cerr_pair(pair<T, U>& a) {
    cerr << a.first << " " << a.second << endl;
}
template <class T> inline void show_set(set<T>& a) {
    for (T i : a) {
        cout << i << " ";
    }
    cout << endl;
}
template <class T> inline void cerr_set(set<T>& a) {
    for (T i : a) {
        cerr << i << " ";
    }
    cerr << endl;
}

inline void yn(bool a) {
    if (a)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

ll ncr[100][100];

void calc_ncr() {
    ncr[0][0] = 1;
    for (int i = 0; i < 40 - 1; i++) {
        for (int j = 0; j <= i; j++) {
            ncr[i + 1][j] += ncr[i][j];
            ncr[i + 1][j + 1] += ncr[i][j];
        }
    }
}

// struct S {
//     mint a;
// };
// struct F {
//     int b;
// };
//  using S = int;
// S op(S a, S b) { return {a.a + b.a}; }
// S eee() { return {0}; }
// S mapping(F f, S x) { return {x.a + f.b}; }
// F composition(F f, F g) { return {f.b + g.b}; }
// F id() { return {0}; }
// using SEG = segtree<S, op, eee>;
//  using LAZY_SEG = lazy_segtree<S, op, eee, F, mapping, composition, id>;
void show_seg(int n) // SEG s, int n)
{
    rep(i, n) {
        // cout << s.get(i) << " ";
    }
    cout << endl;
}
struct UnionFind {
    vector<int> par;  // 親ノード
    vector<int> rank; // ランク

    UnionFind(int n = 1) { init(n); }

    void init(int n = 1) {
        par.resize(n);
        rank.resize(n);
        for (int i = 0; i < n; ++i)
            par[i] = i, rank[i] = 0;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        } else {
            int r = root(par[x]);
            return par[x] = r;
        }
    }

    bool issame(int x, int y) { return root(x) == root(y); }

    bool merge(int x, int y) {
        x = root(x);
        y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y);
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        return true;
    }
};

ll gcd_ext(ll a, ll b, ll& x, ll& y) {
    x = 1;
    ll x_next = 0;
    ll r = a;
    ll r_next = b;
    while (r_next != 0) {
        ll tmp = x_next;
        x_next = x - x_next * (r / r_next);
        x = tmp;

        tmp = r_next;
        r_next = r % r_next;
        r = tmp;
    }
    y = (r - a * x) / b;
    return r;
}
template <class T> inline void cerr_vector(vector<T>& a) {
    for (int i = 0; i < a.size(); i++) {
        cerr << a[i] << " ";
    }
    cerr << endl;
}

template <class T> inline void cerr_vector2(vector<vector<T>>& a) {
    for (int i = 0; i < a.size(); i++) {
        cerr_vector(a[i]);
    }
    cerr << endl;
}
int popcount(ull a) {
    int res = 0;
    while (a > 0) {
        if (a & 1) { res++; }
        a >>= 1;
    }
    return res;
}

ll pow_ll(ll b, ll k, ll g) {
    ll res = 1;
    ll tmp = b;
    while (k > 0) {
        if (k & 1) {
            /*
            if (k != 0 && res > __LONG_LONG_MAX__ / tmp)
            {
                return -1;
            }*/
            res *= tmp;

            res %= g;
        }
        k >>= 1;
        // todo: 消す
        /*
        if (k != 0 && tmp > __LONG_LONG_MAX__ / tmp)
        {
            return -1;
        }*/
        tmp *= tmp;

        tmp %= g;
    }
    return res;
}
using PQP = priority_queue<pair<ll, int>, vector<pair<ll, int>>,
                           greater<pair<ll, int>>>;
using P = pair<ll, ll>;
using vp = vector<P>;
using P3 = pair<ll, P>;
using vp3 = vector<P3>;
using P4 = pair<P3, int>;
using vp2 = vector<vp>;
using T = tuple<int, int, int, int>;
using t3 = tuple<ll, ll, ll>;
using vt = vector<T>;
vi dx = {0, 1, 0, -1, 1, 1, -1, -1};
vi dy = {1, 0, -1, 0, 1, -1, 1, -1};

int main() {

    while (1) {
        int n, m;
        cin >> n >> m;
        vi s(n);
        rep(i, n) cin >> s[i];
        if (n == 0) return 0;

        int ng = s[0] - 1, ok = 11000000;
        while (ok - ng > 1) {
            int mid = (ok + ng) / 2;
            int l = 1;
            bool can = false;
            if (l + mid > s[0]) {
                rep(i, m - 1) {
                    if (l + mid > s[n - 1]) {
                        can = true;
                        break;
                    }
                    auto itr = lower_bound(all(s), l);
                    int up_level = l + 1;
                    assert(itr != s.end());

                    int t1 = *itr;
                    chmax(up_level, mid - t1 + 2 * l);
                    if (itr != s.begin()) {
                        int t2 = *(itr - 1);
                        chmax(up_level, mid + t2);
                    }
                    l = up_level;
                }
            }
            if (can) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        if (ng == s[0] - 1) {
            cout << -1 << endl;
        } else
            cout << ng << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1760
memory_kb: 3712
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}


int n,m;
vector<ll> v(0);


int check(int x) {
    ll lv = 1;
    int now = 0;
    int tm = 0;

    if (lv+x <= v[0]) {
        return 0;
    }


    while (lv+x <= v[n-1]) {
        while (abs(lv-v[now]) > abs(lv-v[now+1])) {
            now++;
        }

        lv += max(1ll,x-abs(lv-v[now]));
        tm++;


        if (tm >= m-1) {
            return 1;
        }
    }

    return 0;
}




void solve() {
    v.resize(n);
    rep(i,n) {
        cin >> v[i];
    }

    v.push_back(INF);

    int ng = v[n-1];
    int ok = v[0];

    while (ng-ok > 1) {
        int mid = (ok+ng)/2;
        if (check(mid)) {
            ok = mid+1;
        }
        else {
            ng = mid-1;
        }
    }

    if (ok == v[0]) {
        if (check(ok)) {
            if (check(ng)) {
                cout << ng << endl;
            }
            else {
                cout << ok << endl;
            }
        }
        else {
            cout << -1 << endl;
        }

        return;
    }


    if (check(ng)) {
        cout << ng << endl;
    }
    else {
        cout << ng-1 << endl;
    }
    return;
}


int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    while (cin >> n >> m && n != 0) {
        solve();
    }
	return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 4664
final_rank: 8

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }
int N, M;
void solve(){
    vi S(N); rep(i, N) cin >> S[i];
    auto f = [&](int x){
        int level = 1, idx = 0;
        for (int turn = 1; turn < M; turn++){
            if (S.back() < level + x) return false;
            while (idx < N - 1 && S[idx + 1] < level + x && abs(level - S[idx]) > abs(level - S[idx + 1])) idx++;
            level += max(1, x - abs(level - S[idx]));
        }
        return true;
    };
    if (!f(S[0])){
        cout << -1 << endl;
        return;
    }
    int top = S.back() + 1, bottom = S[0];
    while (top - bottom > 1){
        int mid = (top + bottom) / 2;
        if (f(mid)) bottom = mid;
        else top = mid;
    }
    cout << bottom << endl;
}

int main(){
    while (true){
        cin >> N >> M;
        if (N == 0) break;
        solve();
    }
}
accuracy: 1
time_ms: 230
memory_kb: 3720
final_rank: 1

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    using P=pair<ll,ll>;
    using tp=tuple<ll,ll,ll>;
    const int INF=1001001001;
    const ll INFL=1e18;
    const int mod=998244353;

    bool solve(){
		int n,m;
		cin>>n>>m;
		if(!n&&!m)return false;
		vector<int>s(n);
		rep(i,n)cin>>s[i];

		auto f=[&](int x){
			if(1+x<=s[0])return -1;

			int cnt=0,l=1;
			rep(z,m+1){
				if(l+x>s[n-1])break;
				cnt++;
                auto j=lower_bound(s.begin(),s.end(),l)-s.begin();
                int mn=INF;
                if(j<n&&s[j]<l+x)chmin(mn,abs(l-s[j]));
                if(j>0)chmin(mn,abs(l-s[j-1]));
				l+=max(1,x-mn);
			}
			return cnt+1;
		};

		int l=0,r=s[n-1];
		while(r-l>1){
			int mid=(l+r)/2;
            int x=f(mid);
            if(x==-1||x>=m)l=mid;
			else r=mid;
		}
        cout<<(f(l)>=m?l:-1)<<endl;
		return true;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);

		while(1){
			if(!solve())return false;
		}
		
        return 0;
    }
accuracy: 1
time_ms: 1410
memory_kb: 3844
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define MAX_N 100005

int N, M;
int s[MAX_N];

// Function to check if a given value X results in at least M battles
int check(int X) {
    int battles = 0;  // Count of battles needed
    int level = 1;    // Starting level of the protagonist
    int p = 0;        // Pointer to the current monster type

    // Loop to determine the number of battles required
    while (level + X <= s[N - 1]) {
        // Move the pointer to the strongest monster that can be defeated
        while (p + 1 < N && s[p] <= level) p++;
        
        int f = p;
        if (s[f] >= level + X) f--;
        if (f > 0 && abs(s[f] - level) > abs(s[f - 1] - level)) f--;
        if (f < 0) return INT_MAX;  // Impossible case
        
        battles++;
        level += max(1, X - abs(s[f] - level));
    }

    return battles + 1;
}

// Function to find the maximum X that requires at least M battles
int solve() {
    int left = s[0];  // Lower bound for X
    int right = 1e9;  // Upper bound for X
    int mid;

    // Perform binary search to find the maximum X
    while (right - left > 1) {
        mid = (left + right) / 2;
        if (check(mid) >= M) {
            left = mid;  // Increase lower bound
        } else {
            right = mid; // Decrease upper bound
        }
    }

    // Verify the result for the left boundary
    if (check(left) >= M) return left;
    else return -1;  // No valid X found
}

int main() {
    while (true) {
        cin >> N >> M;
        if (N == 0 && M == 0) break;

        for (int i = 0; i < N; i++) cin >> s[i];
        
        cout << solve() << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1080
memory_kb: 3504
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int Count(vector<int>& A, int X) {
    int N = A.size();
    int L = 1;
    auto f = [&](int S) {
        if (S >= L + X) return 0;
        else return max(1, X - abs(L - S));
    };
    if (f(A[0]) == 0) return inf;
    int Ret = 0, ID = 0;
    while(1) {
        if (f(A[N-1]) != 0) {
            Ret++;
            break;
        }
        while(ID + 1 < N && f(A[ID]) <= f(A[ID+1])) ID++;
        L += f(A[ID]);
        Ret++;
    }
    return Ret;
}

int main() {
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0) return 0;
    vector<int> A(N);
    rep(i,0,N) cin >> A[i];
    int OK = 0, NG = 3000000;
    while(NG - OK > 1) {
        int MID = (OK + NG) / 2;
        if (Count(A,MID) >= M) OK = MID;
        else NG = MID;
    }
    if (Count(A,OK) != inf) cout << OK << endl;
    else cout << -1 << endl;
}
}
accuracy: 1
time_ms: 560
memory_kb: 3792
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    while(true) {
        int N, M;
        cin >> N >> M;
        if(N == 0) return 0;
        vector<int> S(N);
        for(int i = 0; i < N; i++) {
            cin >> S[i];
        }

        int enemy_idx = 0;
        int level = 1;
        int event = 0;

        while(enemy_idx < N - 1) {
            if(S[N - 1] < level + S[0]) {
                event++;
                break;
            }

            // 敵の遷移
            while(enemy_idx < N - 1 && 
                    S[enemy_idx + 1] < level + S[0] && 
                    max(1, S[0] - abs(level - S[enemy_idx])) <= max(1, S[0] - abs(level - S[enemy_idx + 1]))) enemy_idx++;
            
            // 敵を倒す
            level += max(1, S[0] - abs(level - S[enemy_idx]));
            event++;
        }

        if(event < M) {
            cout << -1 << endl;
            continue;
        }

        int ok = S[0], ng = S[N - 1] + 1;
        while(ok + 1 < ng) { 
            int mid = (ok + ng) / 2;

            int enemy_idx = 0;
            int level = 1;
            int event = 0;

            while(enemy_idx < N - 1) {
                if(S[N - 1] < level + mid) {
                    event++;
                    break;
                }

                // 敵の遷移
                while(enemy_idx < N - 1 && 
                      S[enemy_idx + 1] < level + mid && 
                      max(1, mid - abs(level - S[enemy_idx])) <= max(1, mid - abs(level - S[enemy_idx + 1]))) enemy_idx++;
                
                // 敵を倒す
                level += max(1, mid - abs(level - S[enemy_idx]));
                event++;
            }

            if(M <= event) ok = mid;
            else ng = mid;
            
        }

        cout << ok << endl;
    }


    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 3800
final_rank: 2