#include <bits/stdc++.h>
using namespace std;
int n, m;
struct Edge {
  int pos, val;
  bool operator<(const Edge& a) const { return a.val < val; }
} D;
set<Edge> myset;
set<Edge>::iterator p;
struct node {
  int x, y;
  node(int a = 0, int b = 0) : x(a), y(b) {}
} a[4005], b[4005];
int dis(node a, node b) {
  return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
int St[1001];
int main() {
  int i, j, k, u, v;
  myset.clear();
  for (i = 0; i <= 1000; i++) {
    Edge E = {i, i * i};
    myset.insert(E);
  }
  while (~scanf("%d %d", &n, &m)) {
    int t = n * n + m * m;
    int t1 = 0, t2 = 0;
    n = n * n;
    m = m * m;
    for (i = 1; i * i < n; i++) {
      D.val = n - i * i;
      p = myset.find(D);
      if (p == myset.end()) continue;
      D = *p;
      a[t1++] = node(i, D.pos);
      a[t1++] = node(i, -D.pos);
      a[t1++] = node(-i, D.pos);
      a[t1++] = node(-i, -D.pos);
    }
    for (i = 1; i * i < m; i++) {
      D.val = m - i * i;
      p = myset.find(D);
      if (p == myset.end()) continue;
      D = *p;
      b[t2++] = node(i, D.pos);
      b[t2++] = node(i, -D.pos);
      b[t2++] = node(-i, D.pos);
      b[t2++] = node(-i, -D.pos);
    }
    if (t1 == 0 || t2 == 0) {
      puts("NO");
      continue;
    }
    bool ok = false;
    for (i = 0; i < t1; i++) {
      for (j = 0; j < t2; j++)
        if (dis(a[i], b[j]) == t) {
          if (a[i].x == b[j].x || a[i].y == b[j].y) continue;
          if (a[i].x == 0 || a[i].y == 0 || b[j].x == 0 || b[j].y == 0)
            continue;
          ok = true;
          break;
        }
      if (ok) break;
    }
    if (ok == false) {
      puts("NO");
      continue;
    }
    puts("YES");
    puts("0 0");
    printf("%d %d\n%d %d\n", a[i].x, a[i].y, b[j].x, b[j].y);
  }
  return 0;
}
