#include <bits/stdc++.h>
using namespace std;
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
typedef long long int_;
inline int_ readint(){
	int_ a = 0; char c = getchar(), f = 1;
	for(; c<'0'||c>'9'; c=getchar())
		if(c == '-') f = -f;
	for(; '0'<=c&&c<='9'; c=getchar())
		a = (a<<3)+(a<<1)+(c^48);
	return a*f;
}
inline void writeint(int_ x){
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) writeint(x/10);
	putchar((x-x/10*10)^48);
}

const int MaxN = 1000001;

struct Range{
	long long l, r;
	Range(){ l = r = 0; }
	Range(int_ L,int_ R){
		l = L, r = R;
	}
	int_& operator[](const int &x){
		return x ? r : l;
	}
};
struct BestList{
	struct Node{
		Range r; Node *nxt[2];
	};
	int dir, sgn; int_ adv;
	Node *head, *tail;
	# define unzip(x) (sgn*(x)+adv)

	BestList(){
		dir = sgn = 1, adv = 0;
		head = new Node();
		tail = new Node();
		head->nxt[dir] = tail;
		tail->nxt[dir^1] = head;
	}

	bool empty() const {
		return head->nxt[dir] == tail;
	}

	void reverse(){
		dir ^= 1; // change direction
		swap(head,tail); // keep ordered
		adv = -adv, sgn = -sgn;
	}
	void shift(int_ x){
		adv += x; // stupid
	}
	void pop_back(){
		Node *t = tail->nxt[dir^1];
		tail->nxt[dir^1] = t->nxt[dir^1];
		tail->nxt[dir^1]->nxt[dir] = tail;
		delete t; // delete from list
	}

	void truncate(int_ x){
		while(!empty()){
			Node *t = tail->nxt[dir^1];
			if(unzip(t->r[dir^1]) > x){
				pop_back(); continue;
			}
			if(sgn == 1 && t->r[dir] > x-adv)
				t->r[dir] = x-adv;
			if(!(~sgn) && t->r[dir] < adv-x)
				t->r[dir] = adv-x;
			break; // tackled all
		}
	}

	bool check(int_ x){
		Node *t = tail->nxt[dir^1];
		return t != head && unzip(t->r[dir]) == x;
	}
	int_ front() const {
		return unzip(head->nxt[dir]->r[dir^1]);
	}
	bool tiny(int_ x){
		return !empty() && front() != x;
	}

	void insert(int_ l,int_ r,bool f = false){
		Node *t = tail->nxt[dir^1];
		if(t != head && unzip(t->r[dir]) >= r)
			return ; // involved already
		t->nxt[dir] = new Node();
		l = (l-adv)*sgn, r = (r-adv)*sgn;
		t->nxt[dir]->r[dir^1] = l;
		t->nxt[dir]->r[dir] = r; // range
		t->nxt[dir]->nxt[dir^1] = t;
		t->nxt[dir]->nxt[dir] = tail;
		tail->nxt[dir^1] = t->nxt[dir];
	}
	void fillUp(int_ x){
		while(!empty()) pop_back();
		insert(0,x); // the whole thing
	}
};

BestList lis; bool tag[MaxN];
int_ dif[MaxN], w[MaxN], sy[MaxN];

int main(){
	int n = readint(); readint();
	lis.insert(0,1e18);
	for(int i=1; i<=n-2; ++i){
		w[i] = readint();
		lis.truncate(w[i]);
		if(lis.check(w[i])){
			tag[i] = true;
			lis.fillUp(w[i]);
		}
		else{
			bool corner = lis.tiny(w[i]);
			lis.reverse(); lis.shift(w[i]);
			if(corner) lis.insert(w[i],w[i]);
		}
		sy[i] = lis.front();
	}
	if(lis.empty()){
		puts("NO"); return 0;
	} else puts("YES");
	int_ now = lis.front();
	for(int i=n-2,sgn=1; i>=1; --i){
		dif[i] = now*sgn, sgn = -sgn;
		if(tag[i]) now = w[i];
		else if(now == w[i])
			now = sy[i-1];
		else{
			now = w[i]-now;
			sgn = -sgn;
		}
		if(i == 1 && !(~sgn))
			now = -now;
	}
	dif[0] = now; int_ low = 0;
	rep(i,now=0,n-2) // find valley
		low = min(low,now += dif[i]);
	writeint(now = -low);
	rep(i,0,n-2){
		putchar(' ');
		writeint(now += dif[i]);
	}
	putchar('\n');
	return 0;
}