#------------------------template--------------------------#
import os
import sys
from math import *
from collections import *
from fractions import *
from bisect import *
from heapq import*
from io import BytesIO, IOBase
def vsInput():
    sys.stdin = open('input.txt', 'r')
    sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192
class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None
    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()
    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()
    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)
class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")
ALPHA='abcdefghijklmnopqrstuvwxyz'
M=998244353
EPS=1e-6
def value():return tuple(map(int,input().split()))
def array():return [int(i) for i in input().split()]
def Int():return int(input())
def Str():return input()
def arrayS():return [i for i in input().split()]

#-------------------------code---------------------------#
# vsInput()

n=Int()
a=array()

pre=[~a[0]]
for i in range(1,n):
    pre.append( pre[-1] & (~a[i-1]))

a=a[::-1]
suf=[~a[0]]
for i in range(1,n):
    suf.append( suf[-1] & (~a[i]))

suf=suf[::-1]
a=a[::-1]

# print()
# print(pre)
# print(suf)
# print()

ma=-inf
key=0
for i in range(n):

    if(i!=0 and i!=n-1): here= suf[i+1] & pre[i-1] & (a[i])
    elif(i==0): here=suf[i+1]&a[i]
    else: here=pre[i-1]&a[i]

    if(here>ma):
        ma=here
        key=i

print(a[key],*[a[i] for i in range(n) if i!=key])


#------------------------template--------------------------#
import os
import sys
from math import *
from collections import *
from fractions import *
from bisect import *
from heapq import*
from io import BytesIO, IOBase
def vsInput():
    sys.stdin = open('input.txt', 'r')
    sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192
class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None
    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()
    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()
    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)
class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")
ALPHA='abcdefghijklmnopqrstuvwxyz'
M=998244353
EPS=1e-6
def value():return tuple(map(int,input().split()))
def array():return [int(i) for i in input().split()]
def Int():return int(input())
def Str():return input()
def arrayS():return [i for i in input().split()]

#-------------------------code---------------------------#
# vsInput()

n=Int()
a=array()

pre=[~a[0]]
for i in range(1,n):
    pre.append( pre[-1] & (~a[i-1]))

a=a[::-1]
suf=[~a[0]]
for i in range(1,n):
    suf.append( suf[-1] & (~a[i]))

suf=suf[::-1]
a=a[::-1]

# print()
# print(pre)
# print(suf)
# print()

ma=-inf
key=0
here=0
for i in range(n):

    try:
        if(i!=0 and i!=n-1): here= suf[i+1] & pre[i-1] & (a[i])
        elif(i==0): here=suf[i+1]&a[i]
        else: here=pre[i-1]&a[i]
    except:
        pass

    if(here>ma):
        ma=here
        key=i

print(a[key],*[a[i] for i in range(n) if i!=key])


n = int(input())
a = list(map(int, input().split()))
suf = [0]*(n+1)
for q in range(n-1, -1, -1):
    suf.append(suf[q+1] | a[q])
naw, ans = 0, [-1, -1]
for q in range(n):
    w = a[q] & (~(naw | suf[q+1]))
    if w > ans[0]:
        ans = [w, q]
    naw |= a[q]
print(a[ans[1]], *a[:ans[1]], *a[ans[1]+1:])


n = int(input())
a = list(map(int, input().split()))
suf = [0]*(n+1)
for q in range(n-1, -1, -1):
    suf[q] = suf[q+1] | a[q]
naw, ans = 0, [-1, -1]
for q in range(n):
    w = a[q] & (~(naw | suf[q+1]))
    if w > ans[0]:
        ans = [w, q]
    naw |= a[q]
print(a[ans[1]], *a[:ans[1]], *a[ans[1]+1:])


#!/usr/bin/env python3
import sys
input = sys.stdin.readline

n = int(input())
a = [int(item) for item in input().split()]

cnt = [0] * 10
for item in a:
    for i in range(10):
        if item & 1 << i:
            cnt[i] += 1
mask = 0
for i, item in enumerate(cnt):
    if item == 1:
        mask |= 1 << i
max_val = -1
index = -1
for i, item in enumerate(a):
    if item & mask > max_val:
        max_val = item & mask
        index = i
ans = [a[index]] + a[:index] + a[index+1:]
print(*ans)


#!/usr/bin/env python3
import sys
input = sys.stdin.readline

n = int(input())
a = [int(item) for item in input().split()]

cnt = [0] * 10
for item in a:
    for i in range(10):
        if item & 1 << i:
            cnt[i] += 1
mask = 0
for i, item in enumerate(cnt):
    if item == 1:
        mask |= 1 << i
ans = 0
for item in a:
    ans = max(ans, item & mask)
print(ans)


#!/usr/bin/env python3
import sys
input = sys.stdin.readline
from itertools import permutations

n = int(input())
a = [int(item) for item in input().split()]

cnt = [0] * 32
for item in a:
    for i in range(32):
        if item & 1 << i:
            cnt[i] += 1
mask = 0
for i, item in enumerate(cnt):
    if item == 1:
        mask |= 1 << i
max_val = -1
index = -1
for i, item in enumerate(a):
    if item & mask > max_val:
        max_val = item & mask
        index = i
ans = [a[index]] + a[:index] + a[index+1:]
print(*ans)


n = 0
a = [0]
i = 0
j = 0
x = 0
b = [0]

n = int(input())
b = list(map(int, input().split()))
a = a + b

cnt = [0] * 32
for i in range (1, n + 1):
    x = a[i]
    for j in range (0, 32):
        cnt[j] += x & 1
        x >>= 1

high = 0
for high in range (31, -1, -1):
    if cnt[high] == 1:
        break

if high == -1:
    for i in range (1, n + 1):
        print (a[i], end = ' ')
else:
    r = 0
    for r in range (1, n + 1):
        if (1 << high) & a[r] != 0:
            break

    print (a[r], end = ' ')
    for i in range (1, n + 1):
        if i == r:
            continue
        else:
            print (a[i], end = ' ')


n = 0
a = [0]
i = 0
j = 0
x = 0
b = [0]

n = int(input())
b = list(map(int, input().split()))
a = a + b

cnt = [0] * 32
for i in range (1, n + 1):
    x = a[i]
    for j in range (0, 32):
        cnt[j] += x & 1
        x >>= 1

high = 0
for high in range (0, 32, -1):
    if cnt[high] == 1:
        break

if high == 32:
    for i in range (1, n + 1):
        print (a[i], end = ' ')
else:
    r = 0
    for r in range (1, n + 1):
        if (1 << high) & a[r] != 0:
            break

    print (a[r], end = ' ')
    for i in range (1, n + 1):
        if i == r:
            continue
        else:
            print (a[i], end = ' ')


n = 0
a = [0]
i = 0
j = 0
x = 0
b = [0]

n = int(input())
b = list(map(int, input().split()))
a = a + b

cnt = [0] * 32
for i in range (1, n + 1):
    x = a[i]
    for j in range (0, 32):
        cnt[j] += x & 1
        x >>= 1

high = 0
for high in range (31, -1, -1):
    if cnt[high] == 1:
        break

if high == 0:
    for i in range (1, n + 1):
        print (a[i], end = ' ')
else:
    r = 0
    for r in range (1, n + 1):
        if (1 << high) & a[r] != 0:
            break

    print (a[r], end = ' ')
    for i in range (1, n + 1):
        if i == r:
            continue
        else:
            print (a[i], end = ' ')


#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int  n,m,r;
int map_x[510][510];
int l_x[510][510];
int circle_x[510][510];
int val_l[510][510],val_ln[510][510];
int val_r[510][510],val_rn[510][510];
int nn[510];
int ans;
long long ans_num = 0;
int main()
{
    //��ʼ������
   // freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    scanf("%d%d%d",&n,&m,&r);
    for (int i = 0;i <= r;i++)
        for (int j = 0;j <= r;j++)
        if (j * j <= r * r - i * i) nn[i] = j;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            scanf("%d",&map_x[i][j]);
            l_x[i][j] = l_x[i][j-1] + map_x[i][j];
        }
    //Ԥ����circle����ֵ��
    for (int i = 1 + r; i <= n - r; i++)
        for (int j = 1 + r; j <= m - r; j++)
        {
            val_l[i][j] = val_l[i][j-1];
            val_ln[i][j] = val_ln[i][j-1];
            for (int ii = i - r; ii <= i + r; ii++)
            {
                //int jj = sqrt(r * r - (ii - i)*(ii - i));////�����о�������
                int jj = nn[abs(ii-i)];
                circle_x[i][j]+=l_x[ii][j+jj] - l_x[ii][j-jj-1];
            }
            if (val_l[i][j] == circle_x[i][j]) val_ln[i][j]++;
            if (val_l[i][j] < circle_x[i][j])
            {
                val_l[i][j] = circle_x[i][j];
                val_ln[i][j] = 1;
            }
        }
    //debug
    /*
    for (int i = 1 + r;i <= n - r;i++)
    {
        for (int j = 1 + r;j <= m - r;j++)
            printf("%d ",circle_x[i][j]);
        printf("\n");
    }
    */
    //��ʼ��԰���е����ֵ
    for (int i = 1 + r; i <= n - r; i++)
        for (int j = m - r; j >= 1 + r; j--)
        {
            val_r[i][j] = val_r[i][j+1];
            val_rn[i][j] = val_rn[i][j+1];
            if (val_r[i][j] == circle_x[i][j]) val_rn[i][j]++;
            if (val_r[i][j] < circle_x[i][j])
            {
                val_r[i][j] = circle_x[i][j];
                val_rn[i][j] = 1;
            }
        }
    //debug
    /*
        for (int i = 1 + r;i <= n - r;i++)
        {
            for (int j = 1 + r;j <= m - r;j++)
                printf("%d ",val_l[i][j]);
            printf("\n");
        }
        //debug
        for (int i = 1 + r;i <= n - r;i++)
        {
            for (int j = 1 + r;j <= m - r;j++)
                printf("%d ",val_r[i][j]);
            printf("\n");
        }
    */
    //�ж���circle���뽻�ĺϷ�ii��jj��
    for (int i = 1 + r; i <= n - r; i++)
        for (int j = 1 + r; j <= m - r; j++)
        {
            int temp = 0;
            long long temp_num = 0;
            for (int ii = i; ii <= n - r; ii++)
            {
                int jj1 = j,jj2 = j;
                if (abs(ii - i) <= 2 * r + 1)
                {
                    jj1 = jj1 - (r - (ii - i)) - 1 - r;
                    jj2 = jj2 + (r - (ii - i)) + 1 + r;
                }
                if (ii == i) jj1 = 0;
                if (jj1 == jj2) jj1--;
                if (jj1 >= 1 + r && temp == val_l[ii][jj1]) temp_num+=val_ln[ii][jj1];
                if (jj1 >= 1 + r && temp < val_l[ii][jj1])
                {
                    temp = val_l[ii][jj1];
                    temp_num = val_ln[ii][jj1];
                }
                if (jj2 <= m - r && temp == val_r[ii][jj2]) temp_num+=val_rn[ii][jj2];
                if (jj2 <= m - r && temp < val_r[ii][jj2])
                {
                    temp = val_r[ii][jj2];
                    temp_num = val_rn[ii][jj2];
                }
                /*
                if (temp + circle_x[i][j] == 35)
                {
                    printf("%d %d %d %d %d %d\n",i,j,ii,jj1,jj2,temp_num);
                }
                */
                // if ()
            }
            //   printf("%d %d\n",temp,temp_num);

            if (temp && ans == temp + circle_x[i][j]) ans_num+=temp_num;
            if (temp && ans < temp + circle_x[i][j])
            {
                ans = temp + circle_x[i][j];
                ans_num = temp_num;
            }
        }
    printf("%d %I64d",ans,ans_num);
}


#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int  n,m,r;
int map_x[510][510];
int l_x[510][510];
int circle_x[510][510];
int val_l[510][510],val_ln[510][510];
int val_r[510][510],val_rn[510][510];
int ans,ans_num = 0;
int main()
{
    //��ʼ������
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    scanf("%d%d%d",&n,&m,&r);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            scanf("%d",&map_x[i][j]);
            l_x[i][j] = l_x[i][j-1] + map_x[i][j];
        }
    //Ԥ����circle����ֵ��
    for (int i = 1 + r; i <= n - r; i++)
        for (int j = 1 + r; j <= m - r; j++)
        {
            val_l[i][j] = val_l[i][j-1];
            val_ln[i][j] = val_ln[i][j-1];
            for (int ii = i - r; ii <= i + r; ii++)
            {
                int jj = sqrt(r * r - (ii - i)*(ii - i));////�����о�������
                circle_x[i][j]+=l_x[ii][j+jj] - l_x[ii][j-jj-1];
            }
            if (val_l[i][j] == circle_x[i][j]) val_ln[i][j]++;
            if (val_l[i][j] < circle_x[i][j])
            {
                val_l[i][j] = circle_x[i][j];
                val_ln[i][j] = 1;
            }
        }
    //debug
    /*
    for (int i = 1 + r;i <= n - r;i++)
    {
        for (int j = 1 + r;j <= m - r;j++)
            printf("%d ",circle_x[i][j]);
        printf("\n");
    }
    */
    //��ʼ��԰���е����ֵ
    for (int i = 1 + r; i <= n - r; i++)
        for (int j = m - r; j >= 1 + r; j--)
        {
            val_r[i][j] = val_r[i][j+1];
            val_rn[i][j] = val_rn[i][j+1];
            if (val_r[i][j] == circle_x[i][j]) val_rn[i][j]++;
            if (val_r[i][j] < circle_x[i][j])
            {
                val_r[i][j] = circle_x[i][j];
                val_rn[i][j] = 1;
            }
        }
    //debug
    /*
        for (int i = 1 + r;i <= n - r;i++)
        {
            for (int j = 1 + r;j <= m - r;j++)
                printf("%d ",val_l[i][j]);
            printf("\n");
        }
        //debug
        for (int i = 1 + r;i <= n - r;i++)
        {
            for (int j = 1 + r;j <= m - r;j++)
                printf("%d ",val_r[i][j]);
            printf("\n");
        }
    */
    //�ж���circle���뽻�ĺϷ�ii��jj��
    for (int i = 1 + r; i <= n - r; i++)
        for (int j = 1 + r; j <= m - r; j++)
        {
            int temp = 0,temp_num = 0;
            for (int ii = i; ii <= n - r; ii++)
            {
                int jj1 = j,jj2 = j;
                if (abs(ii - i) <= 2 * r + 1)
                {
                    jj1 = jj1 - (r - (ii - i)) - 1 - r;
                    jj2 = jj2 + (r - (ii - i)) + 1 + r;
                }
                if (ii == i) jj1 = 0;
                if (jj1 == jj2) jj1--;
                if (jj1 >= 1 + r && temp == val_l[ii][jj1]) temp_num+=val_ln[ii][jj1];
                if (jj1 >= 1 + r && temp < val_l[ii][jj1])
                {
                    temp = val_l[ii][jj1];
                    temp_num = val_ln[ii][jj1];
                }
                if (jj2 <= m - r && temp == val_r[ii][jj2]) temp_num+=val_rn[ii][jj2];
                if (jj2 <= m - r && temp < val_r[ii][jj2])
                {
                    temp = val_r[ii][jj2];
                    temp_num = val_rn[ii][jj2];
                }
                //
                if (temp + circle_x[i][j] == 35)
                {
                    printf("%d %d %d %d %d %d\n",i,j,ii,jj1,jj2,temp_num);
                }
                //
                // if ()
            }
            //   printf("%d %d\n",temp,temp_num);

            if (temp && ans == temp + circle_x[i][j]) ans_num+=temp_num;
            if (temp && ans < temp + circle_x[i][j])
            {
                ans = temp + circle_x[i][j];
                ans_num = temp_num;
            }
        }
    printf("%d %d",ans,ans_num);
}


/*
 * Author:  vawait
 * Created Time:  2013/11/12 8:50:20
 * File Name: test.cpp
 */
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define red(i, a, b) for (int i = (a); i >= (b); --i)
#define clr( x , y ) memset(x,y,sizeof(x))
#define sqr(x) ((x) * (x))
typedef long long lint;
int a[510][510],b[510][510],x[510],d[510],n,m,r;
int ans[510][510],sum[510][510],as=0,sm=0;

void init()
{
    scanf("%d%d%d",&n,&m,&r);
    int dx = r;
    rep(i,0,r) {
        while ( sqr(i) + sqr(dx) > sqr(r) ) dx --;
        x[i] = dx;
    }
    rep(i,0,r+r) {
        int mm = 0;
        rep(j,max(i-r,0),min(i,r)) mm = max( mm , x[j] + x[i-j] + 1 );
        d[i] = mm;
    }

    rep(i,1,n)
        rep(j,1,m) {
            scanf("%d",&a[i][j]);
            a[i][j] += a[i][j-1];
        }
    rep(i,r+1,n-r)
        rep(j,r+1,m-r) {
            int dx = n;
            rep(dy,0,r) {
                dx = x[dy];
                b[i][j] += a[i-dy][dx+j] - a[i-dy][j-dx-1];
                if ( dy ) b[i][j] += a[i+dy][dx+j] - a[i+dy][j-dx-1];
            }
        }

    rep(i,1,n)
        rep(j,1,m) {
            ans[i][j] = ans[i][j-1];
            sum[i][j] = sum[i][j-1];
            if ( b[i][j] == ans[i][j] ) sum[i][j]++;
            if ( b[i][j] > ans[i][j] ) ans[i][j] = b[i][j] , sum[i][j] = 1;
        }
}

void work()
{
    rep(i,r+1,n-r)
        rep(j,r+1,m-r)
            rep(k,r+1,m-r) if ( abs( i - k ) > r + r ) {
                if ( ans[k][m] + b[i][j] >= as ) {
                    if ( ans[k][m] + b[i][j] == as ) sm += sum[k][m];else sm = sum[k][m];
                    as = ans[k][m] + b[i][j];
                }
            } else {
                int q = j - d[abs(i-k)];
                if ( q > 0 && ans[k][q] + b[i][j] >= as ) {
                    if ( ans[k][q] + b[i][j] == as ) sm += sum[k][q] * 2;else sm = sum[k][q] * 2;
                    as = ans[k][q] + b[i][j];
                }
            }
    printf("%d %d",as,sm/2);
}

int main()
{
    init();
    work();
    return 0;
}


/*
 * Author:  vawait
 * Created Time:  2013/11/12 8:50:20
 * File Name: test.cpp
 */
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define red(i, a, b) for (int i = (a); i >= (b); --i)
#define clr( x , y ) memset(x,y,sizeof(x))
#define sqr(x) ((x) * (x))
typedef long long lint;
int a[510][510],b[510][510],x[510],d[510],n,m,r;
int ans[510][510],sum[510][510],as=0,sm=0;

void init()
{
    scanf("%d%d%d",&n,&m,&r);
    int dx = r;
    rep(i,0,r) {
        while ( sqr(i) + sqr(dx) > sqr(r) ) dx --;
        x[i] = dx;
    }
    rep(i,0,r+r) {
        int mm = 0;
        rep(j,max(i-r,0),min(i,r)) mm = max( mm , x[j] + x[i-j] + 1 );
        d[i] = mm;
    }

    rep(i,1,n)
        rep(j,1,m) {
            scanf("%d",&a[i][j]);
            a[i][j] += a[i][j-1];
        }
    rep(i,r+1,n-r)
        rep(j,r+1,m-r) {
            int dx = n;
            rep(dy,0,r) {
                dx = x[dy];
                b[i][j] += a[i-dy][dx+j] - a[i-dy][j-dx-1];
                if ( dy ) b[i][j] += a[i+dy][dx+j] - a[i+dy][j-dx-1];
            }
        }

    rep(i,1,n)
        rep(j,1,m) {
            ans[i][j] = ans[i][j-1];
            sum[i][j] = sum[i][j-1];
            if ( b[i][j] == ans[i][j] ) sum[i][j]++;
            if ( b[i][j] > ans[i][j] ) ans[i][j] = b[i][j] , sum[i][j] = 1;
        }
}

void work()
{
    rep(i,r+1,n-r)
        rep(j,r+1,m-r)
            rep(k,r+1,n-r) if ( abs( i - k ) > r + r ) {
                if ( ans[k][m] + b[i][j] >= as ) {
                    if ( ans[k][m] + b[i][j] == as ) sm += sum[k][m];else sm = sum[k][m];
                    as = ans[k][m] + b[i][j];
                }
            } else {
                int q = j - d[abs(i-k)];
                if ( q > r && ans[k][q] + b[i][j] >= as ) {
                    if ( ans[k][q] + b[i][j] == as ) sm += sum[k][q] * 2;else sm = sum[k][q] * 2;
                    as = ans[k][q] + b[i][j];
                }
            }
    printf("%d %d",as,sm/2);
}

int main()
{
    init();
    work();
    return 0;
}


/*
 * Author:  vawait
 * Created Time:  2013/11/12 8:50:20
 * File Name: test.cpp
 */
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define red(i, a, b) for (int i = (a); i >= (b); --i)
#define clr( x , y ) memset(x,y,sizeof(x))
#define sqr(x) ((x) * (x))
typedef long long lint;
int a[510][510],b[510][510],x[510],d[510],n,m,r;
int ans[510][510],sum[510][510],as=0;
lint sm=0;

void init()
{
    scanf("%d%d%d",&n,&m,&r);
    int dx = r;
    rep(i,0,r) {
        while ( sqr(i) + sqr(dx) > sqr(r) ) dx --;
        x[i] = dx;
    }
    rep(i,0,r+r) {
        int mm = 0;
        rep(j,max(i-r,0),min(i,r)) mm = max( mm , x[j] + x[i-j] + 1 );
        d[i] = mm;
    }

    rep(i,1,n)
        rep(j,1,m) {
            scanf("%d",&a[i][j]);
            a[i][j] += a[i][j-1];
        }
    rep(i,r+1,n-r)
        rep(j,r+1,m-r) {
            int dx = n;
            rep(dy,0,r) {
                dx = x[dy];
                b[i][j] += a[i-dy][dx+j] - a[i-dy][j-dx-1];
                if ( dy ) b[i][j] += a[i+dy][dx+j] - a[i+dy][j-dx-1];
            }
        }

    rep(i,1,n)
        rep(j,1,m) {
            ans[i][j] = ans[i][j-1];
            sum[i][j] = sum[i][j-1];
            if ( b[i][j] == ans[i][j] ) sum[i][j]++;
            if ( b[i][j] > ans[i][j] ) ans[i][j] = b[i][j] , sum[i][j] = 1;
        }
}

void work()
{
    rep(i,r+1,n-r)
        rep(j,r+1,m-r)
            rep(k,r+1,n-r) if ( abs( i - k ) > r + r ) {
                if ( ans[k][m] + b[i][j] >= as ) {
                    if ( ans[k][m] + b[i][j] == as ) sm += sum[k][m];else sm = sum[k][m];
                    as = ans[k][m] + b[i][j];
                }
            } else {
                int q = j - d[abs(i-k)];
                if ( q > r && ans[k][q] + b[i][j] >= as ) {
                    if ( ans[k][q] + b[i][j] == as ) sm += sum[k][q] * 2;else sm = sum[k][q] * 2;
                    as = ans[k][q] + b[i][j];
                }
            }
    printf("%d %I64d",as,sm/2);
}

int main()
{
    init();
    work();
    return 0;
}


/*
 * Author:  vawait
 * Created Time:  2013/11/12 8:50:20
 * File Name: test.cpp
 */
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define red(i, a, b) for (int i = (a); i >= (b); --i)
#define clr( x , y ) memset(x,y,sizeof(x))
#define sqr(x) ((x) * (x))
typedef long long lint;
int a[510][510],b[510][510],x[510],d[510],n,m,r;
int ans[510][510],sum[510][510],as=0,sm=0;

void init()
{
    scanf("%d%d%d",&n,&m,&r);
    int dx = r;
    rep(i,0,r) {
        while ( sqr(i) + sqr(dx) > sqr(r) ) dx --;
        x[i] = dx;
    }
    rep(i,0,r+r) {
        int mm = 0;
        rep(j,max(i-r,0),min(i,r)) mm = max( mm , x[j] + x[i-j] + 1 );
        d[i] = mm;
    }

    rep(i,1,n)
        rep(j,1,m) {
            scanf("%d",&a[i][j]);
            a[i][j] += a[i][j-1];
        }
    rep(i,r+1,n-r)
        rep(j,r+1,m-r) {
            int dx = n;
            rep(dy,0,r) {
                dx = x[dy];
                b[i][j] += a[i-dy][dx+j] - a[i-dy][j-dx-1];
                if ( dy ) b[i][j] += a[i+dy][dx+j] - a[i+dy][j-dx-1];
            }
        }

    rep(i,1,n)
        rep(j,1,m) {
            ans[i][j] = ans[i][j-1];
            sum[i][j] = sum[i][j-1];
            if ( b[i][j] == ans[i][j] ) sum[i][j]++;
            if ( b[i][j] > ans[i][j] ) ans[i][j] = b[i][j] , sum[i][j] = 1;
        }
}

void work()
{
    rep(i,r+1,n-r)
        rep(j,r+1,m-r)
            rep(k,r+1,n-r) if ( abs( i - k ) > r + r ) {
                if ( ans[k][m] + b[i][j] >= as ) {
                    if ( ans[k][m] + b[i][j] == as ) sm += sum[k][m];else sm = sum[k][m];
                    as = ans[k][m] + b[i][j];
                }
            } else {
                int q = j - d[abs(i-k)];
                if ( q > 0 && ans[k][q] + b[i][j] >= as ) {
                    if ( ans[k][q] + b[i][j] == as ) sm += sum[k][q] * 2;else sm = sum[k][q] * 2;
                    as = ans[k][q] + b[i][j];
                }
            }
    printf("%d %d",as,sm/2);
}

int main()
{
    init();
    work();
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int flag[2222][2222], rowBorder[2222], leftmost[2222], rightmost[2222];
int sumFlag[2222][2222];

void generateBorder()
{
    for (int i = -1000; i <= 1000; i++)
        for (int j = -1000; j <= 1000; j++)
        {
            sumFlag[i + Z][j + Z] = sumFlag[i + Z][j - 1 + Z];
            if (i * i + j * j <= r * r) sumFlag[i + Z][j + Z]++;
        }

    for (int i = -500; i <= 500; i++)
    {
        leftmost[i + Z] = oo;
        rightmost[i + Z] = -oo;
        for (int j = -500; j <= 500; j++)
        {
            int ok = 1;
            for (int dx = 0, dy = r; dx <= r && ok; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                if (sumFlag[i - dx + Z][j + dy + Z] != sumFlag[i - dx + Z][j - dy - 1 + Z]) ok = 0;
                if (sumFlag[i + dx + Z][j + dy + Z] != sumFlag[i + dx + Z][j - dy - 1 + Z]) ok = 0;
            }

            if (!ok)
            {
                leftmost[i + Z] = min(leftmost[i + Z], j - 1);
                rightmost[i + Z] = j + 1;
            }
        }
    }
}

int main()
{
    //freopen("e.in", "r", stdin);
    int x;

    cin >> m >> n >> r;

    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> x;
            row[i][j] = row[i][j - 1] + x;
        }

    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
            for (int dx = 0, dy = r; dx <= r; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
                if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
            }

    for (int i = r + 1; i <= m - r; i++)
    {
        for (int j = r + 1; j <= n - r; j++)
        {
            maxLeft[i][j] = maxLeft[i][j - 1];
            cntLeft[i][j] = cntLeft[i][j - 1];
            if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
            else
                if (score[i][j] > maxLeft[i][j])
                    maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
        }

        for (int j = n - r; j >= r + 1; j--)
        {
            maxRight[i][j] = maxRight[i][j + 1];
            cntRight[i][j] = cntRight[i][j + 1];
            if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
            else
                if (score[i][j] > maxRight[i][j])
                    maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
        }
    }

    generateBorder();

    int ans = 0;
    long long pairs = 0;
    for (int i = r + 1; i <= n - r; i++)
        for (int j = r + 1; j <= n - r; j++)
        {
            int best = 0, cnt = 0;
            for (int ii = r + 1; ii <= n - r; ii++)
            {
                int di = ii - i;
                if (leftmost[di + Z] == oo)
                {
                    if (maxLeft[ii][n - r] == best) cnt += cntLeft[ii][n - r];
                    else
                        if (maxLeft[ii][n - r] > best)
                            best = maxLeft[ii][n - r], cnt = cntLeft[ii][n - r];
                    continue;
                }

                int jl = j + leftmost[di + Z];
                int jr = j + rightmost[di + Z];

                if (jl >= r + 1)
                {
                    if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
                    else
                        if (maxLeft[ii][jl] > best)
                            best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
                }

                if (jr <= n - r)
                {
                    if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
                    else
                        if (maxRight[ii][jr] > best)
                            best = maxRight[ii][jr], cnt = cntRight[ii][jr];
                }

            }

            if (!best) continue;

            best += score[i][j];
            if (best == ans) pairs += cnt;
            else
                if (best > ans)
                    ans = best, pairs = cnt;
        }

    cout << ans << ' ' << pairs / 2 << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int flag[2222][2222], rowBorder[2222], leftmost[2222], rightmost[2222];
int sumFlag[2222][2222];

void generateBorder()
{
	for (int i = -1000; i <= 1000; i++)
		for (int j = -1000; j <= 1000; j++)
		{
			sumFlag[i + Z][j + Z] = sumFlag[i + Z][j - 1 + Z];
			if (i * i + j * j <= r * r) sumFlag[i + Z][j + Z]++;
		}

	for (int i = -500; i <= 500; i++)
	{
		leftmost[i + Z] = oo;
		rightmost[i + Z] = -oo;
		for (int j = -500; j <= 500; j++)
		{
			int ok = 1;
			for (int dx = 0, dy = r; dx <= r && ok; dx++)
			{
				while (dx * dx + dy * dy > r * r) dy--;
				if (sumFlag[i - dx + Z][j + dy + Z] != sumFlag[i - dx + Z][j - dy - 1 + Z]) ok = 0;
				if (sumFlag[i + dx + Z][j + dy + Z] != sumFlag[i + dx + Z][j - dy - 1 + Z]) ok = 0;
			}

			if (!ok)
			{
				leftmost[i + Z] = min(leftmost[i + Z], j - 1);
				rightmost[i + Z] = j + 1;
			}
		}
	}
}

int main()
{
	//freopen("e.in", "r", stdin);
	int x;

	cin >> m >> n >> r;

	for (int i = 1; i <= m; i++)
		for (int j = 1; j <= n; j++)
		{
			cin >> x;
			row[i][j] = row[i][j - 1] + x;
		}

	for (int i = r + 1; i <= m - r; i++)
		for (int j = r + 1; j <= n - r; j++)
			for (int dx = 0, dy = r; dx <= r; dx++)
			{
				while (dx * dx + dy * dy > r * r) dy--;
				score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
				if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
			}

	for (int i = r + 1; i <= m - r; i++)
	{
		for (int j = r + 1; j <= n - r; j++)
		{
			maxLeft[i][j] = maxLeft[i][j - 1];
			cntLeft[i][j] = cntLeft[i][j - 1];
			if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
			else
				if (score[i][j] > maxLeft[i][j])
					maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
		}

		for (int j = n - r; j >= r - 1; j--)
		{
			maxRight[i][j] = maxRight[i][j + 1];
			cntRight[i][j] = cntRight[i][j + 1];
			if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
			else
				if (score[i][j] > maxRight[i][j])
					maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
		}
	}

	generateBorder();

	int ans = 0;
	long long pairs = 0;
	for (int i = r + 1; i <= n - r; i++)
		for (int j = r + 1; j <= n - r; j++)
		{
			int best = 0, cnt = 0;
			for (int ii = r + 1; ii <= n - r; ii++)
			{
				int di = ii - i;
				if (leftmost[di + Z] == oo)
				{
					if (maxLeft[ii][n] == best) cnt += cntLeft[ii][n];
					else
						if (maxLeft[ii][n] > best)
							best = maxLeft[ii][n], cnt = cntLeft[ii][n];
					continue;
				}

				int jl = j + leftmost[di + Z];
				int jr = j + rightmost[di + Z];

				if (jl >= r + 1)
				{
					if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
					else
						if (maxLeft[ii][jl] > best)
							best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
				}

				if (jr <= n - r)
				{
					if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
					else
						if (maxRight[ii][jr] > best)
							best = maxRight[ii][jr], cnt = cntRight[ii][jr];
				}

			}

			if (!best) continue;

			best += score[i][j];
			if (best == ans) pairs += cnt;
			else
				if (best > ans)
					ans = best, pairs = cnt;
		}

	cout << ans << ' ' << pairs / 2 << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int flag[2222][2222], rowBorder[2222], leftmost[2222], rightmost[2222];
int sumFlag[2222][2222];

void generateBorder()
{
    for (int i = -1000; i <= 1000; i++)
        for (int j = -1000; j <= 1000; j++)
        {
            sumFlag[i + Z][j + Z] = sumFlag[i + Z][j - 1 + Z];
            if (i * i + j * j <= r * r) sumFlag[i + Z][j + Z]++;
        }

    for (int i = -500; i <= 500; i++)
    {
        leftmost[i + Z] = oo;
        rightmost[i + Z] = -oo;
        for (int j = -500; j <= 500; j++)
        {
            int ok = 1;
            for (int dx = 0, dy = r; dx <= r && ok; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                if (sumFlag[i - dx + Z][j + dy + Z] != sumFlag[i - dx + Z][j - dy - 1 + Z]) ok = 0;
                if (sumFlag[i + dx + Z][j + dy + Z] != sumFlag[i + dx + Z][j - dy - 1 + Z]) ok = 0;
            }

            if (!ok)
            {
                leftmost[i + Z] = min(leftmost[i + Z], j - 1);
                rightmost[i + Z] = j + 1;
            }
        }
    }
}

int main()
{
    //freopen("e.in", "r", stdin);
    int x;

    cin >> m >> n >> r;

    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> x;
            row[i][j] = row[i][j - 1] + x;
        }

    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
            for (int dx = 0, dy = r; dx <= r; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
                if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
            }

    for (int i = r + 1; i <= m - r; i++)
    {
        for (int j = r + 1; j <= n - r; j++)
        {
            maxLeft[i][j] = maxLeft[i][j - 1];
            cntLeft[i][j] = cntLeft[i][j - 1];
            if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
            else
                if (score[i][j] > maxLeft[i][j])
                    maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
        }

        for (int j = n - r; j >= r + 1; j--)
        {
            maxRight[i][j] = maxRight[i][j + 1];
            cntRight[i][j] = cntRight[i][j + 1];
            if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
            else
                if (score[i][j] > maxRight[i][j])
                    maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
        }
    }

    generateBorder();

    int ans = 0;
    long long pairs = 0;
    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
        {
            int best = 0, cnt = 0;
            for (int ii = r + 1; ii <= m - r; ii++)
            {
                int di = ii - i;
                if (leftmost[di + Z] == oo)
                {
                    if (maxLeft[ii][n - r] == best) cnt += cntLeft[ii][n - r];
                    else
                        if (maxLeft[ii][n - r] > best)
                            best = maxLeft[ii][n - r], cnt = cntLeft[ii][n - r];
                    continue;
                }

                int jl = j + leftmost[di + Z];
                int jr = j + rightmost[di + Z];

                if (jl >= r + 1)
                {
                    if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
                    else
                        if (maxLeft[ii][jl] > best)
                            best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
                }

                if (jr <= n - r)
                {
                    if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
                    else
                        if (maxRight[ii][jr] > best)
                            best = maxRight[ii][jr], cnt = cntRight[ii][jr];
                }

            }

            if (!best) continue;

            best += score[i][j];
            if (best == ans) pairs += cnt;
            else
                if (best > ans)
                    ans = best, pairs = cnt;
        }

    cout << ans << ' ' << pairs / 2 << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int flag[2222][2222], rowBorder[2222], leftmost[2222], rightmost[2222];

void generateBorder()
{
    for (int i = -500; i <= 500; i++)
        for (int j = -500; j <= 500; j++)
            if (i * i + j * j <= r * r)
            {
                flag[i + Z][j + Z]++;
                flag[i + Z][j + 1 + Z]--;
                for (int dx = 0, dy = r; dx <= r; dx++, dy--)
                {
                    flag[i - dx + Z][j - dy + Z]++;
                    flag[i - dx + Z][j + dy + 1 + Z]--;
                    flag[i + dx + Z][j - dy + Z]++;
                    flag[i + dx + Z][j + dy + 1 + Z]--;
                }
            }

    for (int i = -1000; i <= 1000; i++)
    {
        leftmost[i + Z] = oo;
        rightmost[i + Z] = -oo;
        for (int j = -1000; j <= 1000; j++)
        {
            flag[i + Z][j + Z] += flag[i + Z][j - 1 + Z];
            if (flag[i + Z][j + Z])
            {
                leftmost[i + Z] = min(leftmost[i + Z], j - 1);
                rightmost[i + Z] = j + 1;
            }
        }
    }
}

int main()
{
    //freopen("e.in", "r", stdin);
    int x;

    cin >> m >> n >> r;
    if (r * 2 + 1 > min(m, n))
    {
        puts("0 0");
        return 0;
    }

    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> x;
            row[i][j] = row[i][j - 1] + x;
        }

    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
            for (int dx = 0, dy = r; dx <= r; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
                if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
            }

    for (int i = r + 1; i <= m - r; i++)
    {
        for (int j = r + 1; j <= n - r; j++)
        {
            maxLeft[i][j] = maxLeft[i][j - 1];
            cntLeft[i][j] = cntLeft[i][j - 1];
            if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
            else
                if (score[i][j] > maxLeft[i][j])
                    maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
        }

        for (int j = n - r; j >= r - 1; j--)
        {
            maxRight[i][j] = maxRight[i][j + 1];
            cntRight[i][j] = cntRight[i][j - 1];
            if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
            else
                if (score[i][j] > maxRight[i][j])
                    maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
        }
    }

    generateBorder();

    int ans = 0;
    long long pairs = 0;
    for (int i = r + 1; i <= n - r; i++)
        for (int j = r + 1; j <= n - r; j++)
        {
            int best = 0, cnt = 0;
            for (int ii = r + 1; ii <= n - r; ii++)
            {
                int di = ii - i;
                if (leftmost[di + Z] == oo)
                {
                    if (maxLeft[ii][n] == best) cnt += cntLeft[ii][n];
                    else
                        if (maxLeft[ii][n] > best)
                            best = maxLeft[ii][n], cnt = cntLeft[ii][n];
                    continue;
                }

                int jl = j + leftmost[di + Z];
                int jr = j + rightmost[di + Z];

                if (jl >= r + 1)
                {
                    if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
                    else
                        if (maxLeft[ii][jl] > best)
                            best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
                }

                if (jr <= n - r)
                {
                    if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
                    else
                        if (maxRight[ii][jr] > best)
                            best = maxRight[ii][jr], cnt = cntRight[ii][jr];
                }
            }

            if (!best) continue;

            best += score[i][j];
            if (best == ans) pairs += cnt;
            else
                if (best > ans)
                    ans = best, pairs = cnt;
        }

    cout << ans << ' ' << pairs / 2 << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int leftmost[2222], rightmost[2222];
int sumFlag[2222][2222];

void generateBorder()
{
    for (int i = -250; i <= 250; i++)
        for (int j = -250; j <= 250; j++)
        {
            sumFlag[i + Z][j + Z] = sumFlag[i + Z][j - 1 + Z];
            if (i * i + j * j <= r * r) sumFlag[i + Z][j + Z]++;
        }

    for (int i = -500; i <= 500; i++)
    {
        leftmost[i + Z] = oo;
        rightmost[i + Z] = -oo;
        for (int j = -500; j <= 500; j++)
        {
            int ok = 1;
            for (int dx = 0, dy = r; dx <= r && ok; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                if (sumFlag[i - dx + Z][j + dy + Z] != sumFlag[i - dx + Z][j - dy - 1 + Z]) ok = 0;
                if (sumFlag[i + dx + Z][j + dy + Z] != sumFlag[i + dx + Z][j - dy - 1 + Z]) ok = 0;
            }

            if (!ok)
            {
                leftmost[i + Z] = min(leftmost[i + Z], j - 1);
                rightmost[i + Z] = j + 1;
            }
        }
    }
}

int main()
{
    //freopen("e.in", "r", stdin);
    int x;

    cin >> m >> n >> r;

    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> x;
            row[i][j] = row[i][j - 1] + x;
        }

    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
            for (int dx = 0, dy = r; dx <= r; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
                if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
            }

    for (int i = r + 1; i <= m - r; i++)
    {
        for (int j = r + 1; j <= n - r; j++)
        {
            maxLeft[i][j] = maxLeft[i][j - 1];
            cntLeft[i][j] = cntLeft[i][j - 1];
            if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
            else
                if (score[i][j] > maxLeft[i][j])
                    maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
        }

        for (int j = n - r; j >= r + 1; j--)
        {
            maxRight[i][j] = maxRight[i][j + 1];
            cntRight[i][j] = cntRight[i][j + 1];
            if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
            else
                if (score[i][j] > maxRight[i][j])
                    maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
        }
    }

    generateBorder();

    int ans = 0;
    long long pairs = 0;
    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
        {
            int best = 0, cnt = 0;
            for (int ii = r + 1; ii <= m - r; ii++)
            {
                int di = ii - i;
                if (leftmost[di + Z] == oo)
                {
                    if (maxLeft[ii][n - r] == best) cnt += cntLeft[ii][n - r];
                    else
                        if (maxLeft[ii][n - r] > best)
                            best = maxLeft[ii][n - r], cnt = cntLeft[ii][n - r];
                    continue;
                }

                int jl = j + leftmost[di + Z];
                int jr = j + rightmost[di + Z];

                if (jl >= r + 1)
                {
                    if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
                    else
                        if (maxLeft[ii][jl] > best)
                            best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
                }

                if (jr <= n - r)
                {
                    if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
                    else
                        if (maxRight[ii][jr] > best)
                            best = maxRight[ii][jr], cnt = cntRight[ii][jr];
                }

            }

            if (!best) continue;

            best += score[i][j];
            if (best == ans) pairs += cnt;
            else
                if (best > ans)
                    ans = best, pairs = cnt;
        }

    cout << ans << ' ' << pairs / 2 << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int flag[2222][2222], rowBorder[2222], leftmost[2222], rightmost[2222];
int sumFlag[2222][2222];

void generateBorder()
{
    for (int i = -1000; i <= 1000; i++)
        for (int j = -1000; j <= 1000; j++)
        {
            sumFlag[i + Z][j + Z] = sumFlag[i + Z][j - 1 + Z];
            if (i * i + j * j <= r * r) sumFlag[i + Z][j + Z]++;
        }

    for (int i = -500; i <= 500; i++)
    {
        leftmost[i + Z] = oo;
        rightmost[i + Z] = -oo;
        for (int j = -500; j <= 500; j++)
        {
            int ok = 1;
            for (int dx = 0, dy = r; dx <= r && ok; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                if (sumFlag[i - dx + Z][j + dy + Z] != sumFlag[i - dx + Z][j - dy - 1 + Z]) ok = 0;
                if (sumFlag[i + dx + Z][j + dy + Z] != sumFlag[i + dx + Z][j - dy - 1 + Z]) ok = 0;
            }

            if (!ok)
            {
                leftmost[i + Z] = min(leftmost[i + Z], j - 1);
                rightmost[i + Z] = j + 1;
            }
        }
    }
}

int main()
{
    //freopen("e.in", "r", stdin);
    int x;

    cin >> m >> n >> r;

    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> x;
            row[i][j] = row[i][j - 1] + x;
        }

    for (int i = r + 1; i <= m - r; i++)
        for (int j = r + 1; j <= n - r; j++)
            for (int dx = 0, dy = r; dx <= r; dx++)
            {
                while (dx * dx + dy * dy > r * r) dy--;
                score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
                if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
            }

    for (int i = r + 1; i <= m - r; i++)
    {
        for (int j = r + 1; j <= n - r; j++)
        {
            maxLeft[i][j] = maxLeft[i][j - 1];
            cntLeft[i][j] = cntLeft[i][j - 1];
            if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
            else
                if (score[i][j] > maxLeft[i][j])
                    maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
        }

        for (int j = n - r; j >= r + 1; j--)
        {
            maxRight[i][j] = maxRight[i][j + 1];
            cntRight[i][j] = cntRight[i][j + 1];
            if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
            else
                if (score[i][j] > maxRight[i][j])
                    maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
        }
    }

    generateBorder();

    int ans = 0;
    long long pairs = 0;
    for (int i = r + 1; i <= n - r; i++)
        for (int j = r + 1; j <= n - r; j++)
        {
            int best = 0, cnt = 0;
            for (int ii = r + 1; ii <= n - r; ii++)
            {
                int di = ii - i;
                if (leftmost[di + Z] == oo)
                {
                    if (maxLeft[ii][n] == best) cnt += cntLeft[ii][n];
                    else
                        if (maxLeft[ii][n] > best)
                            best = maxLeft[ii][n], cnt = cntLeft[ii][n];
                    continue;
                }

                int jl = j + leftmost[di + Z];
                int jr = j + rightmost[di + Z];

                if (jl >= r + 1)
                {
                    if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
                    else
                        if (maxLeft[ii][jl] > best)
                            best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
                }

                if (jr <= n - r)
                {
                    if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
                    else
                        if (maxRight[ii][jr] > best)
                            best = maxRight[ii][jr], cnt = cntRight[ii][jr];
                }

            }

            if (!best) continue;

            best += score[i][j];
            if (best == ans) pairs += cnt;
            else
                if (best > ans)
                    ans = best, pairs = cnt;
        }

    cout << ans << ' ' << pairs / 2 << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
using namespace std;
const int Z = 1000, oo = 27081993;

int m, n, r, row[555][555], score[555][555];
int maxLeft[555][555], cntLeft[555][555];
int maxRight[555][555], cntRight[555][555];
int flag[2222][2222], rowBorder[2222], leftmost[2222], rightmost[2222];
int sumFlag[2222][2222];

void generateBorder()
{
	for (int i = -1000; i <= 1000; i++)
		for (int j = -1000; j <= 1000; j++)
		{
			sumFlag[i + Z][j + Z] = sumFlag[i + Z][j - 1 + Z];
			if (i * i + j * j <= r * r) sumFlag[i + Z][j + Z]++;
		}

	for (int i = -500; i <= 500; i++)
	{
		leftmost[i + Z] = oo;
		rightmost[i + Z] = -oo;
		for (int j = -500; j <= 500; j++)
		{
			int ok = 1;
			for (int dx = 0, dy = r; dx <= r && ok; dx++)
			{
				while (dx * dx + dy * dy > r * r) dy--;
				if (sumFlag[i - dx + Z][j + dy + Z] != sumFlag[i - dx + Z][j - dy - 1 + Z]) ok = 0;
				if (sumFlag[i + dx + Z][j + dy + Z] != sumFlag[i + dx + Z][j - dy - 1 + Z]) ok = 0;
			}

			if (!ok)
			{
				leftmost[i + Z] = min(leftmost[i + Z], j - 1);
				rightmost[i + Z] = j + 1;
			}
		}
		//if (leftmost[i + Z] != oo) cout << i << ": " << leftmost[i + Z] << ' ' << rightmost[i + Z] << endl;
	}
}

int main()
{
	//freopen("e.in", "r", stdin);
	int x;

	cin >> m >> n >> r;
	if (r * 2 + 1 > min(m, n))
	{
		puts("0 0");
		return 0;
	}

	for (int i = 1; i <= m; i++)
		for (int j = 1; j <= n; j++)
		{
			cin >> x;
			row[i][j] = row[i][j - 1] + x;
		}

	for (int i = r + 1; i <= m - r; i++)
		for (int j = r + 1; j <= n - r; j++)
			for (int dx = 0, dy = r; dx <= r; dx++)
			{
				while (dx * dx + dy * dy > r * r) dy--;
				score[i][j] += row[i - dx][j + dy] - row[i - dx][j - dy - 1];
				if (dx) score[i][j] += row[i + dx][j + dy] - row[i + dx][j - dy - 1];
			}

	for (int i = r + 1; i <= m - r; i++)
	{
		for (int j = r + 1; j <= n - r; j++)
		{
			maxLeft[i][j] = maxLeft[i][j - 1];
			cntLeft[i][j] = cntLeft[i][j - 1];
			if (score[i][j] == maxLeft[i][j]) cntLeft[i][j]++;
			else
				if (score[i][j] > maxLeft[i][j])
					maxLeft[i][j] = score[i][j], cntLeft[i][j] = 1;
		}

		for (int j = n - r; j >= r - 1; j--)
		{
			maxRight[i][j] = maxRight[i][j + 1];
			cntRight[i][j] = cntRight[i][j - 1];
			if (score[i][j] == maxRight[i][j]) cntRight[i][j]++;
			else
				if (score[i][j] > maxRight[i][j])
					maxRight[i][j] = score[i][j], cntRight[i][j] = 1;
		}
	}

	generateBorder();

	int ans = 0;
	long long pairs = 0;
	for (int i = r + 1; i <= n - r; i++)
		for (int j = r + 1; j <= n - r; j++)
		{
			int best = 0, cnt = 0;
			for (int ii = r + 1; ii <= n - r; ii++)
			{
				int di = ii - i;
				if (leftmost[di + Z] == oo)
				{
					if (maxLeft[ii][n] == best) cnt += cntLeft[ii][n];
					else
						if (maxLeft[ii][n] > best)
							best = maxLeft[ii][n], cnt = cntLeft[ii][n];
					continue;
				}

				int jl = j + leftmost[di + Z];
				int jr = j + rightmost[di + Z];

				if (jl >= r + 1)
				{
					if (maxLeft[ii][jl] == best) cnt += cntLeft[ii][jl];
					else
						if (maxLeft[ii][jl] > best)
							best = maxLeft[ii][jl], cnt = cntLeft[ii][jl];
				}

				if (jr <= n - r)
				{
					if (maxRight[ii][jr] == best) cnt += cntRight[ii][jr];
					else
						if (maxRight[ii][jr] > best)
							best = maxRight[ii][jr], cnt = cntRight[ii][jr];
				}
			}

			if (!best) continue;

			best += score[i][j];
			if (best == ans) pairs += cnt;
			else
				if (best > ans)
					ans = best, pairs = cnt;
		}

	cout << ans << ' ' << pairs / 2 << endl;
}


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <stack>
#include <cassert>
#include <ctime>
#include <cmath>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define pb push_back
#define sz(x) ((x).size())
#define mp make_pair
#define x first
#define y second

const int N = 510;
const int M = 2000010;
const int mod = 1000000007;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double eps = 1e-6;

using namespace std;

int n, m, r, a[N][N], sum[N][N], sumR[N][N];
int d[N];
pii Left[N][N], Right[N][N];

#define sq(x) ((x) * (x))

int Sum(int x, int y, int r){
	int sum = 0;
	for(int i = x - r; i <= x + r; i++){
		int dis = max(sqrt(sq(r) - sq(i - x)) - 1, 0.0);
		while(sq(dis + 1) + sq(i - x) <= sq(r)) dis++;
		sum += sumR[i][y + dis] - sumR[i][y - dis - 1];
	}
	return sum;
}

int Check(int x, int y, int r){
	for(int a = 0; a <= r; a++)
		for(int b = 0; sq(a) + sq(b) <= sq(r); b++){
			if(sq(x - a) + sq(y - b) <= sq(r)) return false;
		}
	return true;
}

int main(){
	scanf("%d%d%d", &n, &m, &r);
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			sumR[i][j] = sumR[i][j - 1] + a[i][j];

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++)
			sum[i][j] = Sum(i, j, r);

	//for(int i = r + 1; i <= n - r; i++)
		//for(int j = r + 1; j <= m - r; j++)
			//cout << i << " " << j << " " << sum[i][j] << endl;

	memset(d, 0, sizeof(d));

	int dis = r + r + 2;

	for(int i = 0; i <= r + r; i++){
		while(dis >= 0 && Check(i, dis - 1, r)) dis--;
		d[i] = dis;
		//cout << i << " " << d[i] << endl;
	}

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			Left[i][j] = Left[i][j - 1];
			if(sum[i][j] > Left[i][j].first) Left[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Left[i][j].first) Left[i][j].second++;
			//cout << i << " " << j << " " << Left[i][j].first << " " << Left[i][j].second << endl;
		}
	//cout << endl;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = m - r; j >= r + 1; j--){
			Right[i][j] = Right[i][j + 1];
			if(sum[i][j] > Right[i][j].first) Right[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Right[i][j].first) Right[i][j].second++;
			//cout << i << " " << j << " " << Right[i][j].first << " " << Right[i][j].second << endl;
		}
	int ret = 0, cnt = 0;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			for(int k = r + 1; k <= n - r; k++){
				int dis = d[abs(k - i)];
				//cout << k << " " << dis << endl;
				if(dis == 0){
					if(ret < Left[k][m - r].first + sum[i][j]) ret = Left[k][m - r].first + sum[i][j], cnt = Left[k][m - r].second;
					else if(ret == Left[k][m - r].first + sum[i][j]) cnt += Left[k][m - r].second;
				}
				else{
					if(j - dis >= r + 1){
						if(ret < Left[k][j - dis].first + sum[i][j])
							ret = Left[k][j - dis].first + sum[i][j], cnt = Left[k][j - dis].second;
						else if(ret == Left[k][j - dis].first + sum[i][j])
							cnt += Left[k][j - dis].second;
					}
					if(j + dis <= m - r){
						if(ret < Right[k][j + dis].first + sum[i][j])
							ret = Right[k][j + dis].first + sum[i][j], cnt = Right[k][j + dis].second;
						else if(ret == Right[k][j + dis].first + sum[i][j])
							cnt += Right[k][j + dis].second;
					}
				}
			}
		}
	cout << ret << " " << cnt / 2<< endl;
	return 0;
}


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <stack>
#include <cassert>
#include <ctime>
#include <cmath>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define pb push_back
#define sz(x) ((x).size())
#define mp make_pair
#define x first
#define y second

const int N = 510;
const int M = 2000010;
const int mod = 1000000007;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double eps = 1e-6;

using namespace std;

int n, m, r, a[N][N], sum[N][N], sumR[N][N];
int d[N];
pii Left[N][N], Right[N][N];

#define sq(x) ((x) * (x))

int Sum(int x, int y, int r){
	int sum = 0;
	for(int i = x - r; i <= x + r; i++){
		int dis = max(sqrt(sq(r) - sq(i - x)) - 1, 0.0);
		while(sq(dis + 1) + sq(i - x) <= sq(r)) dis++;
		sum += sumR[i][y + dis] - sumR[i][y - dis - 1];
	}
	return sum;
}

int Check(int x, int y, int r){
	for(int a = 0; a <= r; a++)
		for(int b = 0; sq(a) + sq(b) <= sq(r); b++){
			if(sq(x - a) + sq(y - b) <= sq(r)) return false;
		}
	return true;
}

int main(){
	scanf("%d%d%d", &n, &m, &r);
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			sumR[i][j] = sumR[i][j - 1] + a[i][j];

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++)
			sum[i][j] = Sum(i, j, r);

	//for(int i = r + 1; i <= n - r; i++)
		//for(int j = r + 1; j <= m - r; j++)
			//cout << i << " " << j << " " << sum[i][j] << endl;

	memset(d, 0, sizeof(d));

	int dis = r + r + 2;

	for(int i = 0; i <= r + r; i++){
		while(dis >= 0 && Check(i, dis - 1, r)) dis--;
		d[i] = dis;
		//cout << i << " " << d[i] << endl;
	}

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			Left[i][j] = Left[i][j - 1];
			if(sum[i][j] > Left[i][j].first) Left[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Left[i][j].first) Left[i][j].second++;
			//cout << i << " " << j << " " << Left[i][j].first << " " << Left[i][j].second << endl;
		}
	//cout << endl;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = m - r; j >= r + 1; j--){
			Right[i][j] = Right[i][j + 1];
			if(sum[i][j] > Right[i][j].first) Right[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Right[i][j].first) Right[i][j].second++;
			//cout << i << " " << j << " " << Right[i][j].first << " " << Right[i][j].second << endl;
		}
	int ret = 0;
	ll cnt = 0;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			for(int k = r + 1; k <= n - r; k++){
				int dis = d[abs(k - i)];
				//cout << k << " " << dis << endl;
				if(dis == 0){
					if(ret < Left[k][m - r].first + sum[i][j]) ret = Left[k][m - r].first + sum[i][j], cnt = Left[k][m - r].second;
					else if(ret == Left[k][m - r].first + sum[i][j]) cnt += Left[k][m - r].second;
				}
				else{
					if(j - dis >= r + 1){
						if(ret < Left[k][j - dis].first + sum[i][j])
							ret = Left[k][j - dis].first + sum[i][j], cnt = Left[k][j - dis].second;
						else if(ret == Left[k][j - dis].first + sum[i][j])
							cnt += Left[k][j - dis].second;
					}
					if(j + dis <= m - r){
						if(ret < Right[k][j + dis].first + sum[i][j])
							ret = Right[k][j + dis].first + sum[i][j], cnt = Right[k][j + dis].second;
						else if(ret == Right[k][j + dis].first + sum[i][j])
							cnt += Right[k][j + dis].second;
					}
				}
			}
		}
	cout << ret << " " << cnt / 2<< endl;
	return 0;
}


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <stack>
#include <cassert>
#include <ctime>
#include <cmath>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define pb push_back
#define sz(x) ((x).size())
#define mp make_pair
#define x first
#define y second

const int N = 510;
const int M = 2000010;
const int mod = 1000000007;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double eps = 1e-6;

using namespace std;

int n, m, r, a[N][N], sum[N][N], sumR[N][N];
int d[N];
pii Left[N][N], Right[N][N];

#define sq(x) ((x) * (x))

int Sum(int x, int y, int r){
	int sum = 0;
	for(int i = x - r; i <= x + r; i++){
		int dis = max(sqrt(sq(r) + sq(i - x)) - 1, 0.0);
		while(sq(dis + 1) + sq(i - x) <= sq(r)) dis++;
		int l = y - dis;
		int r = y + dis;
		sum += sumR[i][r] - sumR[i][l - 1];
	}
	return sum;
}

int Check(int x, int y, int r){
	for(int a = 0; a <= r; a++)
		for(int b = 0; sq(a) + sq(b) <= sq(r); b++){
			if(sq(x - a) + sq(y - b) <= sq(r)) return false;
		}
	return true;
}

int main(){
	scanf("%d%d%d", &n, &m, &r);
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			sumR[i][j] = sumR[i][j - 1] + a[i][j];

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++)
			sum[i][j] = Sum(i, j, r);

	//for(int i = r + 1; i <= n - r; i++)
		//for(int j = r + 1; j <= m - r; j++)
			//cout << i << " " << j << " " << sum[i][j] << endl;

	memset(d, 0, sizeof(d));

	int dis = r + r + 2;

	for(int i = 0; i <= r + r; i++){
		while(dis >= 0 && Check(i, dis - 1, r)) dis--;
		d[i] = dis;
		//cout << i << " " << d[i] << endl;
	}

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			Left[i][j] = Left[i][j - 1];
			if(sum[i][j] > Left[i][j].first) Left[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Left[i][j].first) Left[i][j].second++;
			//cout << i << " " << j << " " << Left[i][j].first << " " << Left[i][j].second << endl;
		}
	//cout << endl;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = m - r; j >= r + 1; j--){
			Right[i][j] = Right[i][j + 1];
			if(sum[i][j] > Right[i][j].first) Right[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Right[i][j].first) Right[i][j].second++;
			//cout << i << " " << j << " " << Right[i][j].first << " " << Right[i][j].second << endl;
		}
	int ret = 0, cnt = 0;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			for(int k = r + 1; k <= n - r; k++){
				int dis = d[abs(k - i)];
				//cout << k << " " << dis << endl;
				if(dis == 0){
					if(ret < Left[k][m - r].first + sum[i][j]) ret = Left[k][m - r].first + sum[i][j], cnt = Left[k][m - r].second;
					else if(ret == Left[k][m - r].first + sum[i][j]) cnt += Left[k][m - r].second;
				}
				else{
					if(j - dis >= r + 1){
						if(ret < Left[k][j - dis].first + sum[i][j])
							ret = Left[k][j - dis].first + sum[i][j], cnt = Left[k][j - dis].second;
						else if(ret == Left[k][j - dis].first + sum[i][j])
							cnt += Left[k][j - dis].second;
					}
					if(j + dis <= m - r){
						if(ret < Right[k][j + dis].first + sum[i][j])
							ret = Right[k][j + dis].first + sum[i][j], cnt = Right[k][j + dis].second;
						else if(ret == Right[k][j + dis].first + sum[i][j])
							cnt += Right[k][j + dis].second;
					}
				}
			}
		}
	cout << ret << " " << cnt / 2<< endl;
	return 0;
}


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <sstream>
#include <stack>
#include <cassert>
#include <ctime>
#include <cmath>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define pb push_back
#define sz(x) ((x).size())
#define mp make_pair
#define x first
#define y second

const int N = 510;
const int M = 2000010;
const int mod = 1000000007;
const ll inf = 0x3f3f3f3f3f3f3f3fll;
const double eps = 1e-6;

using namespace std;

int n, m, r, a[N][N], sum[N][N], sumR[N][N];
int d[N];
pii Left[N][N], Right[N][N];

#define sq(x) ((x) * (x))

int Sum(int x, int y, int r){
	int sum = 0;
	for(int i = x - r; i <= x + r; i++){
		int dis = max(sqrt(sq(r) + sq(i - x)) - 1, 0.0);
		while(sq(dis + 1) + sq(i - x) <= sq(r)) dis++;
		int l = y - dis;
		int r = y + dis;
		sum += sumR[i][r] - sumR[i][l - 1];
	}
	return sum;
}

int Check(int x, int y, int r){
	for(int a = 0; a <= r; a++)
		for(int b = 0; sq(a) + sq(b) <= sq(r); b++){
			if(sq(x - a) + sq(y - b) <= sq(r)) return false;
		}
	return true;
}

int main(){
	scanf("%d%d%d", &n, &m, &r);
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			scanf("%d", &a[i][j]);

	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			sumR[i][j] = sumR[i][j - 1] + a[i][j];

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++)
			sum[i][j] = Sum(i, j, r);

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++)
			cout << i << " " << j << " " << sum[i][j] << endl;

	memset(d, 0, sizeof(d));

	int dis = r + r + 2;

	for(int i = 0; i <= r + r; i++){
		while(dis >= 0 && Check(i, dis - 1, r)) dis--;
		d[i] = dis;
		cout << i << " " << d[i] << endl;
	}

	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			Left[i][j] = Left[i][j - 1];
			if(sum[i][j] > Left[i][j].first) Left[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Left[i][j].first) Left[i][j].second++;
			cout << i << " " << j << " " << Left[i][j].first << " " << Left[i][j].second << endl;
		}
	cout << endl;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = m - r; j >= r + 1; j--){
			Right[i][j] = Right[i][j + 1];
			if(sum[i][j] > Right[i][j].first) Right[i][j] = make_pair(sum[i][j], 1);
			else if(sum[i][j] == Right[i][j].first) Right[i][j].second++;
			cout << i << " " << j << " " << Right[i][j].first << " " << Right[i][j].second << endl;
		}
	int ret = 0, cnt = 0;
	for(int i = r + 1; i <= n - r; i++)
		for(int j = r + 1; j <= m - r; j++){
			for(int k = r + 1; k <= n - r; k++){
				int dis = d[abs(k - i)];
				cout << k << " " << dis << endl;
				if(dis == 0){
					if(ret < Left[k][m - r].first + sum[i][j]) ret = Left[k][m - r].first + sum[i][j], cnt = Left[k][m - r].second;
					else if(ret == Left[k][m - r].first + sum[i][j]) cnt += Left[k][m - r].second;
				}
				else{
					if(j - dis >= r + 1){
						if(ret < Left[k][j - dis].first + sum[i][j])
							ret = Left[k][j - dis].first + sum[i][j], cnt = Left[k][j - dis].second;
						else if(ret == Left[k][j - dis].first + sum[i][j])
							cnt += Left[k][j - dis].second;
					}
					if(j + dis <= m - r){
						if(ret < Right[k][j + dis].first + sum[i][j])
							ret = Right[k][j + dis].first + sum[i][j], cnt = Right[k][j + dis].second;
						else if(ret == Right[k][j + dis].first + sum[i][j])
							cnt += Right[k][j + dis].second;
					}
				}
			}
		}
	cout << ret << " " << cnt / 2<< endl;
	return 0;
}


#include <stdio.h>
#include "math.h"

long long a[600][600],maxup[600][600][2],maxdo[600][600][2],b[600][600],n,m,r;

long long findup(long long a,long long b,long long *m1,long long *m2){
    if (a<0||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{

        if (a>=n){
            a=n-1;
        }
        if (b<0){
            b=0;
        }
        *m1=maxup[a][b][0];
        *m2=maxup[a][b][1];
    }
    return 0;
}

long long finddo(long long a,long long b,long long *m1,long long *m2){
    if (a>=n||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{
        if (a<0){
            a=0;
        }
        if (b<0){
            b=0;
        }
        *m1=maxdo[a][b][0];
        *m2=maxdo[a][b][1];
    }
    return 0;
}

long long comb(long long *a,long long *a1,long long *b,long long *b1){

    if (*b>*a){
        *a=*b;
        *a1=*b1;
    }
    else if (*b==*a){
        *a1+=*b1;
    }
    return 0;
}

long long max2ld(long long a,long long b){
    if (a>b){
        return a;
    }
    return b;
}

long long min2ld(long long a,long long b){
    if (a<b){
        return a;
    }
    return b;
}

int sdis(long long x1,long long y1,long long x2,long long y2){
    long long d;
    d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    if (d>(r*r)){
        return 0;
    }
    return 1;
}

int ncro(long long x1,long long y1,long long x2,long long y2){

    long long mx,my;
    mx=(x1+x2)/2;
    my=(y1+y2)/2;

    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    my+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx-=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    return 1;
}

int main(){

    long long i,j,k,j1,ii,jj,max,maxn,m1,m2,m1t,m2t;

    scanf("%I64d%I64d%I64d",&n,&m,&r);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            scanf("%I64d",&a[i][j]);
            b[i][j]=0;
            maxdo[i][j][0]=0;
            maxdo[i][j][1]=0;
            maxup[i][j][0]=0;
            maxup[i][j][1]=0;
        }
    }
    for (i=1;i<n;i++){
        for (j=0;j<m;j++){
            a[i][j]+=a[i-1][j];
        }
    }

    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            for (k=j-r;k<=j+r;k++){
                j1=sqrt(r*r-(j-k)*(j-k));
                if ((i-j1-1)>=0)
                    b[i][j]+=a[i+j1][k]-a[i-j1-1][k];
                else
                    b[i][j]+=a[i+j1][k];
            }
        }
    }
    for (i=0;i<n;i++){
        maxup[i][m-1][0]=b[i][m-1];
        maxup[i][m-1][1]=1;
        for (j=m-2;j>=0;j--){
            if (b[i][j]>maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=1;
            }
            else if (b[i][j]==maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=maxup[i][j+1][1]+1;
            }
            else {
                maxup[i][j][0]=maxup[i][j+1][0];
                maxup[i][j][1]=maxup[i][j+1][1];
            }
        }
    }
    for (j=0;j<m;j++){
        maxdo[n-1][j][0]=maxup[n-1][j][0];
        maxdo[n-1][j][1]=maxup[n-1][j][1];
        for (i=n-2;i>=0;i--){
            if (maxup[i][j][0]>maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1];
            }
            else if (maxup[i][j][0]==maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1]+maxdo[i+1][j][1];
            }
            else {
                maxdo[i][j][0]=maxdo[i+1][j][0];
                maxdo[i][j][1]=maxdo[i+1][j][1];
            }
        }
    }
    for (j=0;j<m;j++){
        for (i=1;i<n;i++){
            comb(&maxup[i][j][0], &maxup[i][j][1], &maxup[i-1][j][0], &maxup[i-1][j][1]);
        }
    }

    max=0;
    maxn=0;
    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            if (r>0){
                m1=0;
                m2=0;
                findup(i-2*r-1,j,&m1,&m2);
                findup(i+2*r,j+2*r+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
                findup(i-2*r-1,j+2*r+1,&m1t,&m2t);
                if (m1t==m1){
                    m2-=m2t;
                }
                finddo(i+2*r+1,j+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
            }
            else {
                m1=0;
                m2=0;
                findup(i-1,j,&m1,&m2);
                findup(i,j+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
                findup(i-1,j+1,&m1t,&m2t);
                if (m1t==m1){
                    m2-=m2t;
                }
                finddo(i+1,j+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
            }

            for (ii=max2ld(i-2*r,r);ii<=min2ld(i+2*r,n-r-1);ii++){
                for (jj=min2ld(j+2*r,m-r-1);jj>j&&(ncro(i,j,ii,jj));jj--){
                    if (b[ii][jj]>m1){
                        m1=b[ii][jj];
                        m2=1;
                    }
                    else if (b[ii][jj]==m1){
                        m2++;
                    }
                }
            }
            if (m2==0||m1==0){
                continue;
            }
            m1+=b[i][j];
            comb(&max,&maxn,&m1,&m2);
        }
    }
    printf("%I64d %I64d\n",max,maxn);
    return 0;
}


#include <stdio.h>
#include "math.h"

long long a[600][600],maxup[600][600][2],maxdo[600][600][2],maxr[600][600][2],b[600][600],n,m,r,u=4;

long long findup(long long a,long long b,long long*m1,long long*m2){
    if (a<0||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{

        if (a>=n){
            a=n-1;
        }
        if (b<0){
            b=0;
        }
        *m1=maxup[a][b][0];
        *m2=maxup[a][b][1];
    }
    return 0;
}

long long dat(){
    u+=1;
    u%=5;
    if (u==0) {
        return 812;
    }
    if (u==1){
        return 275;
    }
    if (u==2){
        return 315;
    }
    if (u==3){
        return 327;
    }
    if (u==4){
        return 482;
    }
    return 0;
}

long long finddo(long long a,long long b,long long *m1,long long *m2){
    if (a>=n||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{
        if (a<0){
            a=0;
        }
        if (b<0){
            b=0;
        }
        *m1=maxdo[a][b][0];
        *m2=maxdo[a][b][1];
    }
    return 0;
}

long long comb(long long *a,long long *a1,long long *b,long long *b1){

    if (*b>*a){
        *a=*b;
        *a1=*b1;
    }
    else if (*b==*a){
        *a1+=*b1;
    }
    return 0;
}

long long max2ld(long long a,long long b){
    if (a>b){
        return a;
    }
    return b;
}

long long min2ld(long long a,long long b){
    if (a<b){
        return a;
    }
    return b;
}

int sdis(long long x1,long long y1,long long x2,long long y2){
    long long d;
    d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    if (d>(r*r)){
        return 0;
    }
    return 1;
}

int ncro(long long x1,long long y1,long long x2,long long y2){

    long long mx,my;
    mx=(x1+x2)/2;
    my=(y1+y2)/2;

    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    my+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx-=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    return 1;
}

int main(){

    long long i,j,k,j1,ii,jj,m1,m2,m1t,m2t;
    long long long long max,maxn;

    scanf("%I64d%I64d%I64d",&n,&m,&r);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            scanf("%I64d",&a[i][j]);
            b[i][j]=0;
            maxdo[i][j][0]=0;
            maxdo[i][j][1]=0;
            maxup[i][j][0]=0;
            maxup[i][j][1]=0;
        }
    }
    for (i=1;i<n;i++){
        for (j=0;j<m;j++){
            a[i][j]+=a[i-1][j];
        }
    }

    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            for (k=j-r;k<=j+r;k++){
                j1=sqrt(r*r-(j-k)*(j-k));
                if ((i-j1-1)>=0)
                    b[i][j]+=a[i+j1][k]-a[i-j1-1][k];
                else
                    b[i][j]+=a[i+j1][k];
            }
        }
    }
    for (i=0;i<n;i++){
        maxup[i][m-1][0]=b[i][m-1];
        maxup[i][m-1][1]=1;
        for (j=m-2;j>=0;j--){
            if (b[i][j]>maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=1;
            }
            else if (b[i][j]==maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=maxup[i][j+1][1]+1;
            }
            else {
                maxup[i][j][0]=maxup[i][j+1][0];
                maxup[i][j][1]=maxup[i][j+1][1];
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            maxr[i][j][0]=maxup[i][j][0];
            maxr[i][j][1]=maxup[i][j][1];
        }
    }
    for (j=0;j<m;j++){
        maxdo[n-1][j][0]=maxup[n-1][j][0];
        maxdo[n-1][j][1]=maxup[n-1][j][1];
        for (i=n-2;i>=0;i--){
            if (maxup[i][j][0]>maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1];
            }
            else if (maxup[i][j][0]==maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1]+maxdo[i+1][j][1];
            }
            else {
                maxdo[i][j][0]=maxdo[i+1][j][0];
                maxdo[i][j][1]=maxdo[i+1][j][1];
            }
        }
    }
    for (j=0;j<m;j++){
        for (i=1;i<n;i++){
            comb(&maxup[i][j][0], &maxup[i][j][1], &maxup[i-1][j][0], &maxup[i-1][j][1]);
        }
    }

    max=0;
    maxn=0;
    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            m1=0;
            m2=0;
            findup(i-2*r-1,j,&m1,&m2);
            finddo(i+2*r+1,j+1,&m1t,&m2t);
            comb(&m1,&m2,&m1t,&m2t);
            for (ii=max2ld(i-2*r,r),jj=j;ii<=i;ii++){
                while (!ncro(i, j, ii, jj)) {
                    jj++;
                }
                if (jj<m)
                    comb(&m1, &m2, &maxr[ii][jj][0], &maxr[ii][jj][1]);
            }
            for (;ii<=min2ld(i+2*r,n-r-1);ii++){
                while (ncro(i, j, ii, jj)) {
                    jj--;
                }
                jj++;
                if (jj<m)
                    comb(&m1, &m2, &maxr[ii][jj][0], &maxr[ii][jj][1]);
            }

            if (m2==0||m1==0){
                continue;
            }
            m1+=b[i][j];
            if (m1>max){
                max=m1;
                maxn=m2;
            }
            else if (m1==max){
                maxn+=m2;
            }
        }
    }
    printf("%I64d %I64d\n",max,maxn);
    return 0;
}


#include <stdio.h>
#include "math.h"

long a[600][600],maxup[600][600][2],maxdo[600][600][2],maxr[600][600][2],b[600][600],n,m,r,u=4;

long findup(long a,long b,long*m1,long*m2){
    if (a<0||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{

        if (a>=n){
            a=n-1;
        }
        if (b<0){
            b=0;
        }
        *m1=maxup[a][b][0];
        *m2=maxup[a][b][1];
    }
    return 0;
}

long dat(){
    u+=1;
    u%=5;
    if (u==0) {
        return 812;
    }
    if (u==1){
        return 275;
    }
    if (u==2){
        return 315;
    }
    if (u==3){
        return 327;
    }
    if (u==4){
        return 482;
    }
    return 0;
}

long finddo(long a,long b,long *m1,long *m2){
    if (a>=n||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{
        if (a<0){
            a=0;
        }
        if (b<0){
            b=0;
        }
        *m1=maxdo[a][b][0];
        *m2=maxdo[a][b][1];
    }
    return 0;
}

long comb(long *a,long *a1,long *b,long *b1){

    if (*b>*a){
        *a=*b;
        *a1=*b1;
    }
    else if (*b==*a){
        *a1+=*b1;
    }
    return 0;
}

long max2ld(long a,long b){
    if (a>b){
        return a;
    }
    return b;
}

long min2ld(long a,long b){
    if (a<b){
        return a;
    }
    return b;
}

int sdis(long x1,long y1,long x2,long y2){
    long d;
    d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    if (d>(r*r)){
        return 0;
    }
    return 1;
}

int ncro(long x1,long y1,long x2,long y2){

    long mx,my;
    mx=(x1+x2)/2;
    my=(y1+y2)/2;

    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    my+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx-=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    return 1;
}

int main(){

    long i,j,k,j1,ii,jj,m1,m2,m1t,m2t;
    long long max,maxn;

    scanf("%ld%ld%ld",&n,&m,&r);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            scanf("%ld",&a[i][j]);
            b[i][j]=0;
            maxdo[i][j][0]=0;
            maxdo[i][j][1]=0;
            maxup[i][j][0]=0;
            maxup[i][j][1]=0;
        }
    }
    for (i=1;i<n;i++){
        for (j=0;j<m;j++){
            a[i][j]+=a[i-1][j];
        }
    }

    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            for (k=j-r;k<=j+r;k++){
                j1=sqrt(r*r-(j-k)*(j-k));
                if ((i-j1-1)>=0)
                    b[i][j]+=a[i+j1][k]-a[i-j1-1][k];
                else
                    b[i][j]+=a[i+j1][k];
            }
        }
    }
    for (i=0;i<n;i++){
        maxup[i][m-1][0]=b[i][m-1];
        maxup[i][m-1][1]=1;
        for (j=m-2;j>=0;j--){
            if (b[i][j]>maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=1;
            }
            else if (b[i][j]==maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=maxup[i][j+1][1]+1;
            }
            else {
                maxup[i][j][0]=maxup[i][j+1][0];
                maxup[i][j][1]=maxup[i][j+1][1];
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            maxr[i][j][0]=maxup[i][j][0];
            maxr[i][j][1]=maxup[i][j][1];
        }
    }
    for (j=0;j<m;j++){
        maxdo[n-1][j][0]=maxup[n-1][j][0];
        maxdo[n-1][j][1]=maxup[n-1][j][1];
        for (i=n-2;i>=0;i--){
            if (maxup[i][j][0]>maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1];
            }
            else if (maxup[i][j][0]==maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1]+maxdo[i+1][j][1];
            }
            else {
                maxdo[i][j][0]=maxdo[i+1][j][0];
                maxdo[i][j][1]=maxdo[i+1][j][1];
            }
        }
    }
    for (j=0;j<m;j++){
        for (i=1;i<n;i++){
            comb(&maxup[i][j][0], &maxup[i][j][1], &maxup[i-1][j][0], &maxup[i-1][j][1]);
        }
    }

    max=0;
    maxn=0;
    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            m1=0;
            m2=0;
            findup(i-2*r-1,j,&m1,&m2);
            finddo(i+2*r+1,j+1,&m1t,&m2t);
            comb(&m1,&m2,&m1t,&m2t);
            for (ii=max2ld(i-2*r,r),jj=j;ii<=i;ii++){
                while (!ncro(i, j, ii, jj)) {
                    jj++;
                }
                if (jj<m)
                    comb(&m1, &m2, &maxr[ii][jj][0], &maxr[ii][jj][1]);
            }
            for (;ii<=min2ld(i+2*r,n-r-1);ii++){
                while (ncro(i, j, ii, jj)) {
                    jj--;
                }
                jj++;
                if (jj<m)
                    comb(&m1, &m2, &maxr[ii][jj][0], &maxr[ii][jj][1]);
            }

            if (m2==0||m1==0){
                continue;
            }
            m1+=b[i][j];
            if (m1>max){
                max=m1;
                maxn=m2;
            }
            else if (m1==max){
                maxn+=m2;
            }
        }
    }
    printf("%I64d %I64d\n",max,maxn);
    return 0;
}


#include <stdio.h>
#include "math.h"

long long a[600][600],maxup[600][600][2],maxdo[600][600][2],maxr[600][600][2],b[600][600],n,m,r,u=4;

long long findup(long long a,long long b,long long*m1,long long*m2){
    if (a<0||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{

        if (a>=n){
            a=n-1;
        }
        if (b<0){
            b=0;
        }
        *m1=maxup[a][b][0];
        *m2=maxup[a][b][1];
    }
    return 0;
}

long long dat(){
    u+=1;
    u%=5;
    if (u==0) {
        return 812;
    }
    if (u==1){
        return 275;
    }
    if (u==2){
        return 315;
    }
    if (u==3){
        return 327;
    }
    if (u==4){
        return 482;
    }
    return 0;
}

long long finddo(long long a,long long b,long long *m1,long long *m2){
    if (a>=n||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{
        if (a<0){
            a=0;
        }
        if (b<0){
            b=0;
        }
        *m1=maxdo[a][b][0];
        *m2=maxdo[a][b][1];
    }
    return 0;
}

long long comb(long long *a,long long *a1,long long *b,long long *b1){

    if (*b>*a){
        *a=*b;
        *a1=*b1;
    }
    else if (*b==*a){
        *a1+=*b1;
    }
    return 0;
}

long long max2ld(long long a,long long b){
    if (a>b){
        return a;
    }
    return b;
}

long long min2ld(long long a,long long b){
    if (a<b){
        return a;
    }
    return b;
}

int sdis(long long x1,long long y1,long long x2,long long y2){
    long long d;
    d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    if (d>(r*r)){
        return 0;
    }
    return 1;
}

int ncro(long long x1,long long y1,long long x2,long long y2){

    long long mx,my;
    mx=(x1+x2)/2;
    my=(y1+y2)/2;

    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    my+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx-=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    return 1;
}

int main(){

    long long i,j,k,j1,ii,jj,m1,m2,m1t,m2t;
    long long max,maxn;

    scanf("%I64d%I64d%I64d",&n,&m,&r);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            scanf("%I64d",&a[i][j]);
            b[i][j]=0;
            maxdo[i][j][0]=0;
            maxdo[i][j][1]=0;
            maxup[i][j][0]=0;
            maxup[i][j][1]=0;
        }
    }
    for (i=1;i<n;i++){
        for (j=0;j<m;j++){
            a[i][j]+=a[i-1][j];
        }
    }

    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            for (k=j-r;k<=j+r;k++){
                j1=sqrt(r*r-(j-k)*(j-k));
                if ((i-j1-1)>=0)
                    b[i][j]+=a[i+j1][k]-a[i-j1-1][k];
                else
                    b[i][j]+=a[i+j1][k];
            }
        }
    }
    for (i=0;i<n;i++){
        maxup[i][m-1][0]=b[i][m-1];
        maxup[i][m-1][1]=1;
        for (j=m-2;j>=0;j--){
            if (b[i][j]>maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=1;
            }
            else if (b[i][j]==maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=maxup[i][j+1][1]+1;
            }
            else {
                maxup[i][j][0]=maxup[i][j+1][0];
                maxup[i][j][1]=maxup[i][j+1][1];
            }
        }
    }
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            maxr[i][j][0]=maxup[i][j][0];
            maxr[i][j][1]=maxup[i][j][1];
        }
    }
    for (j=0;j<m;j++){
        maxdo[n-1][j][0]=maxup[n-1][j][0];
        maxdo[n-1][j][1]=maxup[n-1][j][1];
        for (i=n-2;i>=0;i--){
            if (maxup[i][j][0]>maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1];
            }
            else if (maxup[i][j][0]==maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1]+maxdo[i+1][j][1];
            }
            else {
                maxdo[i][j][0]=maxdo[i+1][j][0];
                maxdo[i][j][1]=maxdo[i+1][j][1];
            }
        }
    }
    for (j=0;j<m;j++){
        for (i=1;i<n;i++){
            comb(&maxup[i][j][0], &maxup[i][j][1], &maxup[i-1][j][0], &maxup[i-1][j][1]);
        }
    }

    max=0;
    maxn=0;
    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            m1=0;
            m2=0;
            findup(i-2*r-1,j,&m1,&m2);
            finddo(i+2*r+1,j+1,&m1t,&m2t);
            comb(&m1,&m2,&m1t,&m2t);
            for (ii=max2ld(i-2*r,r),jj=j;ii<=i;ii++){
                while (!ncro(i, j, ii, jj)) {
                    jj++;
                }
                if (jj<m)
                    comb(&m1, &m2, &maxr[ii][jj][0], &maxr[ii][jj][1]);
            }
            for (;ii<=min2ld(i+2*r,n-r-1);ii++){
                while (ncro(i, j, ii, jj)) {
                    jj--;
                }
                jj++;
                if (jj<m)
                    comb(&m1, &m2, &maxr[ii][jj][0], &maxr[ii][jj][1]);
            }

            if (m2==0||m1==0){
                continue;
            }
            m1+=b[i][j];
            if (m1>max){
                max=m1;
                maxn=m2;
            }
            else if (m1==max){
                maxn+=m2;
            }
        }
    }
    printf("%I64d %I64d\n",max,maxn);
    return 0;
}


#include <stdio.h>
#include "math.h"

long a[600][600],maxup[600][600][2],maxdo[600][600][2],b[600][600],n,m,r;

long findup(long a,long b,long*m1,long*m2){
    if (a<0||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{

        if (a>=n){
            a=n-1;
        }
        if (b<0){
            b=0;
        }
        *m1=maxup[a][b][0];
        *m2=maxup[a][b][1];
    }
    return 0;
}

long finddo(long a,long b,long *m1,long *m2){
    if (a>=n||b>=m){
        *m1=0;
        *m2=0;
        return 0;
    }
    else{
        if (a<0){
            a=0;
        }
        if (b<0){
            b=0;
        }
        *m1=maxdo[a][b][0];
        *m2=maxdo[a][b][1];
    }
    return 0;
}

long comb(long *a,long *a1,long *b,long *b1){

    if (*b>*a){
        *a=*b;
        *a1=*b1;
    }
    else if (*b==*a){
        *a1+=*b1;
    }
    return 0;
}

long max2ld(long a,long b){
    if (a>b){
        return a;
    }
    return b;
}

long min2ld(long a,long b){
    if (a<b){
        return a;
    }
    return b;
}

int sdis(long x1,long y1,long x2,long y2){
    long d;
    d=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    if (d>(r*r)){
        return 0;
    }
    return 1;
}

int ncro(long x1,long y1,long x2,long y2){

    long mx,my;
    mx=(x1+x2)/2;
    my=(y1+y2)/2;

    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    my+=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    mx-=1;
    if (sdis(x1,y1,mx,my)&&sdis(x2,y2,mx,my)){
        return 0;
    }
    return 1;
}

int main(){

    long i,j,k,j1,ii,jj,m1,m2,m1t,m2t;
    long long max,maxn;

    scanf("%ld%ld%ld",&n,&m,&r);
    for (i=0;i<n;i++){
        for (j=0;j<m;j++){
            scanf("%ld",&a[i][j]);
            b[i][j]=0;
            maxdo[i][j][0]=0;
            maxdo[i][j][1]=0;
            maxup[i][j][0]=0;
            maxup[i][j][1]=0;
        }
    }
    for (i=1;i<n;i++){
        for (j=0;j<m;j++){
            a[i][j]+=a[i-1][j];
        }
    }

    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            for (k=j-r;k<=j+r;k++){
                j1=sqrt(r*r-(j-k)*(j-k));
                if ((i-j1-1)>=0)
                    b[i][j]+=a[i+j1][k]-a[i-j1-1][k];
                else
                    b[i][j]+=a[i+j1][k];
            }
        }
    }
    for (i=0;i<n;i++){
        maxup[i][m-1][0]=b[i][m-1];
        maxup[i][m-1][1]=1;
        for (j=m-2;j>=0;j--){
            if (b[i][j]>maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=1;
            }
            else if (b[i][j]==maxup[i][j+1][0]){
                maxup[i][j][0]=b[i][j];
                maxup[i][j][1]=maxup[i][j+1][1]+1;
            }
            else {
                maxup[i][j][0]=maxup[i][j+1][0];
                maxup[i][j][1]=maxup[i][j+1][1];
            }
        }
    }
    for (j=0;j<m;j++){
        maxdo[n-1][j][0]=maxup[n-1][j][0];
        maxdo[n-1][j][1]=maxup[n-1][j][1];
        for (i=n-2;i>=0;i--){
            if (maxup[i][j][0]>maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1];
            }
            else if (maxup[i][j][0]==maxdo[i+1][j][0]){
                maxdo[i][j][0]=maxup[i][j][0];
                maxdo[i][j][1]=maxup[i][j][1]+maxdo[i+1][j][1];
            }
            else {
                maxdo[i][j][0]=maxdo[i+1][j][0];
                maxdo[i][j][1]=maxdo[i+1][j][1];
            }
        }
    }
    for (j=0;j<m;j++){
        for (i=1;i<n;i++){
            comb(&maxup[i][j][0], &maxup[i][j][1], &maxup[i-1][j][0], &maxup[i-1][j][1]);
        }
    }

    max=0;
    maxn=0;
    for (i=r;i<(n-r);i++){
        for (j=r;j<(m-r);j++){
            if (r>0){
                m1=0;
                m2=0;
                findup(i-2*r-1,j,&m1,&m2);
                findup(i+2*r,j+2*r+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
                findup(i-2*r-1,j+2*r+1,&m1t,&m2t);
                if (m1t==m1){
                    m2-=m2t;
                }
                finddo(i+2*r+1,j+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
            }
            else {
                m1=0;
                m2=0;
                findup(i-1,j,&m1,&m2);
                findup(i,j+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
                findup(i-1,j+1,&m1t,&m2t);
                if (m1t==m1){
                    m2-=m2t;
                }
                finddo(i+1,j+1,&m1t,&m2t);
                comb(&m1,&m2,&m1t,&m2t);
            }

            for (ii=max2ld(i-2*r,r);ii<=min2ld(i+2*r,n-r-1);ii++){
                for (jj=min2ld(j+2*r,m-r-1);jj>j&&(ncro(i,j,ii,jj));jj--){
                    if (b[ii][jj]>m1){
                        m1=b[ii][jj];
                        m2=1;
                    }
                    else if (b[ii][jj]==m1){
                        m2++;
                    }
                }
            }
            if (m2==0||m1==0){
                continue;
            }
            m1+=b[i][j];
            if (m1>max){
                max=m1;
                maxn=m2;
            }
            else if (m1==max){
                maxn+=m2;
            }
        }
    }
    printf("%I64d %I64d\n",max,maxn);
    return 0;
}