#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int) (x).size() typedef long long ll; typedef pair<int, int> pi; typedef vector<int> vi; template<class T> int sgn(T x) { return (x > 0) - (x < 0);} template<class T> struct Point { typedef Point P; T x, y; explicit Point(T x=0, T y=0) : x(x), y(y) {} bool operator<(P p) const {return tie(x, y) < tie(p.x, p.y);} bool operator==(P p) const {return tie(x, y) == tie(p.x, p.y);} P operator+(P p) const {return P(x+p.x, y+p.y);} P operator-(P p) const {return P(x-p.x, y-p.y);} P operator*(T d) const {return P(x*d, y*d);} P operator/(T d) const {return P(x/d, y/d);} T dot(P p) const {return x*p.x + y*p.y;} T cross(P p) const {return x*p.y - y*p.x;} T cross(P a, P b) const {return (a-*this).cross(b-*this);} T dist2() const {return x*x + y*y;} double dist() const { return sqrt((double)dist2());} double angle() const { return atan2(y, x);} P unit() const {return *this/dist();} P perp() const {return P(-y, x);} P normal() const {return perp().unit();} P rotate(double a) const { return P(x*cos(a)-y*sin(a), x*sin(a) + y*cos(a)); } friend ostream& operator<<(ostream& os, P p) { return os << "(" << p.x << "," << p.y << ")"; } }; template<class P> bool onSegment(P s, P e, P p) { return p.cross(s, e) == 0 && (s - p).dot(e - p) <= 0; } template<class P> vector<P> segInter(P a, P b, P c, P d) { auto oa = c.cross(d, a), ob = c.cross(d, b), oc = a.cross(b, c), od = a.cross(b, d); if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn(od) < 0) return {(a * ob - b * oa) / (ob - oa)}; set<P> s; if (onSegment(c, d, a)) s.insert(a); if (onSegment(c, d, b)) s.insert(b); if (onSegment(a, b, c)) s.insert(c); if (onSegment(a, b, d)) s.insert(d); return {all(s)}; } int main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); int n; cin >> n; ll a, b; cin >> a >> b; vector<ll> d(n - 1); for (auto& x : d) { cin >> x; } vector<ll> R(n), r(n); R[0] = r[0] = 0; for (int i = 1; i < n; ++i) { R[i] = R[i - 1] + d[i - 1]; if (d[i - 1] > R[i - 1]) { r[i] = d[i - 1] - R[i - 1]; } else { r[i] = max(0LL, r[i - 1] - d[i - 1]); } } if (!(r[n - 1] <= abs(a) + abs(b) && abs(a) + abs(b) <= R[n - 1] && R[n - 1] % 2 == ((abs(a) + abs(b))% 2))) { cout << "NO\n"; return 0; } vector<pair<ll, ll>> res; for (int i = n - 1; i > 0; --i) { res.emplace_back(a, b); ll dd = d[i - 1]; vector<pair<ll, ll>> poss{{a - dd, b}, {a + dd, b}, {a, b - dd}, {a, b + dd}}; // dodaj przeciecia vector<Point<ll>> wewn{Point{0LL, r[i - 1]}, Point{r[i - 1], 0LL}, Point{0LL, -r[i - 1]}, Point{-r[i - 1], 0LL}}; vector<Point<ll>> zewn{Point{0LL, R[i - 1]}, Point{R[i - 1], 0LL}, Point{0LL, -R[i - 1]}, Point{-R[i - 1], 0LL}}; vector<Point<ll>> curr{Point{a, b + d[i - 1]}, Point{a + d[i - 1], b}, Point{a, b - d[i - 1]}, Point{a - d[i - 1], b}}; for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { vector<Point<ll>> w = segInter(wewn[i], wewn[(i + 1) % 4], curr[j], curr[(j + 1) % 4]); vector<Point<ll>> z = segInter(zewn[i], zewn[(i + 1) % 4], curr[j], curr[(j + 1) % 4]); if (!w.empty()) { poss.emplace_back(w.front().x, w.front().y); } if (!z.empty()) { poss.emplace_back(z.front().x, z.front().y); } } } int psz = poss.size(); for (int k = 0; k < psz; ++k) for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { if (i || j) { poss.emplace_back(poss[k].first + i, poss[k].second + j); } } } for (auto [x, y] : poss) { if (abs(a - x) + abs(b - y) != d[i - 1]) { continue; } if (r[i - 1] <= abs(x) + abs(y) && abs(x) + abs(y) <= R[i - 1] && R[i - 1] % 2 == ((abs(x) + abs(y))) % 2) { a = x; b = y; } } } res.emplace_back(0, 0); reverse(all(res)); cout << "YES\n"; for (auto [x, y] : res) { cout << x << ' ' << y << '\n'; } return 0; }