#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <unordered_map>
#include <iterator>
#include <functional>
#include <cassert>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define pb push_back
#define eb emplace_back
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

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(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const map<S, T> &t) {
os<<"{"; FOR(it,t) {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<<")";}
template<class S, class T> pair<S,T> operator+(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first+t.first, s.second+t.second);}
template<class S, class T> pair<S,T> operator-(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first-t.first, s.second-t.second);}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000007;

template<int B> // n <= 1<<B
struct FFT{
	typedef complex<double> cd;
	vi m2[B];
	vector<cd> power[2*B];
	FFT(){
		REP(e, B){
			m2[e].resize(1<<e);
			REP(m, 1<<e)REP(i,e) if(m&(1<<i)) m2[e][m] |= (1<<(e-1-i));
			
			power[  e].resize(1<<e);
			power[B+e].resize(1<<e);
			power[e][0] = power[B+e][0] = cd(1, 0);
			cd w(cos(acos(-1.0) / (1<<e)), sin(acos(-1.0) / (1<<e)));
			REPS(j, (1<<e)-1){
				power[  e][j] = power[  e][j-1]*w;
				power[B+e][j] = power[B+e][j-1]*conj(w);
			}
		}
	}

	void transform(cd *f, int N, bool inv){
		int e;
		for(e=0;;e++) if(N == (1<<e)) break;
		REP(m,N)if(m < m2[e][m]) swap(f[m], f[m2[e][m]]);
		for(int t=0,t2=1;t2<N;t++,t2+=t2){
			cd *po = power[inv*B + t].data();
			for(int i=0;i<N;i+=t2+t2){
				for (int j = 0; j < (1<<t); j++) {
					cd x = f[i+j];
					cd y = f[i+t2+j] * po[j];
					f[i+j] = x + y;
					f[i+t2+j] = x - y;
				}
			}
		}
		if(inv) for(int i = 0; i < N; i++) f[i] /= N;
	}
	template <typename T>
	vector<cd> convolution(const vector<T> &f, const vector<T> &g){
		const int n = f.size(), m = g.size();
		int n2 = 1;
		while(n2 < 2*max(f.size(), g.size())) n2 *= 2;
		vector<cd> cf(n2), cg(n2);
		REP(i, n) cf[i] = f[i];
		REP(i, m) cg[i] = g[i];
		transform(cf.data(), n2, false);
		transform(cg.data(), n2, false);
		REP(i, n2) cf[i] *= cg[i];
		transform(cf.data(), n2, true);
		return cf;
	}
};
FFT<12> fft;

int T, n, m;

int main(int argc, char *argv[]){
	scanf("%d", &n);
	int n2 = 1;
	while(n2 < 2*n) n2*=2;
	vector<vector<complex<double>>> f(n2, vector<complex<double>>(n2));
	auto g = f;
	int sum = 0;
	REP(i, n)REP(j, n){
		int x; scanf("%d", &x);
		g[n-1-i][n-1-j] = f[i][j] = x;
		sum += x;
	}
	REP(_, 2){
		REP(i, n2){
			fft.transform(f[i].data(), n2, false);
			fft.transform(g[i].data(), n2, false);
		}
		REP(i, n2) REP(j, i){
			swap(f[i][j], f[j][i]);
			swap(g[i][j], g[j][i]);
		}
	}
	REP(i, n2)REP(j, n2) f[i][j] *= g[i][j];
	REP(_, 2){
		REP(i, n2)
			fft.transform(f[i].data(), n2, true);
		REP(i, n2) REP(j, i)
			swap(f[i][j], f[j][i]);
	}
	map<int, ll> cnt;
	double dsum = 0;
	ll all = 0;
	REP(i, 2*n)REP(j, 2*n){
		int x = f[i][j].real() + 0.5;
		int dy = abs(n - 1 - i);
		int dx = abs(n - 1 - j);
		if(x){
			if(dx+dy == 0 && !(x -= sum)) continue;
			cnt[dx*dx+dy*dy] += x;
			all += x;
			dsum += sqrt(dx*dx+dy*dy) * x;
		}
	}
	printf("%.20f\n", dsum / all);
	int putcnt = 0;
	for(auto it : cnt){
		printf("%d %lld\n", it.first, it.second/2);
		if(++ putcnt == 10000) break;
	}
	return 0;
}

Measured memory_bytes: 152004