Problem:
Problem D:
Awkward Lights
You are working as a night watchman in an office building. Your task is to check whether all the lights in the building are turned off after all the office workers in the building have left the office. If there are lights that are turned on, you must turn off those lights. This task is not as easy as it sounds to be because of the strange behavior of the lighting system of the building as described below. Although an electrical engineer checked the lighting system carefully, he could not determine the cause of this behavior. So you have no option but to continue to rely on this system for the time being.
Each floor in the building consists of a grid of square rooms. Every room is equipped with one light and one toggle switch. A toggle switch has two positions but they do not mean fixed ON/OFF. When the position of the toggle switch of a room is changed to the other position, in addition to that room, the ON/OFF states of the lights of the rooms at a certain Manhattan distance from that room are reversed. The Manhattan distance between the room at (
x
1
,
y
1
) of a grid of rooms and the room at (
x
2
,
y
2
) is given by |
x
1
-
x
2
| + |
y
1
-
y
2
|. For example, if the position of the toggle switch of the room at (2, 2) of a 4 × 4 grid of rooms is changed and the given Manhattan distance is two, the ON/OFF states of the lights of the rooms at (1, 1), (1, 3), (2, 4), (3, 1), (3, 3), and (4, 2) as well as at (2, 2) are reversed as shown in Figure D.1, where black and white squares represent the ON/OFF states of the lights.
Figure D.1: An example behavior of the lighting system
Your mission is to write a program that answer whether all the lights on a floor can be turned off.
Input
The input is a sequence of datasets. Each dataset is formatted as follows.
m n d
S
11
S
12
S
13
...
S
1
m
S
21
S
22
S
23
...
S
2
m
...
S
n
1
S
n
2
S
n
3
...
S
nm
The first line of a dataset contains three integers.
m
and
n
(1 ≤
m
≤ 25, 1 ≤
n
≤ 25) are the numbers of columns and rows of the grid, respectively.
d
(1 ≤
d
≤
m
+
n
) indicates the Manhattan distance. Subsequent n lines of m integers are the initial ON/OFF states. Each
S
ij
(1 ≤
i
≤
n
, 1 ≤
j
≤
m
) indicates the initial ON/OFF state of the light of the room at (
i
,
j
): '0' for OFF and '1' for ON.
The end of the input is indicated by a line containing three zeros.
Output
For each dataset, output '1' if all the lights can be turned off. If not, output '0'. In either case,
print it in one line for each input dataset.
Sample Input
1 1 1
1
2 2 1
1 1
1 1
3 2 1
1 0 1
0 1 0
3 3 1
1 0 1
0 1 0
1 0 1
4 4 2
1 1 0 1
0 0 0 1
1 0 1 1
1 0 0 0
5 5 1
1 1 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
5 5 2
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
11 11 3
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
1
...(truncated)

Submitted solutions:

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <string>
using namespace std;

const int MAXN = 1000;
int equ,var;
int a[MAXN][MAXN];
int x[MAXN];

int Gauss()
{
	int max_r,col,k;
	for(k = 0,col = 0;k < equ && col < var;k++,col++)
	{
		max_r = k;
		for(int i = k+1;i < equ;i++)
		{
			if(abs(a[i][col]) > abs(a[max_r][k]))
				max_r = i;
		}
		if(a[max_r][col] == 0)
		{
			k--;
			continue;
		}
		if(max_r != k)
		{
			for(int j = col;j < var+1;j++)
				swap(a[k][j],a[max_r][j]);
		}
		for(int i = k+1;i < equ;i++)
		{
			if(a[i][col] != 0)
			{
				for(int j = col;j < var+1;j++)
					a[i][j] ^= a[k][j];
			}
		}
	}
	for(int i = k;i < equ;i++)
		if(a[i][col] != 0)
			return -1;
	if(k < var)return var-k;
	return 0;
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int n,m,d;
	while(scanf("%d%d%d",&m,&n,&d) == 3)
	{
		if(n == 0 && m == 0 && d == 0)break;
		equ = var = n*m;
		memset(a,0,sizeof(a));
		for(int i = 0;i < n*m;i++)
			scanf("%d",&a[i][n*m]);
		for(int j = 0;j < n*m;j++)
		{
			a[j][j] = 1;
			int x = j/m;
			int y = j%m;
			for(int i= -d;i <= d;i++)
			{
				int xx = x+i;
				int yy = y - (d-abs(i));
				if(xx < 0 || xx >= n || yy < 0 || yy >= m)continue;
				a[xx*m + yy][j] = 1;
			}
			for(int i= -d;i <= d;i++)
			{
				int xx = x+i;
				int yy = y + (d-abs(i));
				if(xx < 0 || xx >= n || yy < 0 || yy >= m)continue;
				a[xx*m + yy][j] = 1;
			}
		}
		if(Gauss() >= 0)printf("1\n");
		else printf("0\n");
	}
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 7088
final_rank: 16

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=1000;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
//bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;
    bool free_x[MAXN];
    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = abs(a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if(((a[i][col]+2)%2)!= 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d))
    {
        if(n==0&&m==0&&d==0) break;
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]+=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 7308
final_rank: 17

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=1000;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
//bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;
    bool free_x[MAXN];
    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = abs(a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if(((a[i][col]+2)%2)!= 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d))
    {
        if(n==0&&m==0&&d==0) break;
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 7408
final_rank: 18

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=1000;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
//bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;
    bool free_x[MAXN];
    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = abs(a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if(((a[i][col]+2)%2)!= 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d)&&n)
    {
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 7404
final_rank: 19

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=900;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
//bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;
    bool free_x[MAXN];
    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = abs(a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if((a[i][col]%2)!= 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d)&&n)
    {
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 6416
final_rank: 12

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=900;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
//bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;
    bool free_x[MAXN];
    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = abs(a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if (a[i][col]!= 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d)&&n)
    {
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 6420
final_rank: 13

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=900;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
//bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;
    bool free_x[MAXN];
    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = (a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if (a[i][col] != 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d)&&n)
    {
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 6404
final_rank: 11

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;

const int MAXN=900;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{
    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;

    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = (a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }

  //  Debug();

    // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if (a[i][col] != 0) return -1;
    }
    return 0;
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d)&&n)
    {
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 6672
final_rank: 15

code_snippet: #include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
inline int Input(){
	int ret=0;bool isN=0;char c=getchar();
	while(c<'0' || c>'9'){
		if(c=='-') isN=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10+c-'0';
		c=getchar();
	}
	return isN?-ret:ret;
}

inline void Output(long long x){
    if(x<0){
        putchar('-');x=-x;
    }
    int len=0,data[20];
    while(x){
        data[len++]=x%10;x/=10;
    }
    if(!len)    data[len++]=0;
    while(len--)
        putchar(data[len]+48);
    putchar('\n');
}
#pragma comment(linker,"/STACK:124000000,124000000")
#include<map>
#include<vector>
#include<queue>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL<<60
using namespace std;
const int MAXN=900;



int a[MAXN][MAXN];//增广矩阵
int x[MAXN];//解集
bool free_x[MAXN];//标记是否是不确定的变元



/*
void Debug(void)
{
    int i, j;
    for (i = 0; i < equ; i++)
    {
        for (j = 0; j < var + 1; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}
*/


inline int gcd(int a,int b)
{
    int t;
    while(b!=0)
    {
        t=b;
        b=a%b;
        a=t;
    }
    return a;
}
inline int lcm(int a,int b)
{
    return a/gcd(a,b)*b;//先除后乘防溢出
}

// 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解，但无整数解，
//-1表示无解，0表示唯一解，大于0表示无穷解，并返回自由变元的个数)
//有equ个方程，var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ,int var)
{

    int i,j,k;
    int max_r;// 当前这列绝对值最大的行.
    int col;//当前处理的列
    int ta,tb;
    int LCM;
    int temp;
    int free_x_num;
    int free_index;

    for(int i=0;i<=var;i++)
    {
        x[i]=0;
        free_x[i]=true;
    }

    //转换为阶梯阵.
    col=0; // 当前处理的列
    for(k = 0;k < equ && col < var;k++,col++)
    {// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
        max_r=k;
        for(i=k+1;i<equ;i++)
        {
            if(abs(a[i][col])>abs(a[max_r][col])) max_r=i;
        }
        if(max_r!=k)
        {// 与第k行交换.
            for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]);
        }
        if(a[k][col]==0)
        {// 说明该col列第k行以下全是0了，则处理当前行的下一列.
            k--;
            continue;
        }
        for(i=k+1;i<equ;i++)
        {// 枚举要删去的行.
            if(a[i][col]!=0)
            {
                LCM = lcm(abs(a[i][col]),abs(a[k][col]));
                ta = LCM/abs(a[i][col]);
                tb = LCM/abs(a[k][col]);
                if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加
                for(j=col;j<var+1;j++)
                {
                    a[i][j] = (a[i][j]*ta-a[k][j]*tb)%2;
                }
            }
        }
    }
//    for(int i=0;i<equ;i++)
//        {
//            for(int j=0;j<=equ;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
//    Debug();
//
//     1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
//    printf("%d\n",k);
    for (i = k; i < equ; i++)
    { // 对于无穷解来说，如果要判断哪些是自由变元，那么初等行变换中的交换就会影响，则要记录交换.
        if (a[i][col] %2!= 0) return -1;
    }
    return 0;
//    for(int i=0;i<equ;i++)
//        printf("%d ",a[i][var]);
    // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行，即说明没有形成严格的上三角阵.
    // 且出现的行数即为自由变元的个数.
    if (k < var)
    {
        // 首先，自由变元有var - k个，即不确定的变元至少有var - k个.
        for (i = k - 1; i >= 0; i--)
        {
            // 第i行一定不会是(0, 0, ..., 0)的情况，因为这样的行是在第k行到第equ行.
            // 同样，第i行一定不会是(0, 0, ..., a), a != 0的情况，这样的无解的.
            free_x_num = 0; // 用于判断该行中的不确定的变元的个数，如果超过1个，则无法求解，它们仍然为不确定的变元.
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
            }
            if (free_x_num > 1) continue; // 无法求解出确定的变元.
            // 说明就只有一个不确定的变元free_index，那么可以求解出该变元，且该变元是确定的.
            temp = a[i][var];
            for (j = 0; j < var; j++)
            {
                if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j];
            }
            x[free_index] = temp / a[i][free_index]; // 求出该变元.
            free_x[free_index] = 0; // 该变元是确定的.
        }
        return var - k; // 自由变元有var - k个.
    }
    // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
    // 计算出Xn-1, Xn-2 ... X0.
    for (i = var - 1; i >= 0; i--)
    {
        temp = a[i][var];
        for (j = i + 1; j < var; j++)
        {
            if (a[i][j] != 0) temp -= a[i][j] * x[j];
        }
        if (temp % a[i][i] != 0) return -2; // 说明有浮点数解，但无整数解.
        x[i] = temp / a[i][i];
    }
    return 0;
}
int main()
{
    int n,m,d;
    while(scanf("%d%d%d",&m,&n,&d)&&n)
    {
        int t=n*m;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&a[i*m+j][t]);
            }
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                a[i*m+j][i*m+j]=1;
                for(int x=0;x<n;x++)
                {
                    for(int y=0;y<m;y++)
                    {
                        if(abs(x-i)+abs(y-j)==d)
                        {
                            a[i*m+j][x*m+y]=1;
                        }
                    }
                }
            }
        }
//        for(int i=0;i<t;i++)
//        {
//            for(int j=0;j<=t;j++)
//                printf("%d ",a[i][j]);
//            printf("\n");
//        }
        int ans=Gauss(t,t);
        if(ans>=0) printf("1\n");
        else printf("0\n");
//        for(int i=0;i<t;i++)
//            printf("%d ",x[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 6664
final_rank: 14

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,s,n) for(ll i = (ll)s;i < (ll)n;i++)
#define rrep(i,l,r) for(ll i = r-1;i >= l;i--)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}


// F_2係数 N×M行列 掃き出しO(N^2 M)
// これはAx = bを解くとき等はis = true．これにより最右列がrankの計算などに絡まないようにする．
// return {idx,rank}
pair<vector<int>,int> Gauss_Jordan(vector<vector<int>> &a,bool is = false){
  assert(!a.empty());
  int n = a.size(),m = a[0].size();
  // idx[j] = j列目に対応する元々の番号
  vector<int> idx(m);iota(idx.begin(),idx.end(),0);
  int rank = 0;
  for(int _ = 0;_ < n;_++){
    for(int i = _;i < n;i++)for(int j = _;j + is < m;j++){
      if(a[i][j]){
        swap(idx[_],idx[j]);
        for(int k = 0;k < n;k++)swap(a[k][_],a[k][j]);
        for(int k = 0;k < m;k++)swap(a[_][k],a[i][k]);
        rank++;
        goto kasu;
      }
    }
    kasu:
    if(rank != _ + 1)break;
    for(int i = 0;i < n;i++){
      if(i == _ || !a[i][_])continue;
      for(int j = 0;j < m;j++)a[i][j] = a[i][j] ^ a[_][j];
    }
  }
  // 必要ならばidxを参照することを忘れない
  // ex.) res[idx[i]] = hoge;等
  return {idx,rank};
};
// 時間が厳しいならbitset高速化

int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  while(1){
    int n,m,d;cin >> m >> n >> d;
    if(!n)break;
    vvi v(n,vi(m));cin >> v;
    vector<vector<int>> a(n*m,vector<int>(n*m + 1));
    rep(i,0,n)rep(j,0,m)if(v[i][j] == 1)a[i*m + j].back() = 1;
    rep(i,0,n)rep(j,0,m){
      a[i*m+j][i*m+j] = 1;
      rep(ni,0,n)rep(nj,0,m){
        if(abs(i-ni) + abs(j-nj) == d)a[i*m + j][ni*m + nj] = 1;
      }
    }
    auto [idx,rnk] = Gauss_Jordan(a,true);
    bool is = true;
    rep(i,rnk,n*m){
      if(a[i].back())is = false;
    }
    cout << is << "\n";
  }
  
  
  

  return 0;
}
accuracy: 1
time_ms: 600
memory_kb: 4596
final_rank: 10

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

const int MAX_ROW = 700; // to be set appropriately
const int MAX_COL = 700; // to be set appropriately
struct BitMatrix {
    int H, W;
    bitset<MAX_COL> val[MAX_ROW];
    BitMatrix(int m = 1, int n = 1) : H(m), W(n) {}
    inline bitset<MAX_COL>& operator [] (int i) {return val[i];}
};

int GaussJordan(BitMatrix &A, bool is_extended = false) {
    int rank = 0;
    for (int col = 0; col < A.W; ++col) {
        if (is_extended && col == A.W - 1) break;
        int pivot = -1;
        for (int row = rank; row < A.H; ++row) {
            if (A[row][col]) {
                pivot = row;
                break;
            }
        }
        if (pivot == -1) continue;
        swap(A[pivot], A[rank]);
        for (int row = 0; row < A.H; ++row) {
            if (row != rank && A[row][col]) A[row] ^= A[rank];
        }
        ++rank;
    }
    return rank;
}

int linear_equation(BitMatrix A, vector<int> b, vector<int> &res) {
    int m = A.H, n = A.W;
    BitMatrix M(m, n + 1);
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) M[i][j] = A[i][j];
        M[i][n] = b[i];
    }
    int rank = GaussJordan(M, true);

    // check if it has no solution
    for (int row = rank; row < m; ++row) if (M[row][n]) return -1;

    // answer
    res.assign(n, 0);
    for (int i = 0; i < rank; ++i) res[i] = M[i][n];
    return rank;
}

int solve(int w, int h, int d) {
    vector<vector<int>> s = in(h, w);

    BitMatrix A(h * w, h * w);
    for(int i : rep(h)) for(int j : rep(w)) {
        for(int x : rep(h)) for(int y : rep(w)) {
            if(abs(i - x) + abs(j - y) == d or make_pair(i, j) == make_pair(x, y)) {
                A[x * w + y][i * w + j] = 1;
            }
        }
    }

    vector<int> b(h * w, 0);
    for(int i : rep(h)) for(int j : rep(w)) {
        b[i * w + j] = s[i][j];
    }

    vector<int> res;
    return linear_equation(A, b, res) != -1;
}

int main() {
    while(true) {
        int w = in(), h = in(), d = in();
        if(make_tuple(w, h, d) == make_tuple(0, 0, 0)) return 0;
        cout << solve(w, h, d) << "\n";
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3580
final_rank: 2

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

const int MAX_ROW = 1000; // to be set appropriately
const int MAX_COL = 1000; // to be set appropriately
struct BitMatrix {
    int H, W;
    bitset<MAX_COL> val[MAX_ROW];
    BitMatrix(int m = 1, int n = 1) : H(m), W(n) {}
    inline bitset<MAX_COL>& operator [] (int i) {return val[i];}
};

int GaussJordan(BitMatrix &A, bool is_extended = false) {
    int rank = 0;
    for (int col = 0; col < A.W; ++col) {
        if (is_extended && col == A.W - 1) break;
        int pivot = -1;
        for (int row = rank; row < A.H; ++row) {
            if (A[row][col]) {
                pivot = row;
                break;
            }
        }
        if (pivot == -1) continue;
        swap(A[pivot], A[rank]);
        for (int row = 0; row < A.H; ++row) {
            if (row != rank && A[row][col]) A[row] ^= A[rank];
        }
        ++rank;
    }
    return rank;
}

int linear_equation(BitMatrix A, vector<int> b, vector<int> &res) {
    int m = A.H, n = A.W;
    BitMatrix M(m, n + 1);
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) M[i][j] = A[i][j];
        M[i][n] = b[i];
    }
    int rank = GaussJordan(M, true);

    // check if it has no solution
    for (int row = rank; row < m; ++row) if (M[row][n]) return -1;

    // answer
    res.assign(n, 0);
    for (int i = 0; i < rank; ++i) res[i] = M[i][n];
    return rank;
}

int solve(int w, int h, int d) {
    vector<vector<int>> s = in(h, w);

    BitMatrix A(h * w, h * w);
    for(int i : rep(h)) for(int j : rep(w)) {
        for(int x : rep(h)) for(int y : rep(w)) {
            if(abs(i - x) + abs(j - y) == d or make_pair(i, j) == make_pair(x, y)) {
                A[x * w + y][i * w + j] = 1;
            }
        }
    }

    vector<int> b(h * w, 0);
    for(int i : rep(h)) for(int j : rep(w)) {
        b[i * w + j] = s[i][j];
    }

    vector<int> res;
    return linear_equation(A, b, res) != -1;
}

int main() {
    while(true) {
        int w = in(), h = in(), d = in();
        if(make_tuple(w, h, d) == make_tuple(0, 0, 0)) return 0;
        cout << solve(w, h, d) << "\n";
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3732
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

template <class T> struct Matrix {
    int h, w;
    vector<vector<T>> val;
    T det;
    Matrix() {}
    Matrix(int n) : h(n), w(n), val(vector<vector<T>>(n, vector<T>(n))) {}
    Matrix(int n, int m)
        : h(n), w(m), val(vector<vector<T>>(n, vector<T>(m))) {}
    vector<T> &operator[](const int i) {
        return val[i];
    }
    Matrix &operator+=(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) val[i][j] += m.val[i][j];
        return *this;
    }
    Matrix &operator-=(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) val[i][j] -= m.val[i][j];
        return *this;
    }
    Matrix &operator*=(const Matrix &m) {
        assert(w == m.h);
        Matrix<T> res(h, m.w);
        rep(i, 0, h) rep(j, 0, m.w) rep(k, 0, w) res.val[i][j] +=
            val[i][k] * m.val[k][j];
        *this = res;
        return *this;
    }
    Matrix operator+(const Matrix &m) const {
        return Matrix(*this) += m;
    }
    Matrix operator-(const Matrix &m) const {
        return Matrix(*this) -= m;
    }
    Matrix operator*(const Matrix &m) const {
        return Matrix(*this) *= m;
    }
    Matrix pow(ll k) {
        Matrix<T> res(h, h), c = *this;
        rep(i, 0, h) res.val[i][i] = 1;
        while (k) {
            if (k & 1)
                res *= c;
            c *= c;
            k >>= 1;
        }
        return res;
    }
    vector<int> gauss(int c = -1) {
        det = 1;
        if (val.empty())
            return {};
        if (c == -1)
            c = w;
        int cur = 0;
        vector<int> res;
        rep(i, 0, c) {
            if (cur == h)
                break;
            rep(j, cur, h) if (val[j][i] != 0) {
                swap(val[cur], val[j]);
                if (cur != j)
                    det *= -1;
                break;
            }
            det *= val[cur][i];
            if (val[cur][i] == 0)
                continue;
            rep(j, 0, h) if (j != cur) {
                T z = val[j][i] / val[cur][i];
                rep(k, i, w) val[j][k] -= val[cur][k] * z;
            }
            res.push_back(i);
            cur++;
        }
        return res;
    }
    Matrix inv() {
        assert(h == w);
        Matrix base(h, h * 2), res(h, h);
        rep(i, 0, h) rep(j, 0, h) base[i][j] = val[i][j];
        rep(i, 0, h) base[i][h + i] = 1;
        base.gauss(h);
        det = base.det;
        rep(i, 0, h) rep(j, 0, h) res[i][j] = base[i][h + j] / base[i][i];
        return res;
    }
    bool operator==(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) if (val[i][j] != m.val[i][j]) return false;
        return true;
    }
    bool operator!=(const Matrix &m) {
        assert(h == m.h and w == m.w);
        rep(i, 0, h) rep(j, 0, w) if (val[i][j] == m.val[i][j]) return false;
        return true;
    }
    friend istream &operator>>(istream &is, Matrix &m) {
        rep(i, 0, m.h) rep(j, 0, m.w) is >> m[i][j];
        return is;
    }
    friend ostream &operator<<(ostream &os, Matrix &m) {
        rep(i, 0, m.h) {
            rep(j, 0, m.w) os << m[i][j]
                              << (j == m.w - 1 and i != m.h - 1 ? '\n' : ' ');
        }
        return os;
    }
};

/**
 * @brief Matrix
 */

template<typename T>pair<vector<T>,Matrix<T>> LinearEquation(Matrix<T> a,vector<T> b){
   int h=a.h,w=a.w;
   rep(i,0,h)a[i].push_back(b[i]);
   a.w++;
   vector<int> idx=a.gauss(w);
   rep(i,idx.size(),h)if(a[i][w]!=0)return {{},{}};
   vector<T> res(w);
   rep(i,0,idx.size())res[idx[i]]=a[i][w]/a[i][idx[i]];
   Matrix<T> d(w,h+w);
   rep(i,0,h)rep(j,0,w)d[j][i]=a[i][j];
   rep(i,0,w)d[i][h+i]=1;
   int r=d.gauss(h).size();
   Matrix<T> basis(w-r,w);
   rep(i,r,w)basis[i-r]={d[i].begin()+h,d[i].end()};
   return {res,basis};
}

/**
 * @brief Linear Equation
 */

using Fp = fp<2>;

int main() {
while(1) {
    int N, M, D;
    cin >> M >> N >> D;
    if (N == 0) return 0;
    int K = N*M;
    vector A(N,vector<int>(M));
    rep(i,0,N) rep(j,0,M) cin >> A[i][j];
    Matrix<Fp> X(K);
    rep(i,0,N) {
        rep(j,0,M) {
            X[i*M+j][i*M+j] = 1;
            rep(k,0,N) {
                rep(l,0,M) {
                    if (abs(i-k)+abs(j-l) == D) {
                        X[i*M+j][k*M+l] = 1;
                    }
                }
            }
        }
    }
    vector<Fp> Y(K);
    rep(i,0,N) rep(j,0,M) Y[i*M+j] = A[i][j];
    auto Ret = LinearEquation(X,Y);
    if (Ret.first.empty()) cout << 0 << endl;
    else cout << 1 << endl;
}
}
accuracy: 1
time_ms: 3480
memory_kb: 10920
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define each(e, x) for (auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template <typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }
TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }
TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main() {
    while (1) {
        int m, n, d;
        cin >> m >> n >> d;
        if (!m)
            break;
        vector<vector<int>> s(n, vector<int>(m));
        rep(i, n) rep(j, m) cin >> s[i][j];
        auto XOR = [&](vector<int> x, const vector<int> &y) {
            rep(i, n) x[i] ^= y[i];
            return x;
        };
        vector<vector<int>> xs;
        rep(i, n) rep(j, m) {
            vector<int> x(n, 0);
            x[i] |= 1 << j;
            rep(k, n) rep(l, m) if (abs(i - k) + abs(j - l) == d) x[k] |= 1 << l;
            each(y, xs) chmin(x, XOR(x, y));
            if (*max_element(all(x)) > 0)
                xs.eb(x);
        }
        vector<int> x(n, 0);
        rep(i, n) rep(j, m) x[i] |= s[i][j] << j;
        each(y, xs) chmin(x, XOR(x, y));
        cout << (*max_element(all(x)) > 0 ? 0 : 1) << '\n';
    }
}
accuracy: 1
time_ms: 210
memory_kb: 3496
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using pl = pair<ll,ll>;
using vp = vector<pl>;
#define rep(i,n) for(ll i=0;i<(ll)(n);++i)
#define reps(i,s,n) for(ll i=(s);i<(ll)(n);++i)
#define rep1(i,n) for(ll i=1;i<=(ll)(n);++i)
template<typename T>inline bool chmax(T &a,T b){return a<b?a=b,true:false;}
template<typename T>inline bool chmin(T &a,T b){return a>b?a=b,true:false;}
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define be(v) (v).begin(),(v).end()
const long long INF = 1e18;
#ifdef DEBUG
#include <debug.hpp>
random_device rd;
mt19937 gen(rd());
ll random(ll l,ll h){
	uniform_int_distribution<ll> dist(l,h);
	return dist(gen);
}
#endif

const int MAX_ROW = 25*25; // to be set appropriately
const int MAX_COL = 25*25; // to be set appropriately
struct BitMatrix {
	int H, W;
	bitset<MAX_COL> val[MAX_ROW];
	BitMatrix(int m = 1, int n = 1) : H(m), W(n) {}
	inline bitset<MAX_COL>& operator [] (int i) {return val[i];}
	void show(){
		rep(h,H)rep(w,W)cout<<val[h][w]<<" ";
		cout<<endl;
	}
};

int GaussJordan(BitMatrix &A, bool is_extended = false) {
	int rank = 0;
	for (int col = 0; col < A.W; ++col) {
		if (is_extended && col == A.W - 1) break;
		int pivot = -1;
		for (int row = rank; row < A.H; ++row) {
			if (A[row][col]) {
				pivot = row;
				break;
			}
		}
		if (pivot == -1) continue;
		swap(A[pivot], A[rank]);
		for (int row = 0; row < A.H; ++row) {
			if (row != rank && A[row][col]) A[row] ^= A[rank];
		}
		++rank;
	}
	return rank;
}

int linear_equation(BitMatrix A, vector<int> b, vector<int> &res) {
	int m = A.H, n = A.W;
	BitMatrix M(m, n + 1);
	for (int i = 0; i < m; ++i) {
		for (int j = 0; j < n; ++j) M[i][j] = A[i][j];
		M[i][n] = b[i];
	}
	int rank = GaussJordan(M, true);

	// check if it has no solution
	for (int row = rank; row < m; ++row) if (M[row][n]) return -1;

	// answer
	res.assign(n, 0);
	for (int i = 0; i < rank; ++i) res[i] = M[i][n];
	return rank;
}
ll M,N,D;
vector<int> B;
bool input(){
	cin>>M>>N>>D;
	if(M==0)return false;
	B.assign(N*M,0);
	rep(n,N*M){
		ll x;cin>>x;
		B.at(n) = x;
	}
	return true;
}
#ifdef DEBUG
void showall(){
	show(M,N,D,B);
}
#endif
vp manhattan(ll y,ll x,ll d){
	ll H=N,W=M;
	vp ret;
	reps(nx,x-d,x+d+1){
		for(ll j=-1;j<=1;j+=2){
			ll ny = y + j * (d - abs(nx - x));
			if(ny >= 0 && ny < H && nx >= 0 && nx < W){
				ret.eb(ny,nx);
			}
		}
	}
	return ret;
}
void logic(){
	BitMatrix A(N*M,N*M);
	rep(n,N)rep(m,M){
		A[n*M+m][n*M+m] = 1;
		for(auto e:manhattan(n,m,D)){
			A[n*M+m][e.fi*M+e.se] = 1;
		}
	}
	vector<int> res(N*M);
	ll rank = linear_equation(A,B,res);
	#ifdef DEBUG
	show("A");A.show();
	show("rank res",rank);show(res);
	#endif
	cout<< (rank>=0?1:0) <<endl;
}
#ifdef DEBUG
ll naive(){
	return 1;
}
#endif
int main(){
	while(input()){
	#ifdef DEBUG
		showall();
	#endif
		logic();
	}
	#ifdef DEBUG
	//show("naive=",naive());
	#endif
	#ifdef DEBUG
	/*
	rep(q,100){
		N=random(1LL,1000LL);
		ll lans=logic(),nans=naive();
		showall();
		if(lans!=nans){ show(" WA",lans,nans); break; }
		else{ show(" AC",lans,nans); }
	}
	*/
	#endif
	return 0;
}
//cout << fixed << setprecision(9);
accuracy: 1
time_ms: 50
memory_kb: 3488
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std ;
#define fast_io ios::sync_with_stdio(false); cin.tie(nullptr);
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
typedef long long ll ;
typedef long double ld ;
typedef pair<ll,ll> P ;
typedef tuple<ll,ll,ll> TP ;
#define chmin(a,b) a = min(a,b)
#define chmax(a,b) a = max(a,b)
#define bit_count(x) __builtin_popcountll(x)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a / gcd(a,b) * b
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define rrep(i,a,b) for(int i = a ; i < b ; i++)
#define repi(it,S) for(auto it = S.begin() ; it != S.end() ; it++)
#define pt(a) cout << a << endl
#define DEBUG(...) ; cout << #__VA_ARGS__ << endl ; for(auto x : {__VA_ARGS__}) cout << x << "  " ; cout << endl ;
#define DEBUG_LIST(...) cout << #__VA_ARGS__ << endl ; DEBUG_REP(__VA_ARGS__) ;
#define DEBUG_REP(V) cout << "{ " ; repi(itr,V) cout << *itr << ", " ; cout << "}" << endl ;
#define debug(a) cout << #a << " " << a << endl
#define all(a) a.begin(), a.end()
#define endl "\n"

template<int MAX_COL, typename T=bool> struct BitMatrix{

    private:
        int row, col;
        vector<bitset<MAX_COL>> mat;

        void init_(vector<vector<T>> A){
            row = A.size();
            col = A[0].size();
            mat.resize(row);
            for(int i = 0; i < row; i++){
                for(int j = 0; j < col; j++){
                    if(A[i][j] != 0) mat[i][j] = 1;
                    else mat[i][j] = 0;
                }
            }
        }
        
        void init_(vector<T> A, bool row_matrix = false){
            if(row_matrix) {
                col = (int)A.size();
                row = 1;
                mat.resize(1);
                for(int i = 0; i < col; i++){
                    if(A[i] != 0) mat[0][i] = 1;
                    else mat[0][i] = 0;
                }
            }
            else {
                col = 1;
                row = (int)A.size();
                mat.resize(row);
                for(int i = 0; i < row; i++){
                    if(A[i] != 0) mat[i][0] = 1;
                    else mat[i][0] = 0;
                }
            }
        }

        void transpose_() {
            vector<bitset<MAX_COL>> res(col);
            rep(i,row) rep(j,col) res[j][i] = mat[i][j];
            mat = res;
            swap(row,col);
        }
        
        void flip_() {
            rep(i,row) rep(j,col) mat[i][j].flip();
        }

        void concat_col_(vector<T> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(BitMatrix &Y) {
            assert((int)Y.row == row);
            rep(i,row) {
                rep(j,Y.col) mat[i][j+col] = (Y.mat[i][j]);
            }
            col += Y.col;
        }

        void concat_row_(vector<T> &Y) {
            BitMatrix X(Y,true);
            concat_row_(X);
        }
        void concat_row_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_row_(X);
        }
        void concat_row_(BitMatrix &Y) {
            assert((int)Y.col == col);
            row += Y.row;
            rep(i,Y.row) mat.push_back(Y.mat[i]);
        }

        void print_() {
            rep(i,row){
                rep(j,col) cout << mat[i][j]; cout << endl;
            }
        }

    public:

        inline BitMatrix &operator&=(const BitMatrix Y) {
            rep(i,row) mat[i] &= Y.mat[i];
            return *this ;
        }

        inline BitMatrix &operator|=(const BitMatrix Y) {
            rep(i,row) mat[i] |= Y.mat[i];
            return *this ;
        }
        
        inline BitMatrix &operator^=(const BitMatrix Y) {
            rep(i,row) mat[i] ^= Y.mat[i];
            return *this ;
        }

        inline BitMatrix operator&(const BitMatrix Y) const { return BitMatrix(*this) &= Y; }

        inline BitMatrix operator|(const BitMatrix Y) const { return BitMatrix(*this) |= Y; }

        inline BitMatrix operator^(const BitMatrix Y) const { return BitMatrix(*this) += Y; }

        inline bool operator==(const BitMatrix Y) const { return mat == Y.mat; }

        inline bool operator!=(const BitMatrix Y) const { return mat != Y.mat; }

        inline bitset<MAX_COL>&operator[] (int i) {return mat[i]; }

        BitMatrix(int n): row(n), col(0) { mat.resize(row); }
        BitMatrix(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        BitMatrix(vector<vector<T>> A){ init_(A); }
        void init(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        void init(vector<vector<T>> A) { init_(A); }
        size_t row_size() { return row; }
        size_t col_size() { return col; }
        void transpose() { transpose_(); }
        void flip() { flip_(); }
        void concat_col(vector<vector<T>> &Y) { concat_col_(Y); }
        void concat_col(vector<T> &Y) { concat_col_(Y); }
        void concat_col(BitMatrix &Y) { concat_col_(Y); }
        void concat_row(vector<vector<T>> &Y) { concat_row_(Y); }
        void concat_row(vector<T> &Y) { concat_row_(Y); }
        void concat_row(BitMatrix &Y) { concat_row_(Y); }
        void print() { print_(); }
};

const int MAX_COL = 2510;
using Matrix = BitMatrix<MAX_COL, bool>;

template<typename T=bool> struct GaussJordan{
    private:
        int rank;
        vector<bool> solution;

        int sweep_out_(Matrix &A , bool is_extended = false){
            rank = 0 ;
            for(int col = 0 ; col < A.col_size() ; col++){
                if(is_extended && col == A.col_size() - 1) break ;

                int pivot = -1 ;
                for(int row = rank ; row < A.col_size() ; row++){
                    if(A[row][col]){
                        pivot = row ;
                        break ;
                    }
                }

                if(pivot == -1) continue ;
                swap(A[pivot] , A[rank]) ;
                for(int row = 0 ; row < A.row_size() ; row++){
                    if(row != rank && A[row][col]) A[row] ^= A[rank] ;
                }
                rank++ ;
            }
            return rank ;
        }
        
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , vector<T> &b){
            Matrix X(A), Y(b);
            return solve_simultaneous_equation_(X, Y);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , vector<T> &b){
            Matrix Y(b);
            return solve_simultaneous_equation_(A, Y);
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , Matrix &b){
            Matrix X(A);
            return solve_simultaneous_equation_(X, b);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , Matrix &b){
            A.concat_col(b);
            return solve_simultaneous_equation_(A);
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A){
            return solve_simultaneous_equation_(to_matrix(A));
        }
        vector<bool> solve_simultaneous_equation_(Matrix &M){

            int n = M.row_size() , m = M.col_size();

            rank = sweep_out_(M,true);

            for(int row = rank ; row < n ; row++) if(M[row][n]) return {};

            vector<bool> res;
            res.resize(rank);
            for(int i = 0 ; i < rank; i++) res[i] = M[i][m];

            return solution = res;
        }

    public:
        GaussJordan(){}
        int sweep_out(Matrix &A) { return sweep_out_(A, false); }
        int sweep_out(Matrix &A, bool is_extended) { return sweep_out_(A, is_extended); }
        vector<bool> solve_simultaneous_equation(Matrix &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(Matrix &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A) { return solve_simultaneous_equation_(A); }
        vector<bool> solve_simultaneous_equation(Matrix A) { return solve_simultaneous_equation_(A); }
        int get_rank() { return rank; }
        vector<T> get_solution() { return solution; }
};

int n, m, d;
vector<vector<char>> S;
vector<vector<bool>> A;

bool solve(){
    S.clear();
    A.clear();
    cin >> m >> n >> d;
    if(m == 0 && n == 0 && d == 0) return false;
    S.resize(n, vector<char>(m));
    A.resize(n, vector<bool>(m));
    rep(i,n) rep(j,m) cin >> S[i][j], A[i][j] = S[i][j] - '0';
    vector<vector<bool>> M(n*m,vector<bool>(n*m+1,0));
    vector<bool> res(n*m);
    rep(i,n) rep(j,m){
        M[i*m+j][i*m+j] = 1;
        rep(x,n) rep(y,m){
            int dist = abs(i - x) + abs(j - y);
            if(dist == d) {
                M[i*m+j][x*m+y] = 1;
            }
        }
        if(!A[i][j]) M[i*m+j][n*m] = 1;
    }
    GaussJordan gj;

    auto ans = gj.solve_simultaneous_equation(Matrix(M));
    if(ans.empty()) cout << 0 << endl;
    else cout << 1 << endl;
    return 1;
}

int main(){
    fast_io
    while(1){
        if(!solve()) {
            return 0;
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3876
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std ;
#define fast_io ios::sync_with_stdio(false); cin.tie(nullptr);
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
typedef long long ll ;
typedef long double ld ;
typedef pair<ll,ll> P ;
typedef tuple<ll,ll,ll> TP ;
#define chmin(a,b) a = min(a,b)
#define chmax(a,b) a = max(a,b)
#define bit_count(x) __builtin_popcountll(x)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a / gcd(a,b) * b
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define rrep(i,a,b) for(int i = a ; i < b ; i++)
#define repi(it,S) for(auto it = S.begin() ; it != S.end() ; it++)
#define pt(a) cout << a << endl
#define DEBUG(...) ; cout << #__VA_ARGS__ << endl ; for(auto x : {__VA_ARGS__}) cout << x << "  " ; cout << endl ;
#define DEBUG_LIST(...) cout << #__VA_ARGS__ << endl ; DEBUG_REP(__VA_ARGS__) ;
#define DEBUG_REP(V) cout << "{ " ; repi(itr,V) cout << *itr << ", " ; cout << "}" << endl ;
#define debug(a) cout << #a << " " << a << endl
#define all(a) a.begin(), a.end()
#define endl "\n"

template<int MAX_COL, typename T=bool> struct BitMatrix{

    private:
        int row, col;
        vector<bitset<MAX_COL>> mat;

        void init_(vector<vector<T>> A){
            row = A.size();
            col = A[0].size();
            mat.resize(row);
            for(int i = 0; i < row; i++){
                for(int j = 0; j < col; j++){
                    if(A[i][j] != 0) mat[i][j] = 1;
                    else mat[i][j] = 0;
                }
            }
        }
        
        void init_(vector<T> A, bool row_matrix = false){
            if(row_matrix) {
                col = (int)A.size();
                row = 1;
                mat.resize(1);
                for(int i = 0; i < col; i++){
                    if(A[i] != 0) mat[0][i] = 1;
                    else mat[0][i] = 0;
                }
            }
            else {
                col = 1;
                row = (int)A.size();
                mat.resize(row);
                for(int i = 0; i < row; i++){
                    if(A[i] != 0) mat[i][0] = 1;
                    else mat[i][0] = 0;
                }
            }
        }

        void transpose_() {
            vector<bitset<MAX_COL>> res(col);
            rep(i,row) rep(j,col) res[j][i] = mat[i][j];
            mat = res;
            swap(row,col);
        }
        
        void flip_() {
            rep(i,row) rep(j,col) mat[i][j].flip();
        }

        void concat_col_(vector<T> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(BitMatrix &Y) {
            assert((int)Y.row == row);
            rep(i,row) {
                rep(j,Y.col) mat[i][j+col] = (Y.mat[i][j]);
            }
            col += Y.col;
        }

        void concat_row_(vector<T> &Y) {
            BitMatrix X(Y,true);
            concat_row_(X);
        }
        void concat_row_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_row_(X);
        }
        void concat_row_(BitMatrix &Y) {
            assert((int)Y.col == col);
            row += Y.row;
            rep(i,Y.row) mat.push_back(Y.mat[i]);
        }

        void print_() {
            rep(i,row){
                rep(j,col) cout << mat[i][j]; cout << endl;
            }
        }

    public:

        inline BitMatrix &operator&=(const BitMatrix Y) {
            rep(i,row) mat[i] &= Y.mat[i];
            return *this ;
        }

        inline BitMatrix &operator|=(const BitMatrix Y) {
            rep(i,row) mat[i] |= Y.mat[i];
            return *this ;
        }
        
        inline BitMatrix &operator^=(const BitMatrix Y) {
            rep(i,row) mat[i] ^= Y.mat[i];
            return *this ;
        }

        inline BitMatrix operator&(const BitMatrix Y) const { return BitMatrix(*this) &= Y; }

        inline BitMatrix operator|(const BitMatrix Y) const { return BitMatrix(*this) |= Y; }

        inline BitMatrix operator^(const BitMatrix Y) const { return BitMatrix(*this) += Y; }

        inline bool operator==(const BitMatrix Y) const { return mat == Y.mat; }

        inline bool operator!=(const BitMatrix Y) const { return mat != Y.mat; }

        inline bitset<MAX_COL>&operator[] (int i) {return mat[i]; }

        BitMatrix(int n): row(n), col(0) { mat.resize(row); }
        BitMatrix(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        BitMatrix(vector<vector<T>> A){ init_(A); }
        void init(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        void init(vector<vector<T>> A) { init_(A); }
        size_t row_size() { return row; }
        size_t col_size() { return col; }
        void transpose() { transpose_(); }
        void flip() { flip_(); }
        void concat_col(vector<vector<T>> &Y) { concat_col_(Y); }
        void concat_col(vector<T> &Y) { concat_col_(Y); }
        void concat_col(BitMatrix &Y) { concat_col_(Y); }
        void concat_row(vector<vector<T>> &Y) { concat_row_(Y); }
        void concat_row(vector<T> &Y) { concat_row_(Y); }
        void concat_row(BitMatrix &Y) { concat_row_(Y); }
        void print() { print_(); }
};

const int MAX_COL = 2510;
using Matrix = BitMatrix<MAX_COL, bool>;

template<typename T=bool> struct GaussJordan{
    private:
        int rank;
        vector<bool> solution;

        int sweep_out_(Matrix &A , bool is_extended = false){
            rank = 0 ;
            for(int col = 0 ; col < A.col_size() ; col++){
                if(is_extended && col == A.col_size() - 1) break ;

                int pivot = -1 ;
                for(int row = rank ; row < A.col_size() ; row++){
                    if(A[row][col]){
                        pivot = row ;
                        break ;
                    }
                }

                if(pivot == -1) continue ;
                swap(A[pivot] , A[rank]) ;
                for(int row = 0 ; row < A.row_size() ; row++){
                    if(row != rank && A[row][col]) A[row] ^= A[rank] ;
                }
                rank++ ;
            }
            return rank ;
        }
        
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , vector<T> &b){
            Matrix X(A), Y(b);
            return solve_simultaneous_equation_(X, Y);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , vector<T> &b){
            Matrix Y(b);
            return solve_simultaneous_equation_(A, Y);
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , Matrix &b){
            Matrix X(A);
            return solve_simultaneous_equation_(X, b);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , Matrix &b){
            A.concat_col(b);
            return solve_simultaneous_equation_(A);
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A){
            return solve_simultaneous_equation_(to_matrix(A));
        }
        vector<bool> solve_simultaneous_equation_(Matrix &M){

            int n = M.row_size() , m = M.col_size();

            rank = sweep_out_(M,true);

            for(int row = rank ; row < n ; row++) if(M[row][n]) return {};

            vector<bool> res;
            res.resize(rank);
            for(int i = 0 ; i < rank; i++) res[i] = M[i][m];

            return solution = res;
        }

    public:
        GaussJordan(){}
        int sweep_out(Matrix &A) { return sweep_out_(A, false); }
        int sweep_out(Matrix &A, bool is_extended) { return sweep_out_(A, is_extended); }
        vector<bool> solve_simultaneous_equation(Matrix &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(Matrix &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A) { return solve_simultaneous_equation_(A); }
        vector<bool> solve_simultaneous_equation(Matrix A) { return solve_simultaneous_equation_(A); }
        int get_rank() { return rank; }
        vector<T> get_solution() { return solution; }
};

int n, m, d;
vector<vector<char>> S;
vector<vector<bool>> A;

bool solve(){
    S.clear();
    A.clear();
    cin >> m >> n >> d;
    if(m == 0 && n == 0 && d == 0) return false;
    S.resize(n, vector<char>(m));
    A.resize(n, vector<bool>(m));
    rep(i,n) rep(j,m) cin >> S[i][j], A[i][j] = S[i][j] - '0';
    vector<vector<bool>> M(n*m,vector<bool>(n*m,0));
    vector<bool> res(n*m);
    rep(i,n) rep(j,m){
        M[i*m+j][i*m+j] = 1;
        rep(x,n) rep(y,m){
            int dist = abs(i - x) + abs(j - y);
            if(dist == d) {
                M[i*m+j][x*m+y] = 1;
            }
        }
        if(!A[i][j]) res[i*m+j] = 1;
    }
    GaussJordan gj;
    auto ans = gj.solve_simultaneous_equation(M,res);
    if(ans.empty()) cout << 0 << endl;
    else cout << 1 << endl;
    return 1;
}

int main(){
    fast_io
    while(1){
        if(!solve()) {
            return 0;
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3852
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std ;
#define fast_io ios::sync_with_stdio(false); cin.tie(nullptr);
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
typedef long long ll ;
typedef long double ld ;
typedef pair<ll,ll> P ;
typedef tuple<ll,ll,ll> TP ;
#define chmin(a,b) a = min(a,b)
#define chmax(a,b) a = max(a,b)
#define bit_count(x) __builtin_popcountll(x)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a / gcd(a,b) * b
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define rrep(i,a,b) for(int i = a ; i < b ; i++)
#define repi(it,S) for(auto it = S.begin() ; it != S.end() ; it++)
#define pt(a) cout << a << endl
#define DEBUG(...) ; cout << #__VA_ARGS__ << endl ; for(auto x : {__VA_ARGS__}) cout << x << "  " ; cout << endl ;
#define DEBUG_LIST(...) cout << #__VA_ARGS__ << endl ; DEBUG_REP(__VA_ARGS__) ;
#define DEBUG_REP(V) cout << "{ " ; repi(itr,V) cout << *itr << ", " ; cout << "}" << endl ;
#define debug(a) cout << #a << " " << a << endl
#define all(a) a.begin(), a.end()
#define endl "\n"

template<int MAX_COL, typename T=bool> struct BitMatrix{

    private:
        int row, col;
        vector<bitset<MAX_COL>> mat;

        void init_(vector<vector<T>> A){
            row = A.size();
            col = A[0].size();
            mat.resize(row);
            for(int i = 0; i < row; i++){
                for(int j = 0; j < col; j++){
                    if(A[i][j] != 0) mat[i][j] = 1;
                    else mat[i][j] = 0;
                }
            }
        }
        
        void init_(vector<T> A, bool row_matrix = false){
            if(row_matrix) {
                col = (int)A.size();
                row = 1;
                mat.resize(1);
                for(int i = 0; i < col; i++){
                    if(A[i] != 0) mat[0][i] = 1;
                    else mat[0][i] = 0;
                }
            }
            else {
                col = 1;
                row = (int)A.size();
                mat.resize(row);
                for(int i = 0; i < row; i++){
                    if(A[i] != 0) mat[i][0] = 1;
                    else mat[i][0] = 0;
                }
            }
        }

        void transpose_() {
            vector<bitset<MAX_COL>> res(col);
            rep(i,row) rep(j,col) res[j][i] = mat[i][j];
            mat = res;
            swap(row,col);
        }
        
        void flip_() {
            rep(i,row) rep(j,col) mat[i][j].flip();
        }

        void concat_col_(vector<T> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(BitMatrix &Y) {
            assert((int)Y.row == row);
            rep(i,row) {
                rep(j,Y.col) mat[i][j+col] = (Y.mat[i][j]);
            }
            col += Y.col;
        }

        void concat_row_(vector<T> &Y) {
            BitMatrix X(Y,true);
            concat_row_(X);
        }
        void concat_row_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_row_(X);
        }
        void concat_row_(BitMatrix &Y) {
            assert((int)Y.col == col);
            row += Y.row;
            rep(i,Y.row) mat.push_back(Y.mat[i]);
        }

        void print_() {
            rep(i,row){
                rep(j,col) cout << mat[i][j]; cout << endl;
            }
        }

    public:

        inline BitMatrix &operator&=(const BitMatrix Y) {
            rep(i,row) mat[i] &= Y.mat[i];
            return *this ;
        }

        inline BitMatrix &operator|=(const BitMatrix Y) {
            rep(i,row) mat[i] |= Y.mat[i];
            return *this ;
        }
        
        inline BitMatrix &operator^=(const BitMatrix Y) {
            rep(i,row) mat[i] ^= Y.mat[i];
            return *this ;
        }

        inline BitMatrix operator&(const BitMatrix Y) const { return BitMatrix(*this) &= Y; }

        inline BitMatrix operator|(const BitMatrix Y) const { return BitMatrix(*this) |= Y; }

        inline BitMatrix operator^(const BitMatrix Y) const { return BitMatrix(*this) += Y; }

        inline bool operator==(const BitMatrix Y) const { return mat == Y.mat; }

        inline bool operator!=(const BitMatrix Y) const { return mat != Y.mat; }

        inline bitset<MAX_COL>&operator[] (int i) {return mat[i]; }

        BitMatrix(int n): row(n), col(0) { mat.resize(row); }
        BitMatrix(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        BitMatrix(vector<vector<T>> A){ init_(A); }
        void init(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        void init(vector<vector<T>> A) { init_(A); }
        size_t row_size() { return row; }
        size_t col_size() { return col; }
        void transpose() { transpose_(); }
        void flip() { flip_(); }
        void concat_col(vector<vector<T>> &Y) { concat_col_(Y); }
        void concat_col(vector<T> &Y) { concat_col_(Y); }
        void concat_col(BitMatrix &Y) { concat_col_(Y); }
        void concat_row(vector<vector<T>> &Y) { concat_row_(Y); }
        void concat_row(vector<T> &Y) { concat_row_(Y); }
        void concat_row(BitMatrix &Y) { concat_row_(Y); }
        void print() { print_(); }
};

const int MAX_COL = 2510;
using Matrix = BitMatrix<MAX_COL, bool>;

template<typename T=bool> struct GaussJordan{
    private:
        int rank;
        vector<bool> solution;
    
        int sweep_out_(Matrix &A , bool is_extended = false){
            rank = 0 ;
            for(int col = 0 ; col < A.col_size() ; col++){
                if(is_extended && col == A.col_size() - 1) break ;

                int pivot = -1 ;
                for(int row = rank ; row < A.col_size() ; row++){
                    if(A[row][col]){
                        pivot = row ;
                        break ;
                    }
                }

                if(pivot == -1) continue ;
                swap(A[pivot] , A[rank]) ;
                for(int row = 0 ; row < A.row_size() ; row++){
                    if(row != rank && A[row][col]) A[row] ^= A[rank] ;
                }
                rank++ ;
            }
            return rank ;
        }
        
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , vector<T> &b){
            Matrix X(A), Y(b);
            return solve_simultaneous_equation_(X,Y);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , vector<T> &b){
            return solve_simultaneous_equation_(A, Matrix(b));
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , Matrix &b){
            return solve_simultaneous_equation_(Matrix(A), b);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , Matrix &b){
            A.concat_col(b);
            return solve_simultaneous_equation_(A);
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A){
            Matrix M(A);
            return solve_simultaneous_equation_(M);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &M){

            int n = M.row_size() , m = M.col_size();

            rank = sweep_out_(M,true);

            for(int row = rank ; row < n ; row++) if(M[row][n]) return {};

            vector<bool> res;
            res.resize(rank);
            for(int i = 0 ; i < rank; i++) res[i] = M[i][m];

            return solution = res;
        }

    public:
        GaussJordan(){}
        int sweep_out(Matrix &A) { return sweep_out_(A, false); }
        int sweep_out(Matrix &A, bool is_extended) { return sweep_out_(A, is_extended); }
        vector<bool> solve_simultaneous_equation(Matrix &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(Matrix &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A) { return solve_simultaneous_equation_(A); }
        vector<bool> solve_simultaneous_equation(Matrix A) { return solve_simultaneous_equation_(A); }
        int get_rank() { return rank; }
        vector<T> get_solution() { return solution; }
};

int n, m, d;
vector<vector<char>> S;
vector<vector<bool>> A;

bool solve(){
    S.clear();
    A.clear();
    cin >> m >> n >> d;
    if(m == 0 && n == 0 && d == 0) return false;
    S.resize(n, vector<char>(m));
    A.resize(n, vector<bool>(m));
    rep(i,n) rep(j,m) cin >> S[i][j], A[i][j] = S[i][j] - '0';
    vector<vector<bool>> M(n*m,vector<bool>(n*m,0));
    vector<bool> res(n*m);
    rep(i,n) rep(j,m){
        M[i*m+j][i*m+j] = 1;
        rep(x,n) rep(y,m){
            int dist = abs(i - x) + abs(j - y);
            if(dist == d) {
                M[i*m+j][x*m+y] = 1;
            }
        }
        if(!A[i][j]) res[i*m+j] = 1;
    }
    GaussJordan gj;
    auto ans = gj.solve_simultaneous_equation(M,res);
    if(ans.empty()) cout << 0 << endl;
    else cout << 1 << endl;
    return 1;
}

int main(){
    fast_io
    while(1){
        if(!solve()) {
            return 0;
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3748
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std ;
#define fast_io ios::sync_with_stdio(false); cin.tie(nullptr);
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
typedef long long ll ;
typedef long double ld ;
typedef pair<ll,ll> P ;
typedef tuple<ll,ll,ll> TP ;
#define chmin(a,b) a = min(a,b)
#define chmax(a,b) a = max(a,b)
#define bit_count(x) __builtin_popcountll(x)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a / gcd(a,b) * b
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define rrep(i,a,b) for(int i = a ; i < b ; i++)
#define repi(it,S) for(auto it = S.begin() ; it != S.end() ; it++)
#define pt(a) cout << a << endl
#define DEBUG(...) ; cout << #__VA_ARGS__ << endl ; for(auto x : {__VA_ARGS__}) cout << x << "  " ; cout << endl ;
#define DEBUG_LIST(...) cout << #__VA_ARGS__ << endl ; DEBUG_REP(__VA_ARGS__) ;
#define DEBUG_REP(V) cout << "{ " ; repi(itr,V) cout << *itr << ", " ; cout << "}" << endl ;
#define debug(a) cout << #a << " " << a << endl
#define all(a) a.begin(), a.end()
#define endl "\n"

template<int MAX_COL, typename T=bool> struct BitMatrix{

    private:
        int row, col;
        vector<bitset<MAX_COL>> mat;

        void init_(vector<vector<T>> A){
            row = A.size();
            col = A[0].size();
            mat.resize(row);
            for(int i = 0; i < row; i++){
                for(int j = 0; j < col; j++){
                    if(A[i][j] != 0) mat[i][j] = 1;
                    else mat[i][j] = 0;
                }
            }
        }
        
        void init_(vector<T> A, bool row_matrix = false){
            if(row_matrix) {
                col = (int)A.size();
                row = 1;
                mat.resize(1);
                for(int i = 0; i < col; i++){
                    if(A[i] != 0) mat[0][i] = 1;
                    else mat[0][i] = 0;
                }
            }
            else {
                col = 1;
                row = (int)A.size();
                mat.resize(row);
                for(int i = 0; i < row; i++){
                    if(A[i] != 0) mat[i][0] = 1;
                    else mat[i][0] = 0;
                }
            }
        }

        void transpose_() {
            vector<bitset<MAX_COL>> res(col);
            rep(i,row) rep(j,col) res[j][i] = mat[i][j];
            mat = res;
            swap(row,col);
        }
        
        void flip_() {
            rep(i,row) rep(j,col) mat[i][j].flip();
        }

        void concat_col_(vector<T> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(BitMatrix &Y) {
            assert((int)Y.row == row);
            rep(i,row) {
                rep(j,Y.col) mat[i][j+col] = (Y.mat[i][j]);
            }
            col += Y.col;
        }

        void concat_row_(vector<T> &Y) {
            BitMatrix X(Y,true);
            concat_row_(X);
        }
        void concat_row_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_row_(X);
        }
        void concat_row_(BitMatrix &Y) {
            assert((int)Y.col == col);
            row += Y.row;
            rep(i,Y.row) mat.push_back(Y.mat[i]);
        }

        void print_() {
            rep(i,row){
                rep(j,col) cout << mat[i][j]; cout << endl;
            }
        }

    public:

        inline BitMatrix &operator&=(const BitMatrix Y) {
            rep(i,row) mat[i] &= Y.mat[i];
            return *this ;
        }

        inline BitMatrix &operator|=(const BitMatrix Y) {
            rep(i,row) mat[i] |= Y.mat[i];
            return *this ;
        }
        
        inline BitMatrix &operator^=(const BitMatrix Y) {
            rep(i,row) mat[i] ^= Y.mat[i];
            return *this ;
        }

        inline BitMatrix operator&(const BitMatrix Y) const { return BitMatrix(*this) &= Y; }

        inline BitMatrix operator|(const BitMatrix Y) const { return BitMatrix(*this) |= Y; }

        inline BitMatrix operator^(const BitMatrix Y) const { return BitMatrix(*this) += Y; }

        inline bool operator==(const BitMatrix Y) const { return mat == Y.mat; }

        inline bool operator!=(const BitMatrix Y) const { return mat != Y.mat; }

        inline bitset<MAX_COL>&operator[] (int i) {return mat[i]; }

        BitMatrix(int n): row(n), col(0) { mat.resize(row); }
        BitMatrix(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        BitMatrix(vector<vector<T>> A){ init_(A); }
        void init(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        void init(vector<vector<T>> A) { init_(A); }
        size_t row_size() { return row; }
        size_t col_size() { return col; }
        void transpose() { transpose_(); }
        void flip() { flip_(); }
        void concat_col(vector<vector<T>> &Y) { concat_col_(Y); }
        void concat_col(vector<T> &Y) { concat_col_(Y); }
        void concat_col(BitMatrix &Y) { concat_col_(Y); }
        void concat_row(vector<vector<T>> &Y) { concat_row_(Y); }
        void concat_row(vector<T> &Y) { concat_row_(Y); }
        void concat_row(BitMatrix &Y) { concat_row_(Y); }
        void print() { print_(); }
};

const int MAX_COL = 2510;
using Matrix = BitMatrix<MAX_COL, bool>;

template<typename T=bool> struct GaussJordan{
    private:
        int rank;
        vector<bool> solution;
    
        int sweep_out_(Matrix &A , bool is_extended = false){
            rank = 0 ;
            for(int col = 0 ; col < A.col_size() ; col++){
                if(is_extended && col == A.col_size() - 1) break ;

                int pivot = -1 ;
                for(int row = rank ; row < A.col_size() ; row++){
                    if(A[row][col]){
                        pivot = row ;
                        break ;
                    }
                }

                if(pivot == -1) continue ;
                swap(A[pivot] , A[rank]) ;
                for(int row = 0 ; row < A.row_size() ; row++){
                    if(row != rank && A[row][col]) A[row] ^= A[rank] ;
                }
                rank++ ;
            }
            return rank ;
        }
        
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , vector<T> &b){
            return solve_simultaneous_equation_(Matrix(A), Matrix(b));
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , vector<T> &b){
            return solve_simultaneous_equation_(A, Matrix(b));
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , Matrix &b){
            return solve_simultaneous_equation_(Matrix(A), b);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , Matrix &b){
            return solve_simultaneous_equation_(A.concat_col(b));
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A){
            Matrix M(A);
            return solve_simultaneous_equation_(M);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &M){

            int n = M.row_size() , m = M.col_size();

            rank = sweep_out_(M,true);

            for(int row = rank ; row < n ; row++) if(M[row][n]) return {};

            vector<bool> res;
            res.resize(rank);
            for(int i = 0 ; i < rank; i++) res[i] = M[i][m];

            return solution = res;
        }

    public:
        GaussJordan(){}
        int sweep_out(Matrix &A) { return sweep_out_(A, false); }
        int sweep_out(Matrix &A, bool is_extended) { return sweep_out_(A, is_extended); }
        vector<bool> solve_simultaneous_equation(Matrix &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(Matrix &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A) { return solve_simultaneous_equation_(A); }
        vector<bool> solve_simultaneous_equation(Matrix A) { return solve_simultaneous_equation_(A); }
        int get_rank() { return rank; }
        vector<T> get_solution() { return solution; }
};

int n, m, d;
vector<vector<char>> S;
vector<vector<bool>> A;

bool solve(){
    S.clear();
    A.clear();
    cin >> m >> n >> d;
    if(m == 0 && n == 0 && d == 0) return false;
    S.resize(n, vector<char>(m));
    A.resize(n, vector<bool>(m));
    rep(i,n) rep(j,m) cin >> S[i][j], A[i][j] = S[i][j] - '0';
    vector<vector<bool>> M(n*m,vector<bool>(n*m+1,0));
    rep(i,n) rep(j,m){
        M[i*m+j][i*m+j] = 1;
        rep(x,n) rep(y,m){
            int dist = abs(i - x) + abs(j - y);
            if(dist == d) {
                M[i*m+j][x*m+y] = 1;
            }
        }
        if(!A[i][j]) M[i*m+j][n*m] = 1;
    }
    GaussJordan gj;
    auto res = gj.solve_simultaneous_equation(M);
    if(res.empty()) cout << 0 << endl;
    else cout << 1 << endl;
    return 1;
}

int main(){
    fast_io
    while(1){
        if(!solve()) {
            return 0;
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3828
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std ;
#define fast_io ios::sync_with_stdio(false); cin.tie(nullptr);
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
typedef long long ll ;
typedef long double ld ;
typedef pair<ll,ll> P ;
typedef tuple<ll,ll,ll> TP ;
#define chmin(a,b) a = min(a,b)
#define chmax(a,b) a = max(a,b)
#define bit_count(x) __builtin_popcountll(x)
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a / gcd(a,b) * b
#define rep(i,n) for(int i = 0 ; i < n ; i++)
#define rrep(i,a,b) for(int i = a ; i < b ; i++)
#define repi(it,S) for(auto it = S.begin() ; it != S.end() ; it++)
#define pt(a) cout << a << endl
#define DEBUG(...) ; cout << #__VA_ARGS__ << endl ; for(auto x : {__VA_ARGS__}) cout << x << "  " ; cout << endl ;
#define DEBUG_LIST(...) cout << #__VA_ARGS__ << endl ; DEBUG_REP(__VA_ARGS__) ;
#define DEBUG_REP(V) cout << "{ " ; repi(itr,V) cout << *itr << ", " ; cout << "}" << endl ;
#define debug(a) cout << #a << " " << a << endl
#define all(a) a.begin(), a.end()
#define endl "\n"

template<int MAX_COL, typename T=bool> struct BitMatrix{

    private:
        int row, col;
        vector<bitset<MAX_COL>> mat;

        void init_(vector<vector<T>> A){
            row = A.size();
            col = A[0].size();
            mat.resize(row);
            for(int i = 0; i < row; i++){
                for(int j = 0; j < col; j++){
                    if(A[i][j] != 0) mat[i][j] = 1;
                    else mat[i][j] = 0;
                }
            }
        }
        
        void init_(vector<T> A, bool row_matrix = false){
            if(row_matrix) {
                col = (int)A.size();
                row = 1;
                mat.resize(1);
                for(int i = 0; i < col; i++){
                    if(A[i] != 0) mat[0][i] = 1;
                    else mat[0][i] = 0;
                }
            }
            else {
                col = 1;
                row = (int)A.size();
                mat.resize(row);
                for(int i = 0; i < row; i++){
                    if(A[i] != 0) mat[i][0] = 1;
                    else mat[i][0] = 0;
                }
            }
        }

        void transpose_() {
            vector<bitset<MAX_COL>> res(col);
            rep(i,row) rep(j,col) res[j][i] = mat[i][j];
            mat = res;
            swap(row,col);
        }
        
        void flip_() {
            rep(i,row) rep(j,col) mat[i][j].flip();
        }

        void concat_col_(vector<T> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_col_(X);
        }
        void concat_col_(BitMatrix &Y) {
            assert((int)Y.row == row);
            rep(i,row) {
                rep(j,Y.col) mat[i][j+col] = (Y.mat[i][j]);
            }
            col += Y.col;
        }

        void concat_row_(vector<T> &Y) {
            BitMatrix X(Y,true);
            concat_row_(X);
        }
        void concat_row_(vector<vector<T>> &Y) {
            BitMatrix X(Y);
            concat_row_(X);
        }
        void concat_row_(BitMatrix &Y) {
            assert((int)Y.col == col);
            row += Y.row;
            rep(i,Y.row) mat.push_back(Y.mat[i]);
        }

        void print_() {
            rep(i,row){
                rep(j,col) cout << mat[i][j]; cout << endl;
            }
        }

    public:

        inline BitMatrix &operator&=(const BitMatrix Y) {
            rep(i,row) mat[i] &= Y.mat[i];
            return *this ;
        }

        inline BitMatrix &operator|=(const BitMatrix Y) {
            rep(i,row) mat[i] |= Y.mat[i];
            return *this ;
        }
        
        inline BitMatrix &operator^=(const BitMatrix Y) {
            rep(i,row) mat[i] ^= Y.mat[i];
            return *this ;
        }

        inline BitMatrix operator&(const BitMatrix Y) const { return BitMatrix(*this) &= Y; }

        inline BitMatrix operator|(const BitMatrix Y) const { return BitMatrix(*this) |= Y; }

        inline BitMatrix operator^(const BitMatrix Y) const { return BitMatrix(*this) += Y; }

        inline bool operator==(const BitMatrix Y) const { return mat == Y.mat; }

        inline bool operator!=(const BitMatrix Y) const { return mat != Y.mat; }

        inline bitset<MAX_COL>&operator[] (int i) {return mat[i]; }

        BitMatrix(int n): row(n), col(0) { mat.resize(row); }
        BitMatrix(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        BitMatrix(vector<vector<T>> A){ init_(A); }
        void init(vector<T> A, bool row_matrix = false) { init_(A, row_matrix); }
        void init(vector<vector<T>> A) { init_(A); }
        size_t row_size() { return row; }
        size_t col_size() { return col; }
        void transpose() { transpose_(); }
        void flip() { flip_(); }
        void concat_col(vector<vector<T>> &Y) { concat_col_(Y); }
        void concat_col(vector<T> &Y) { concat_col_(Y); }
        void concat_col(BitMatrix &Y) { concat_col_(Y); }
        void concat_row(vector<vector<T>> &Y) { concat_row_(Y); }
        void concat_row(vector<T> &Y) { concat_row_(Y); }
        void concat_row(BitMatrix &Y) { concat_row_(Y); }
        void print() { print_(); }
};

const int MAX_COL = 2510;
using Matrix = BitMatrix<MAX_COL, bool>;

template<typename T=bool> struct GaussJordan{
    private:
        int rank;
        vector<bool> solution;
    
        int sweep_out_(Matrix &A , bool is_extended = false){
            rank = 0 ;
            for(int col = 0 ; col < A.col_size() ; col++){
                if(is_extended && col == A.col_size() - 1) break ;

                int pivot = -1 ;
                for(int row = rank ; row < A.col_size() ; row++){
                    if(A[row][col]){
                        pivot = row ;
                        break ;
                    }
                }

                if(pivot == -1) continue ;
                swap(A[pivot] , A[rank]) ;
                for(int row = 0 ; row < A.row_size() ; row++){
                    if(row != rank && A[row][col]) A[row] ^= A[rank] ;
                }
                rank++ ;
            }
            return rank ;
        }
        
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , vector<T> &b){
            return solve_simultaneous_equation_(Matrix(A), Matrix(b));
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , vector<T> &b){
            return solve_simultaneous_equation_(A, Matrix(b));
        }
        vector<bool> solve_simultaneous_equation_(vector<vector<T>> &A , Matrix &b){
            return solve_simultaneous_equation_(Matrix(A), b);
        }
        vector<bool> solve_simultaneous_equation_(Matrix &A , Matrix &b){
            return solve_simultaneous_equation_(A.concat_col(b));
        }
        vector<bool> solve_simultaneous_equation_(Matrix &M){

            int n = M.row_size() , m = M.col_size();

            rank = sweep_out_(M,true);

            for(int row = rank ; row < n ; row++) if(M[row][n]) return {};

            vector<bool> res;
            res.resize(rank);
            for(int i = 0 ; i < rank; i++) res[i] = M[i][m];

            return solution = res;
        }

    public:
        GaussJordan(){}
        int sweep_out(Matrix &A) { return sweep_out_(A, false); }
        int sweep_out(Matrix &A, bool is_extended) { return sweep_out_(A, is_extended); }
        vector<bool> solve_simultaneous_equation(Matrix &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(Matrix &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , vector<T> &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(vector<vector<T>> &A , Matrix &b) { return solve_simultaneous_equation_(A, b); }
        vector<bool> solve_simultaneous_equation(Matrix A) { return solve_simultaneous_equation_(A); }
        int get_rank() { return rank; }
        vector<T> get_solution() { return solution; }
};

int n, m, d;
vector<vector<char>> S;
vector<vector<bool>> A;

bool solve(){
    S.clear();
    A.clear();
    cin >> m >> n >> d;
    if(m == 0 && n == 0 && d == 0) return false;
    S.resize(n, vector<char>(m));
    A.resize(n, vector<bool>(m));
    rep(i,n) rep(j,m) cin >> S[i][j], A[i][j] = S[i][j] - '0';
    vector<vector<bool>> M(n*m,vector<bool>(n*m+1,0));
    rep(i,n) rep(j,m){
        M[i*m+j][i*m+j] = 1;
        rep(x,n) rep(y,m){
            int dist = abs(i - x) + abs(j - y);
            if(dist == d) {
                M[i*m+j][x*m+y] = 1;
            }
        }
        if(!A[i][j]) M[i*m+j][n*m] = 1;
    }
    GaussJordan gj;
    auto res = gj.solve_simultaneous_equation(Matrix(M));
    if(res.empty()) cout << 0 << endl;
    else cout << 1 << endl;
    return 1;
}

int main(){
    fast_io
    while(1){
        if(!solve()) {
            return 0;
        }
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3632
final_rank: 3