#include <bits/stdc++.h>
using namespace std;
const int INF = 1 << 28;
template <class T>
bool chmax(T& a, const T& b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T& a, const T& b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& t) {
  os << "[";
  for (__typeof((t).begin()) it = (t).begin(); it != (t).end(); it++) {
    if (it != t.begin()) os << ",";
    os << *it;
  }
  os << "]";
  return os;
}
template <class T>
ostream& operator<<(ostream& os, const set<T>& t) {
  os << "{";
  for (__typeof((t).begin()) it = (t).begin(); it != (t).end(); it++) {
    if (it != t.begin()) os << ",";
    os << *it;
  }
  os << "}";
  return os;
}
template <class S, class T>
ostream& operator<<(ostream& os, const pair<S, T>& t) {
  return os << "(" << t.first << "," << t.second << ")";
}
unsigned long xor128() {
  static unsigned long x = 123456789, y = 362436069, z = 521288629,
                       w = 88675123;
  unsigned long t;
  t = (x ^ (x << 11));
  x = y;
  y = z;
  z = w;
  return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
inline int signum(double x) { return (abs(x) < 1.0e-10 ? 0 : x > 0 ? 1 : -1); }
inline double norm(complex<double> p) {
  return p.real() * p.real() + p.imag() * p.imag();
}
inline double outp(const complex<double>& a, const complex<double>& b) {
  return (conj(a) * b).imag();
}
inline int ccw(const complex<double>& p, const complex<double>& r,
               const complex<double>& s) {
  complex<double> a(r - p), b(s - p);
  return signum(outp(a, b));
}
bool xy_less(const complex<double>& a, const complex<double>& b) {
  if (abs(a.imag() - b.imag()) < 1.0e-10) return (a.real() < b.real());
  return (a.imag() < b.imag());
}
template <class IN>
void walk_rightside(IN begin, IN end, vector<complex<double> >& v) {
  IN cur = begin;
  v.push_back(*cur++);
  vector<complex<double> >::size_type s = v.size();
  v.push_back(*cur++);
  while (cur != end) {
    if (v.size() == s || ccw(v[v.size() - 2], v.back(), *cur) > 0)
      v.push_back(*cur++);
    else
      v.pop_back();
  }
  v.pop_back();
}
vector<complex<double> > convex_hull(vector<complex<double> > v) {
  if (v.size() <= 1) return v;
  sort(v.begin(), v.end(), xy_less);
  vector<complex<double> > cv;
  walk_rightside(v.begin(), v.end(), cv);
  walk_rightside(v.rbegin(), v.rend(), cv);
  return cv;
}
vector<int> lans;
int sum;
int n, r;
int dist[50][50];
void dfs(int gs, vector<int>& ans, int s, int rest, int cur) {
  if (rest == 0) {
    if (chmax(sum, cur)) {
      lans = ans;
    }
    return;
  }
  if (4 * r * r * rest * n / 2 + cur < sum) return;
  for (int i = s; i < gs; i++) {
    int pl = 0;
    for (int j = 0; j < (int)(ans.size()); j++) pl += dist[i][ans[j]];
    ans.push_back(i);
    dfs(gs, ans, i, rest - 1, cur + pl);
    ans.pop_back();
  }
  return;
}
int main() {
  scanf("%d %d", &n, &r);
  vector<complex<double> > g;
  for (int y = -r; y <= r; y++)
    for (int x = -r; x <= r; x++)
      if (x * x + y * y <= r * r) {
        g.emplace_back(x, y);
      }
  g = convex_hull(g);
  for (int i = 0; i < (int)(g.size()); i++)
    for (int j = 0; j < (int)(g.size()); j++)
      dist[i][j] = norm(g[i] - g[j]) + 1.0e-10;
  sum = -INF;
  vector<int> ans;
  dfs(g.size(), ans, 0, n, 0);
  cout << sum << endl;
  for (int i = 0; i < (int)(n); i++)
    cout << g[lans[i]].real() << " " << g[lans[i]].imag() << endl;
  return 0;
}
