363_E. Two Circles_21694
Let's assume that we are given an n × m table filled by integers. We'll mark a cell in the i-th row and j-th column as (i, j). Thus, (1, 1) is the upper left cell of the table and (n, m) is the lower right cell. We'll assume that a circle of radius r with the center in cell (i0, j0) is a set of such cells (i, j) that <image>. We'll consider only the circles that do not go beyond the limits of the table, that is, for which r + 1 ≤ i0 ≤ n - r and r + 1 ≤ j0 ≤ m - r. 

<image> A circle of radius 3 with the center at (4, 5). 

Find two such non-intersecting circles of the given radius r that the sum of numbers in the cells that belong to these circles is maximum. Two circles intersect if there is a cell that belongs to both circles. As there can be more than one way to choose a pair of circles with the maximum sum, we will also be interested in the number of such pairs. Calculate the number of unordered pairs of circles, for instance, a pair of circles of radius 2 with centers at (3, 4) and (7, 7) is the same pair as the pair of circles of radius 2 with centers at (7, 7) and (3, 4). 

Input

The first line contains three integers n, m and r (2 ≤ n, m ≤ 500, r ≥ 0). Each of the following n lines contains m integers from 1 to 1000 each — the elements of the table. The rows of the table are listed from top to bottom at the elements in the rows are listed from left to right. It is guaranteed that there is at least one circle of radius r, not going beyond the table limits. 

Output

Print two integers — the maximum sum of numbers in the cells that are located into two non-intersecting circles and the number of pairs of non-intersecting circles with the maximum sum. If there isn't a single pair of non-intersecting circles, print 0 0.

Examples

Input

2 2 0
1 2
2 4


Output

6 2


Input

5 6 1
4 2 1 3 2 6
2 3 2 4 7 2
5 2 2 1 1 3
1 4 3 3 6 4
5 1 4 2 3 2


Output

34 3


Input

3 3 1
1 2 3
4 5 6
7 8 9


Output

0 0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;


public class TwoCircles {

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String [] data = in.readLine().split(" ");
		int n = Integer.parseInt(data[0]);
		int m = Integer.parseInt(data[1]);
		int r = Integer.parseInt(data[2]);
		int [] border = new int[2*r+3];
		for(int i = 1; i<2*r+3; ++i)
		{
			int borde = r+1;
			while(Math.sqrt(((i-r-1)*(i-r-1))+((borde-r-1)*(borde-r-1)))<=r)
					--borde;
			border[i]=borde;
		}
		
		
		int [][] values = new int[n+1][m+1];
		for(int i = 1; i<=n; ++i)
		{
			data = in.readLine().split(" ");
			for(int j = 1; j<=m; ++j)
			{
				values[i][j] = Integer.parseInt(data[j-1]);
			}
		}
		
		Circle[][] mCircles = new Circle[n+1][m+1];
		
			for(int i0 = r+1; i0<=n-r; ++i0)
			for(int j0 = r+1; j0<=m-r; ++j0)
			{
				long value = 0;
				if(i0==r+1&&j0==r+1)
				{
					for(int i = i0-r; i<=i0+r; ++i)
						for(int j = j0-r; j<=j0+r; ++j)
							if(Math.sqrt(((i0-i)*(i0-i))+((j0-j)*(j0-j)))<=r)value+=values[i][j];
				}else
				{
					if(j0==r+1)
					{
						Circle template = mCircles[i0-1][j0];
						value = template.value;
						for(int j = 1; j<=2*r+1; ++j)
						{
							value-=values[template.i-r+border[j]][j + template.j-r -1];
							value+=values[i0+r-border[j]][j + template.j-r -1];
						}
							
					}else
					{
						Circle template = mCircles[i0][j0-1];
						value = template.value;
						for(int i = 1; i<=2*r+1; ++i)
						{	
							value-=values[i + template.i-r -1][template.j-r+border[i]];
							value+=values[i + template.i-r -1][j0+r-border[i]];
						}
					}
					
				}
				Circle newC = new Circle(i0,j0,value);
				mCircles[i0][j0] = newC;
			}
	
		Circle leftMaxOfRow[][] = new Circle[n+1][m+1];
		long lMax [][] = new long[n+1][m+1];
		Circle rightMaxOfRow[][] = new Circle[n+1][m+1];
		long rMax [][] = new long[n+1][m+1];
		
		for(int i = r+1; i<=n-r; ++i)
		{
			leftMaxOfRow[i][r+1] = mCircles[i][r+1];
			lMax[i][r+1] = 1;
			rightMaxOfRow[i][m-r] = mCircles[i][m-r];
			rMax[i][m-r] = 1;
			for(int j = r+2; j<=m-r; ++j)
			{
				if(leftMaxOfRow[i][j-1].value>mCircles[i][j].value)
				{
					leftMaxOfRow[i][j] = leftMaxOfRow[i][j-1];
					lMax[i][j] = lMax[i][j-1];
				}else if (leftMaxOfRow[i][j-1].value==mCircles[i][j].value)
				{
					leftMaxOfRow[i][j] = mCircles[i][j];
					lMax[i][j] = lMax[i][j-1] + 1;
				}else
				{
					leftMaxOfRow[i][j] = mCircles[i][j];
					lMax[i][j] = 1;
				}
				
				if(rightMaxOfRow[i][m-j+2].value>mCircles[i][m-j+1].value)
				{
					rightMaxOfRow[i][m-j+1] = rightMaxOfRow[i][m-j+2];
					rMax[i][m-j+1] = rMax[i][m-j+2];
				}else if(rightMaxOfRow[i][m-j+2].value==mCircles[i][m-j+1].value)
				{
					rightMaxOfRow[i][m-j+1] = mCircles[i][m-j+1];
					rMax[i][m-j+1] = rMax[i][m-j+2]+1;
				}else
				{
					rightMaxOfRow[i][m-j+1] = mCircles[i][m-j+1];
					rMax[i][m-j+1] = 1;
				}
			}
		}//PRECOMPUTE MAX OF ROWS FROM RL TO LR
		

		int[] ks = new int[n-2*r];
		for(int d = 0; d<=n-2*r-1; ++d)
		{
			Circle reference = new Circle(0, 0, 0);
			int k = 0;
			while(reference.intersects(new Circle(d, k, 0), r))
				++k;
			//Encuentra el primer k que no lo intersecta
			ks[d] = k;
		}//Precompute ks
		
		
		long max = 0;
		long noMax = 0;
		for(int i = r+1; i<=n-r; ++i)
		{
			for(int j = r+1; j<=m-r; ++j)
			{
				for(int x2 = r+1; x2<=n-r; ++x2)
				{
					long add = 1;
					int k = ks[Math.abs(x2-i)];
					if(k==0)
					{
						Circle other = leftMaxOfRow[x2][m-r];
						add = lMax[x2][m-r];
						if(mCircles[i][j].value+other.value>max)
						{
							max = mCircles[i][j].value+other.value;
							noMax = add;
						}else if(mCircles[i][j].value+other.value==max)
						{
							noMax+=add;
						}
					}
					else
					{
						Circle other = null;
						if(j-k>=r+1 && j+k>m-r)
						{
							other = leftMaxOfRow[x2][j-k];
							add = lMax[x2][j-k];
						}else if(j-k<r+1 && j+k<=m-r)
						{
							other = rightMaxOfRow[x2][j+k];
							add = rMax[x2][j+k];
						}else if(j-k>=r+1 && j+k<=m-r)
						{
							if(leftMaxOfRow[x2][j-k].value>rightMaxOfRow[x2][j+k].value)
							{
								other = leftMaxOfRow[x2][j-k];
								add = lMax[x2][j-k];
							}else if(leftMaxOfRow[x2][j-k].value==rightMaxOfRow[x2][j+k].value)
							{
								other = rightMaxOfRow[x2][j+k];
								add = lMax[x2][j-k]+rMax[x2][j+k];
							}else
							{
								other = rightMaxOfRow[x2][j+k];
								add = rMax[x2][j+k];
							}
						}
						if(other!=null)
						{
							if(mCircles[i][j].value+other.value>max)
							{
								max = mCircles[i][j].value+other.value;
								noMax = add;
							}else if(mCircles[i][j].value+other.value==max)
							{
								noMax+=add;
							}
						}
				
					}
				}
			}
		}
		System.out.println(max+" "+noMax/2);
		
	}

}

class Circle implements Comparable
{
	public int i;
	public int j;
	public long value;
	public Circle(int i, int j, long value)
	{
		this.i = i;
		this.j = j;
		this.value = value;
	}
	@Override
	public int compareTo(Object o) 
	{
		Circle that = (Circle)o;
		if(this.value==that.value)
		{
			if(this.i == that.i)return that.j-this.j;
			return that.i-this.i;
		}
		if(that.value-this.value>0)return 1;
		else if(that.value-this.value<0)return -1;
		else return 0;
	}
	
	@Override
	public String toString()
	{
		return "("+this.i+","+this.j+"): "+this.value;
	}
	public boolean intersects(Circle that, int r)
	{
		if(Math.sqrt((this.i-i)*(this.i-i)+(this.j-j)*(this.j-j))>2*r) return false;
		int iMin = Math.min(this.i, that.i);
		int iMax = Math.max(this.i, that.i);
		int jMin = Math.min(this.j, that.j);
		int jMax = Math.max(this.j, that.j);
		for(int i = iMin;i<=iMax;++i)
			for(int j = jMin;j<=jMax;++j)
				if(Math.sqrt((this.i-i)*(this.i-i)+(this.j-j)*(this.j-j))<=r&&Math.sqrt((that.i-i)*(that.i-i)+(that.j-j)*(that.j-j))<=r)
					return true;
		return false;
	}
}