Go: package main

import (
    "bufio"
    "fmt"
    "strconv"
    "os"
    "strings"
    "math"
)

/*
var sc = bufio.NewScanner(os.Stdin) exceed MaxScanTokenSize
func read() string {
    sc.Scan()
    return sc.Text()
}
*/

var rdr = bufio.NewReaderSize(os.Stdin, 1000000)

func readLine() string {
    buf := make([]byte, 0, 1000000)
    for {
        l, p, e := rdr.ReadLine()
        if e != nil {
            panic(e)
        }
        buf = append(buf, l...)
        if !p {
            break
        }
    }
    return string(buf)
}

func toInt(str string) int {
    n, _ := strconv.Atoi(str)
    return n
}

func min(a int, b int) int {
    return int(math.Min(float64(a), float64(b)))
}

func max(a int, b int) int {
    return int(math.Max(float64(a), float64(b)))
}

func main() {
    nm := strings.Split(readLine(), " ")
    n := toInt(nm[0])
    var infoDist [100000]int
    for i := 0; i < n; i++ {
        infoDist[i] = 100000
    }
    haveInfo := strings.Split(readLine(), " ")
    for _, value := range haveInfo {
        infoDist[toInt(value) - 1] = 0
    }

    for i := 0;i < n - 1; i++ {
        infoDist[i + 1] = min(infoDist[i] + 1, infoDist[i + 1])
    }

    for i := n - 1;i > 0; i-- {
        infoDist[i - 1] = min(infoDist[i] + 1, infoDist[i - 1])
    }

    ans := 0
    for i := 0;i < n;i++ {
        ans = max(ans, infoDist[i])
    }

    fmt.Println(max(ans, infoDist[0]))

}

C++: /* template.cpp {{{ */
#include <bits/stdc++.h>
using namespace std;
 
// #define int long long
#define GET_MACRO(a, b, c, d, NAME, ...) NAME
#define REP1(n) REP2(i_, n)
#define REP2(i, n) REP3(i, 0, n)
#define REP3(i, a, b) REP4(i, a, b, 1)
#define REP4(i, a, b, s) for (long long i = (a); i < (long long)(b); i += (long long)(s))
#define RREP1(n) RREP2(i_, n)
#define RREP2(i, n) RREP3(i, 0, n)
#define RREP3(i, a, b) RREP4(i, a, b, 1)
#define RREP4(i, a, b, s) for (long long i = (b) - 1; i >= (long long)(a);  i -= (long long)(s))
#define rep(...) GET_MACRO(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define rrep(...) GET_MACRO(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define fs first
#define sc second
#define all(c) std::begin(c), std::end(c)
#define pcnt(x) __builtin_popcountll(x)
#define each(x, c) for (auto &&x : c)
#define endl "\n"
#define y0 y0_
#define y1 y1_
#define yn yn_
 
#define TMP_T template<typename T>
#define TMP_TU template<typename T, typename U>
#define TMP_Ts template<typename ...T>
#define TMP_NTs template<size_t N, typename ...T>
#define TMP_CT template<bool C, typename T = void>
 
#ifndef DEBUG
#define cerr no_output
struct NoOutput : ostream {
  TMP_T ostream &operator<<(const T &){ return *this; }
} no_output;
#endif
 
using uint = unsigned;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
TMP_T using PQL = priority_queue<T, vector<T>, greater<T>>;
TMP_T using PQG = priority_queue<T>;
TMP_CT using enable_if_t = typename enable_if<C, T>::type;
 
const ll LLINF = 1e18 + 10;
#ifndef int
const int INF = 1e9 + 10;
#else
const int INF = LLINF;
#endif
 
const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};
const int dy[] = {0, -1, 0, 1, -1, -1, 1, 1};
 
TMP_T inline constexpr T sq(T x){ return x * x; }
TMP_TU inline T& chmin(T &x, U y){ if (x > y) x = y; return x; }
TMP_TU inline T& chmax(T &x, U y){ if (x < y) x = y; return x; }
 
TMP_NTs enable_if_t<(N >= sizeof...(T))> input_tuple(istream &, tuple<T...> &){}
TMP_NTs enable_if_t<(N < sizeof...(T))> input_tuple(istream &is, tuple<T...> &x){ is >> get<N>(x); input_tuple<N + 1, T...>(is, x); }
TMP_Ts ostream &operator>>(istream &is, tuple<T...> &x){ input_tuple<0, T...>(is, x); return is; }
TMP_TU ostream &operator>>(istream &is, pair<T, U> &x){ return is >> x.first >> x.second; }
TMP_NTs enable_if_t<(N >= sizeof...(T))> print_tuple(ostream &, const tuple<T...> &){}
TMP_NTs enable_if_t<(N < sizeof...(T))> print_tuple(ostream &os, const tuple<T...> &x){ os << (N > 0 ? " " : "") << get<N>(x); print_tuple<N + 1, T...>(os, x); }
TMP_Ts ostream &operator<<(ostream &os, const tuple<T...> &x){ print_tuple<0, T...>(os, x); return os; }
TMP_TU ostream &operator<<(ostream &os, const pair<T, U> &x){ return os << x.first << " " << x.second; }
 
#undef TMP_T
#undef TMP_TU
#undef TMP_Ts
#undef TMP_NTs
#undef TMP_CT

ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b){ return a / gcd(a, b) * b; }
tuple<ll, ll, ll> extgcd(ll a, ll b){
  if (b){
    ll g, x, y;
    tie(g, x, y) = extgcd(b, a % b);
    return make_tuple(g, y, x - a / b * y);
  }
  return make_tuple(a, 1, 0);
}
ll invmod(ll a, ll m = 1000000007){
  ll g, x;
  tie(g, x, ignore) = extgcd(a, m);
  return g == 1 ? (x + m) % m : 0;
}

inline ll in(){ ll x; cin >> x; return x; }
 
struct prepare {
  prepare(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(12);
    cerr << fixed << setprecision(12);
  }
} prepare_;
/* }}} */

int n, m;
int dp[100000];

signed main()
{
  cin >> n >> m;
  fill_n(dp, 100000, INF);
  rep(m) dp[in() - 1] = 0;
  rep(i, n - 1) chmin(dp[i + 1], dp[i] + 1);
  rrep(i, 1, n) chmin(dp[i - 1], dp[i] + 1);
  int res = 0;
  rep(i, n) chmax(res, dp[i]);
  cout << res << endl;
}

C++: #include <bits/stdc++.h>
using namespace std;
long long esp_org,esp_new;

typedef complex<double> P;



int deg[100010];
vector<int> g[100010];

set<int> A,B;
int N;
	

void rekkyo(int x,int p){
	A.erase(x);
	B.insert(x);
	for( auto e : g[x] ){
		if( e != p ){
			rekkyo(e,x);
		}
	}
}

int subtree(int x,int p){

	int ans = 0;
	for( auto e : g[x] ){
		if( e != p ){
			int sz = subtree(e,x);
			ans += sz;
			if( N - sz == sz ){
				deg[e]--;
				deg[x]--;
				rekkyo(e,x);
			}
		}
	}
	return ans+1;
}

int u,v;
bool check(set<int> A){
	int X;
	if( A.count(u) ) X = u;
	else X = v;

	if( deg[X] != 1 ) return false;
	
	int D[3] = {};
	for( auto a : A ){
		if( deg[a] != 1 && deg[a] != 2 ) return false;
		D[deg[a]]++;
	}
	return D[1] == 2;
}



int _main(){
	cin >> N;
	
	cin >> u >> v;
	u--,v--;
	for(int i = 0 ; i < N ; i++) A.insert(i);
	for(int i = 0 ; i < N-1 ; i++){
		int a,b;
		cin >> a >> b;
		--a,--b;
		g[a].push_back(b);
		g[b].push_back(a);
		deg[a]++;
		deg[b]++;
	}
	subtree(0,-1);
	if( A.size() != B.size() ){
		cout << "No" << endl;
		return 0;
	}

	if( A.count(u) && A.count(v) || A.count(u) && A.count(v) ) cout << "No" << endl;
	else if( check(A) && check(B) ){
		cout << "Yes" << endl;
	}else{
		cout << "No" << endl;
	}
}

int main(){
	const int size = 256 * 1024 * 1024;
	void *p = malloc(size);
	esp_new = (long long)p + size - 1;
	__asm__("mov %rsp, esp_org");
	__asm__("mov esp_new, %rsp");
	
	_main();

	__asm__("mov esp_org, %rsp");	
}

C++: //	created : 16/03/14
// 	author   : Rp7rf
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
#define rep(i,a) for(int i = 0 ; i < a ; i ++)
#define loop(i,a,b) for(int i = a ; i < b ; i ++)
#define vi vector<int>
#define mp make_pair
#define pb push_back
#define MOD 1000000007
#define INF 1e9

bool ok(ll t,ll n,ll m,vector<ll> x){
	ll p = 0;
	rep(i,m){
		if(p < x[i]){
			if( x[i] - p > t){
				return false;
			}
			p = max(	x[i] + (t-2 * (x[i] - p)) + 1,
						x[i] + (t-(x[i]-p))/2 + 1);
		} else {
			p = max(p,x[i] + t + 1);
		}

		if( p >= n){
			return true;
		}
	}
	return false;
}

int main(void){
	int n,m;
	cin>>n>>m;
	vector<ll> x(m);
	rep(i,m){
		cin>>x[i];
		x[i]--;
	}

	if(n==m){
		cout<<0<<endl;
		return 0;
	}

	ll l = 0;
	ll r = INF;

	while(r - l > 1){
		ll mid = (r+l) / 2;
		if(ok(mid,n,m,x)){
			r = mid;
		}else{
			l = mid;
		}
	}

	cout<<r<<endl;
}