#include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using namespace std;

using ll=long long;
using R=long double;
const R eps=1e-11; // [-1000:1000]->EPS=1e-8 [-10000:10000]->EPS=1e-7
const R pi=acos(-1);
const R inf=1e40;
inline int sgn(const R& r){ return (r > eps) - (r < -eps);}
inline int sgn(const R& a, const R &b){ return sgn(a-b); }
inline R sq(R x){return sqrt(max<R>(x,0.0));}
using C=complex<R>;

void fft2D(vector<vector<C>> &a,bool inv){
	const int r=a.size(),c=a[0].size();
 	const R sign=(inv?-1.0:1.0);

	rep(i,r){	
		int rj=0;
		rep(j,1,c-1){
			for(int k=c>>1;k>(rj^=k);k>>=1);
			if(j<rj) swap(a[i][j],a[i][rj]);
	 	}

	 	for(int m=1;m<c;m<<=1){
	 		C wn=exp(C(0.0,sign*pi/m)),w=1.0;
			rep(p,m){
				for(int s=p;s<c;s+=2*m){
					C u=a[i][s],v=a[i][s+m]*w;
					a[i][s]=u+v,a[i][s+m]=u-v;				
				}
				w*=wn;
			}
		}
		if(inv) rep(j,c) a[i][j]/=c;
	}

	rep(i,c){	
		int rj=0;
		rep(j,1,r-1){
			for(int k=r>>1;k>(rj^=k);k>>=1);
			if(j<rj) swap(a[j][i],a[rj][i]);
	 	}

	 	for(int m=1;m<r;m<<=1){
	 		C wn=exp(C(0.0,sign*pi/m)),w=1.0;
			rep(p,m){
				for(int s=p;s<c;s+=2*m){
					C u=a[s][i],v=a[s+m][i]*w;
					a[s][i]=u+v,a[s+m][i]=u-v;				
				}
				w*=wn;
			}
		}
		if(inv) rep(j,r) a[j][i]/=c;
	}

}


vector<vector<C>> convolution2D(vector<vector<C>>a,vector<vector<C>> b){
	int fft_size_r=1,fft_size_c=1;
	while (fft_size_r < a.size()+b.size()) fft_size_r <<= 1;
	while (fft_size_c < a[0].size()+b[0].size()) fft_size_c <<= 1;

	a.resize(fft_size_r);
	rep(i,fft_size_r) a[i].resize(fft_size_c);
	fft2D(a,0);
	
	b.resize(fft_size_r);
	rep(i,fft_size_r) b[i].resize(fft_size_c);
	fft2D(b,0);
	
	
	vector<vector<C>> c(fft_size_r,vector<C>(fft_size_c,0.0));
	rep(i,fft_size_r)rep(j,fft_size_c) c[i][j]=a[i][j]*b[i][j];
	fft2D(c,1);
	return c;
}

map<int,ll> ans;

int main(void){
	int n;
	cin >> n;

	vector<vector<C>> a(n,vector<C>(n));
	vector<vector<C>> b(n,vector<C>(n));

	
	rep(i,n)rep(j,n) cin >> a[i][j];

	int zero=0;
	rep(i,n)rep(j,n){
		int cur=real(a[i][j]);
		zero+=cur*(cur-1)/2;
	}

	R num=0.0,den=0.0;
	if(zero!=0) ans[0]=zero,den+=zero;

	rep(i,n)rep(j,n) b[i][j]=a[n-1-i][n-1-j];

	vector<vector<C>> c=convolution2D(a,b);

	const int m=c.size();
	// rep(i,m){
	// 	rep(j,m) cout << int(real(c[i][j])+0.5) << " ";
	// 	cout << endl;
	// }

	rep(i,2*n-1)rep(j,2*n-1){
		if(i==n-1 && j==n-1){
			i=2*n-1,j=2*n-1;
			break;
		}
		const int row=(n-1-i),col=(n-1-j);
		ans[row*row+col*col]+=ll(real(c[i][j])+0.5);
	}

	for(auto &it:ans){
		if(it.first==0) continue;
		num+=1.0*sqrt(it.first)*it.second;
		den+=1.0*it.second;
	}

	cout.precision(20);
	cout << fixed << 1.0*num/den << endl;

	int cnt=0;
	for(auto &it:ans){
		if(it.second==0) continue;
		cout << it.first << " " << it.second << endl;
		cnt++;
		if(cnt==10000) break;
	}	

	return 0;
}

Measured memory_bytes: 462576