/* -*- coding: utf-8 -*- * * 3596.cc: No.3596 Queen Score Attack 1 - yukicoder */ #include #include using namespace std; /* constant */ const int MAX_H = 100; const int MAX_W = 100; const int MAX_L = MAX_H + MAX_W - 1; const int INF = 1 << 30; /* typedef */ /* global variables */ int as[MAX_H][MAX_W]; int hs0[MAX_H], hs1[MAX_H], vs0[MAX_W], vs1[MAX_W]; int ds0[MAX_L], ds1[MAX_L], es0[MAX_L], es1[MAX_L]; /* subroutines */ /* main */ int main() { int tn; scanf("%d", &tn); while (tn--) { int h, w; scanf("%d%d", &h, &w); for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) scanf("%d", as[i] + j); int l = h + w - 1; fill(hs0, hs0 + h, -INF); fill(hs1, hs1 + h, -INF); fill(vs0, vs0 + w, -INF); fill(vs1, vs1 + w, -INF); fill(ds0, ds0 + l, -INF); fill(ds1, ds1 + l, -INF); fill(es0, es0 + l, -INF); fill(es1, es1 + l, -INF); for (int i = 0; i < h; i++) for (int j = 0; j < w; j++) { if (as[i][j] > hs0[i]) hs1[i] = hs0[i], hs0[i] = as[i][j]; else if (as[i][j] > hs1[i]) hs1[i] = as[i][j]; if (as[i][j] > vs0[j]) vs1[j] = vs0[j], vs0[j] = as[i][j]; else if (as[i][j] > vs1[j]) vs1[j] = as[i][j]; int dk = i + j; if (as[i][j] > ds0[dk]) ds1[dk] = ds0[dk], ds0[dk] = as[i][j]; else if (as[i][j] > ds1[dk]) ds1[dk] = as[i][j]; int ek = i + (w - 1 - j); if (as[i][j] > es0[ek]) es1[ek] = es0[ek], es0[ek] = as[i][j]; else if (as[i][j] > es1[ek]) es1[ek] = as[i][j]; } bool f = false; for (int i = 0; ! f && i < h; i++) for (int j = 0; ! f && j < w; j++) { int h = (as[i][j] != hs0[i]) ? hs0[i] : hs1[i]; if (as[i][j] + h > 0) { f = true; break; } int v = (as[i][j] != vs0[j]) ? vs0[j] : vs1[j]; if (as[i][j] + v > 0) { f = true; break; } int dk = i + j; int d = (as[i][j] != ds0[dk]) ? ds0[dk] : ds1[dk]; if (as[i][j] + d > 0) { f = true; break; } int ek = i + (w - 1 - j); int e = (as[i][j] != es0[ek]) ? es0[ek] : es1[ek]; if (as[i][j] + e > 0) { f = true; break; } } if (f) puts("infinite"); else puts("finite"); } return 0; }