Problem:
X-Ray Screening System
これは 20XX 年の話である．再生発電網による安定したエネルギー供給，および液化合成燃料の発明によって航空旅客数は鰻登りに増加した．しかし，航空機によるテロリズムの脅威は依然として存在するため，高速でかつ高い信頼性をもつ自動手荷物検査システムの重要性が高まっている．検査官が全部の荷物を調べることは実際問題として困難であることから，自動検査において疑わしいと判断された手荷物だけを検査官で改めて調べるという仕組みを整えたいわけである．
航空機業界からの要請を受け，国際客室保護会社（International Cabin Protection Company）では，新たな自動検査システムを開発するため，最近の旅客の手荷物について調査した．調査の結果，最近の旅客の手荷物には次のような傾向があることが判明した．
手荷物は 1 辺だけが短い直方体のような形状をしている．
一般の乗客が手荷物に詰めて航空機に持ち込む品物としてはノートパソコン，音楽プレイヤー，携帯ゲーム機，トランプなどがあり，これらはいずれも長方形である．
個々の品物は，その長方形の辺が手荷物の辺と平行になるように詰めこまれる．
一方，テロリズムに用いられるような武器は，長方形とは非常に異なる形状をもつ．
上記の調査結果をふまえて，以下のような手荷物検査のためのモデルを考案した．それぞれの手荷物は X 線に対して透明である直方体の容器だとみなす．その中には X 線に対して不透明である複数の品物が入っている．ここで，直方体の 3 辺を x 軸，y 軸，z 軸とする座標系を考え，x 軸と平行な方向に X 線を照射して，y-z 平面に投影された画像を撮影する．撮影された画像は適当な大きさの格子に分割され，画像解析によって，それぞれの格子領域に映っている品物の材質が推定される．この会社には非常に高度の解析技術があり，材質の詳細な違いすらも解析することが可能であることから，品物の材質は互いに異なると考えることができる．なお，複数の品物が x 軸方向に関して重なっているときは，それぞれの格子領域について最も手前にある，すなわち x 座標が最小である品物の材質が得られる．また，2 つ以上の品物の x 座標が等しいことはないと仮定する．
あなたの仕事は，画像解析の結果が与えられたときに，長方形ではない（武器であるかもしれない）品物が入っていることが断言できるか，あるいはその手荷物には長方形の品物以外のものは入っていないと推測されるかを判定するプログラムを作成することである．
Input
入力の先頭行には単一の正の整数が含まれ，これはデータセットの個数を表す．それぞれのデータセットは次の形式で与えられる．
H
W
解析結果その1
解析結果その2
...
解析結果その
H
H
は画像の縦の大きさ，
W
は横の大きさを表す整数である (1 <=
h
,
w
<= 50)．解析結果の各行は
W
文字で構成されており，
i
番目の文字は，行の左から
i
番目にある格子領域における解析結果を表す．物質が検出された格子領域については，その材質が英大文字（A〜Z）によって表される．このとき，同じ材質であれば同じ文字が，また異なる材質であれば異なる文字が用いられる．物質が検出されなかった格子領域についてはドット（.）で表される．
すべてのデータセットについて，材質の種類は 7 種類を超えないことが保証されている．
Output
それぞれのデータセットに対して，長方形以外の品物が確実に入っているときは「SUSPICIOUS」を，そうでないときは「SAFE」をそれぞれ 1 行に出力しなさい．
Sample Input
6
1 1
.
3 3
...
.W.
...
10 10
..........
.DDDDCCC..
.DDDDCCC..
.DDDDCCC..
ADDDDCCC..
AAA..CCC..
AAABBBBC..
AAABBBB...
..BBBBB...
..........
10 10
..........
.DDDDDD...
.DDDDCCC..
.DDDDCCC..
ADDDDCCC..
AAA..CCC..
AAABBBBC..
AAABBBB...
..BBBBB...
..........
10 10
R..E..C.T.
R.EEE.C.T.
.EEEEE....
EEEEEEE...
.EEEEEEE..
..EEEEEEE.
...EEEEEEE
....EEEEE.
.....EEE..
......E...
16 50
..................................................
.........AAAAAAAAAAAAAAAA.........................
....PPP...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.....
....PPP...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.....
....PPP...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....
....PPP..............AAAAA.AAAAAAAAAAAAAAAA.......
....PPP................A....AAA.AAAAAAAAAA........
....PPP...........IIIIIAAIIAIII.AAAAAAAAAA........
..CCCCCCCCCCCCC...IIIIIIAAAAAAAAAAAAAAAAAA........
..CCCCCCCCCCCCC...IIIIIIIIIIIII...AAAAAAAAAA......
....PPP............................AAAAAAAAAA.....
MMMMPPPMMMMMMMMMMMMMMM.............AAAAAAAAAAA....
MMMMPPPMMMMMMMMMMMMMMM..............AAAAAAAAAAA...
MMMMMMMMMMMMMMMMMMMMMM...............AAAAAAAAAA...
MMMMMMMMMMMMMMMMMMMMMM...............AAAAAAAAAA...
MMMMMMMMMMMMMMMMMMMMMM............................
Output for the Sample Input
SAFE
SAFE
SAFE
SUSPICIOUS
SUSPICIOUS
SUSPICIOUS

Submitted solutions:

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

int main()
{
	int N, H, W;
	cin >> N;
	while (N--) {
		cin >> H >> W;
		vector<int> used(26), xma(26), xmi(26, 100), yma(26), ymi(26, 100);
		vector<vector<char>> a(H, vector<char>(W));
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				cin >> a[i][j];
				if (a[i][j] != '.') {
					int p = a[i][j] - 'A';
					used[p] = 1;
					xma[p] = max(xma[p], i);
					xmi[p] = min(xmi[p], i);
					yma[p] = max(yma[p], j);
					ymi[p] = min(ymi[p], j);
				}
			}
		}
		vector<vector<int>> d(26, vector<int>(26, 1000));
		for (int i = 0; i < 26; i++) {
			d[i][i] = 0;
		}
		bool sus = false;
		for (int i = 0; i < 26; i++) {
			if (used[i]) {
				for (int x = xmi[i]; x <= xma[i]; x++) {
					for (int y = ymi[i]; y <= yma[i]; y++) {
						if (a[x][y] == '.') {
							sus = true;
						}
						else if (a[x][y] - 'A' != i) {
							d[i][a[x][y] - 'A'] = -1;
						}
					}
				}
			}
		}
		for (int k = 0; k < 26; k++) {
			for (int i = 0; i < 26; i++) {
				for (int j = 0; j < 26; j++) {
					d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
				}
			}
		}
		for (int i = 0; i < 26; i++) {
			if (d[i][i] < 0) {
				sus = true;
				break;
			}
		}
		cout << (sus ? "SUSPICIOUS" : "SAFE") << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3352
final_rank: 6

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

int main()
{
	int N, H, W;
	cin >> N;
	while (N--) {
		cin >> H >> W;
		vector<int> used(26), xma(26), xmi(26, 100), yma(26), ymi(26, 100);
		vector<vector<char>> a(H, vector<char>(W));
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				cin >> a[i][j];
				if (a[i][j] != '.') {
					int p = a[i][j] - 'A';
					used[p] = 1;
					xma[p] = max(xma[p], i);
					xmi[p] = min(xmi[p], i);
					yma[p] = max(yma[p], j);
					ymi[p] = min(ymi[p], j);
				}
			}
		}
		vector<vector<int>> d(26, vector<int>(26, 1000));
		for (int i = 0; i < 26; i++) {
			d[i][i] = 0;
		}
		bool sus = false;
		for (int i = 0; i < 26; i++) {
			if (used[i]) {
				for (int x = xmi[i]; x <= xma[i]; x++) {
					for (int y = ymi[i]; y <= yma[i]; y++) {
						if (a[x][y] == '.') {
							sus = true;
						}
						else if (a[x][y] - 'A' != i) {
							d[i][a[x][y] - 'A'] = -1;
						}
					}
				}
			}
		}
		for (int k = 0; k < 26; k++) {
			for (int i = 0; i < 26; i++) {
				for (int j = 0; j < 26; j++) {
					d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
				}
			}
		}
		for (int i = 0; i < 26; i++) {
			if (d[i][i] < 0) {
				sus = true;
				break;
			}
		}
		cout << (sus ? "SUSPICIOUS" : "SAFE") << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3164
final_rank: 2

code_snippet: #line 1 "2006JAGC.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2006JAGC.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(...)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

ll dx[] = {1, 0, -1, 0, -1, 1, -1, 1};
ll dy[] = {0, 1, 0, -1, -1, 1, 1, -1};

int n = 26;
int solve(){
    int h, w; cin >> h >> w;
    vector<string> s(h); rep(i,h) cin >> s[i];

    auto checker = [&](char c) -> vll {
        // 上に被っているものの配列を返す
        ll l=inf, r=-1, u=inf, d=-1;
        rep(i,h) {
            rep(j,w) {
                if(s[i][j] == c) {
                    chmin(l,j);
                    chmax(r,j);
                    chmin(u,i);
                    chmax(d,i);
                }
            }
        }
        if(l==inf) return {};

        vll res;
        rep2(i,u,d+1) {
            rep2(j,l,r+1) {
                if(s[i][j] == '.') return {-1}; // 構成不可能なときはこれ
                else if(s[i][j] != c) res.emplace_back(s[i][j] - 'A');
            }
        }
        sort(all(res));
        res.erase(unique(all(res)),res.end());
        return res;
    };

    vvll g(n);
    vll ins(n,0);

    rep(i,n) {
        g[i] = checker('A'+i);
        dbg(i, g[i]);
        if(g[i].size()>0 && g[i][0]==-1) return 1;
        for(auto ni: g[i]) ins[ni]++;
    }

    queue<int> que;
    vector<bool> seen(26,false);
    rep(i,n) {
        if(ins[i] == 0) {
            que.push(i);
            seen[i] = true;
        }
    }
    while(!que.empty()) {
        auto p = que.front();
        que.pop();
        for(auto ni: g[p]) {
            if(--ins[ni] == 0) {
                seen[ni] = true;
                que.push(ni);
            }
        }
    }

    bool all_seen = true;
    rep(i,n) all_seen = all_seen && seen[i];
    return !all_seen;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int t; cin >> t;
    while(t--) {
        // 0ならsafe
        if(solve()==0) {
            cout << "SAFE\n";
        } else {
            cout << "SUSPICIOUS\n";
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3396
final_rank: 10

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

void solve() {
    const int N = 26;
    int H, W;
    cin >> H >> W;
    vector<string> S(H);
    for (int i = 0; i < H; i++) cin >> S[i];
    for (bool fn = true; fn; ) {
        fn = false;
        vector<int> lh(N, H + 1), rh(N, -1), lw(N, W + 1), rw(N, -1);
        vector<int> cnt(26);
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (S[i][j] == '.' || S[i][j] == '#') continue;
                int p = S[i][j] - 'A';
                lh[p] = min(lh[p], i);
                rh[p] = max(rh[p], i + 1);
                lw[p] = min(lw[p], j);
                rw[p] = max(rw[p], j + 1);
                cnt[p]++;
            }
        }
        vector<int> del;
        for (int p = 0; p < 26; p++) {
            if (cnt[p]) {
                bool ok = true;
                for (int i = lh[p]; i < rh[p]; i++) {
                    for (int j = lw[p]; j < rw[p]; j++) {
                        if (S[i][j] != '#' && S[i][j] - 'A' != p) ok = false;
                    }
                }
                if (ok) del.push_back(p);
            }
        }
        fn = del.size();
        for (int p : del) {
            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    if (S[i][j] - 'A' == p) S[i][j] = '#';
                }
            }
        }
    }
    string ans = "SAFE";
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (S[i][j] != '.' && S[i][j] != '#') ans = "SUSPICIOUS";
        }
    }
    cout << ans << '\n';
}

int main() {
    int T;
    cin >> T;
    while (T--) solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3456
final_rank: 12

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

bool solve();
int main() {
  int T;
  cin >> T;
  while (T--) solve();
  return 0;
}

bool solve() {
  int H, W;
  cin >> H >> W;

  vector<string> S(H);
  string z = "";
  vector<int> lx, ly, rx, ry;
  for (int i = 0; i < H; i++) {
    cin >> S[i];
    for (int j = 0; j < W; j++) {
      if (S[i][j] != '.') {
        int k = z.find(S[i][j]);
        if (k == z.npos) {
          z.push_back(S[i][j]);
          lx.push_back(j);
          rx.push_back(j);
          ly.push_back(i);
          ry.push_back(i);
        } else {
          lx[k] = min(lx[k], j);
          rx[k] = max(rx[k], j);
          ly[k] = min(ly[k], i);
          ry[k] = max(ry[k], i);
        }
      }
    }
  }

  // n!
  int N = int(z.size());
  vector<int> order(N);
  iota(order.begin(), order.end(), 0);
  bool ans = false;

  do {
    vector<string> T(H, string(W, '.'));
    for (int kk = 0; kk < N; kk++) {
      int k = order[kk];
      for (int i = ly[k]; i <= ry[k]; i++) {
        for (int j = lx[k]; j <= rx[k]; j++) {
          T[i][j] = z[k];
        }
      }
    }
    if (S == T) {
      ans = true;
      break;
    }
  } while (next_permutation(order.begin(), order.end()));
  cout << (ans ? "SAFE" : "SUSPICIOUS") << endl;
  return true;
}
accuracy: 1
time_ms: 860
memory_kb: 3456
final_rank: 15

code_snippet: #include<iostream>
#include<algorithm>
#include<set>
#include<vector>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int T;cin>>T;
	for(;T--;)
	{
		int H,W;cin>>H>>W;
		vector<string>S(H);
		set<char>c;
		for(int i=0;i<H;i++)
		{
			cin>>S[i];
			for(int j=0;j<W;j++)if(S[i][j]!='.')c.insert(S[i][j]);
		}
		if(c.size()==0)
		{
			cout<<"SAFE"<<endl;
			continue;
		}
		vector<char>p;
		for(auto e:c)p.push_back(e);
		// 図形の幅を見る
		vector<int>mnx(256,1e9),mny(256,1e9),mxx(256,0),mxy(256,0);
		for(int i=0;i<p.size();i++)for(int x=0;x<H;x++)for(int y=0;y<W;y++)
		{
			if(S[x][y]==p[i])
			{
				mnx[p[i]]=min(mnx[p[i]],x),mny[p[i]]=min(mny[p[i]],y);
				mxx[p[i]]=max(mxx[p[i]],x),mxy[p[i]]=max(mxy[p[i]],y);
			}
		}
		bool safe=false;
		do{
			vector<vector<bool> >vis(H,vector<bool>(W));
			bool ok=true;
			for(int i=0;i<p.size();i++)
			{
				// 埋められるか見る
				for(int x=mnx[p[i]];x<=mxx[p[i]];x++)for(int y=mny[p[i]];y<=mxy[p[i]];y++)
				{
					if(S[x][y]!=p[i])
					{
						if(!vis[x][y]||S[x][y]=='.')ok=false;
					}
					else vis[x][y]=true;
				}
			}
			if(ok)
			{
				safe=true;
				break;
			}
		}while(next_permutation(p.begin(),p.end()));
		cout<<(safe?"SAFE":"SUSPICIOUS")<<endl;
	}
}
accuracy: 1
time_ms: 2560
memory_kb: 3484
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define vi vector<int>
#define vl vector<long long>
#define pii pair<int, int>
#define pll pair<long long, long long>
#define elif else if
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(v) (v).begin(), (v).end()
#define rall(x) x.rbegin(), x.rend()
#define el '\n'
#define Yes cout << "Yes" << el
#define No cout << "No" << el
#define YES cout << "YES" << el
#define NO cout << "NO" << el
const double pi = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";
const int MOD = 998244353;
const array<int, 8> dx = {0, 0, -1, 1, -1, -1, 1, 1};
const array<int, 8> dy = {-1, 1, 0, 0, -1, 1, -1, 1};
template <typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) {
    bool compare = a < b;
    if (compare) a = b;
    return compare;
}
template <typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) {
    bool compare = a > b;
    if (compare) a = b;
    return compare;
}
template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, std::pair<T1, T2> p) {
    os << "{" << p.first << "," << p.second << "}";
    return os;
}
template <typename T>
inline void print_vec(const vector<T> &v, bool split_line = false) {
    if (v.empty()) {
        cout << "This vector is empty." << el;
        return;
    }
    constexpr bool isValue = is_integral<T>::value;
    for (int i = 0; i < (int)v.size(); i++) {
        if constexpr (isValue) {
            if ((v[i] == inf) || (v[i] == infl))
                cout << 'x' << " \n"[split_line || i + 1 == (int)v.size()];
            else
                cout << v[i] << " \n"[split_line || i + 1 == (int)v.size()];
        } else
            cout << v[i] << " \n"[split_line || i + 1 == (int)v.size()];
    }
}
template <typename T>
void vin(vector<T> &v) {
    for (auto &element : v) {
        cin >> element;
    }
}
template <typename T>
T mod_pow(T x, T n, const T &p) {
    T ret = 1;
    while (n > 0) {
        if (n & 1) (ret *= x) %= p;
        (x *= x) %= p;
        n >>= 1;
    }
    return ret;
}
template <typename T>
T ipow(T x, T n) {
    T ret = 1;
    while (n > 0) {
        if (n & 1) ret *= x;
        x *= x;
        n >>= 1;
    }
    return ret;
}
string solve(int h, int w, vector<string> s) {
    map<char, pii> minmax_x;
    map<char, pii> minmax_y;
    rep(i, h) {
        rep(j, w) {
            if (s[i][j] == '.') {
                continue;
            }
            if (minmax_x.find(s[i][j]) == minmax_x.end()) {
                minmax_x[s[i][j]] = make_pair(inf, -inf);
                minmax_y[s[i][j]] = make_pair(inf, -inf);
            }
            chmin(minmax_x[s[i][j]].first, i);
            chmax(minmax_x[s[i][j]].second, i);
            chmin(minmax_y[s[i][j]].first, j);
            chmax(minmax_y[s[i][j]].second, j);
        }
    }
    vector<pair<char, char>> more_big;
    vector<char> per;

    for (auto k : minmax_x) {
        // cout << k << el;
        per.push_back(k.first);
        for (int i = k.second.first; i <= k.second.second; i++) {
            for (int j = minmax_y[k.first].first; j <= minmax_y[k.first].second;
                 j++) {
                if (s[i][j] == '.') {
                    return "SUSPICIOUS";
                } else if (s[i][j] != k.first) {
                    more_big.push_back(make_pair(k.first, s[i][j]));
                }
            }
        }
    }

    sort(all(per));
    string result = "SUSPICIOUS";
    // print_vec(per);
    // print_vec(more_big);

    while (1) {
        bool ok = true;
        for (auto ij : more_big) {
            if (find(all(per), ij.first) < find(all(per), ij.second)) {
            } else {
                ok = false;
            }
        }
        if (ok) {
            result = "SAFE";
            break;
        }
        if (not next_permutation(all(per))) {
            break;
        }
    }

    return result;
}
int main() {
    int t;
    cin >> t;
    rep(i, t) {
        int h, w;
        cin >> h >> w;
        vector<string> s(h);
        rep(i, h) { cin >> s[i]; }
        cout << solve(h, w, s) << el;
        // set<char> tmp;
        // rep(i, h) {
        //     rep(j, w) {
        //         if (s[i][j] == '.') {
        //             tmp.insert(s[i][j]);
        //         }
        //     }
        // }
    }
    // to do
}
accuracy: 1
time_ms: 650
memory_kb: 3456
final_rank: 14

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


using namespace std;
//make -f ../makefile SRC=
/*
input top view of rect and non-rect objects
some rects may be partly masked by other
test 3:
D -> A -> B -> C => SAFE
D -> A -> B -> C -> D => SUSPICIOUS

SUSPICIOUS due to
1. cycle
2. non-rect obj
*/


//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 1000000000;

const int MAX_N = 60;
const char FREE = '.';
static char grid[MAX_N][MAX_N];

const int MAX_K = 26;
const int LETTER = 26;
static bool visited[MAX_K];
static int rec_stack[MAX_K];
typedef vector<vector<int> > Graph;

//------------------------------------------------------------------------------
bool cyclic_recursive(int N, Graph& G, int v)
{
    if (!visited[v])
    {
        visited[v] = true;
        rec_stack[v] = true;
        for (int w: G[v])
        {
            if (!visited[w] && cyclic_recursive(N, G, w)) return true;
            else if (rec_stack[w]) return true;
        }
    }
    rec_stack[v] = false;
    return false;
}

bool cyclic(int N, Graph& G)
{
    for (int v=0; v<N; ++v) { visited[v] = false; rec_stack[v] = false; }

    for (int v=0; v<N; ++v)
    {
        if (visited[v]) continue;
        else if (cyclic_recursive(N, G, v)) return true;
    }

    return false;
}

void debug_graph(int N, Graph& G)
{
    for (int v=0; v<N; v++)
    {
        printf("%d: ", v); for (int w: G[v]) printf("%d ", w);  printf("\n");
    }

}
//------------------------------------------------------------------------------
// bounding box
struct BBox
{
    char c;
    int m1, n1, m2, n2;
    BBox(): c('?'), m1(0), n1(0), m2(0), n2(0) {}
    BBox(char m, int a, int b, int c, int d): c(m), m1(a), n1(b), m2(c), n2(d) {}
    bool is_rect()
    {
        for (int m=m1; m<=m2; ++m)
            for (int n=n1; n<=n2; ++n)
                if (grid[m][n] == FREE)
                    return false;
        return true;
    }
    void debug() const { printf("%c: (%d,%d), (%d,%d)\n", c, m1, n1, m2, n2); }
};

typedef vector<BBox> BBoxes;
//------------------------------------------------------------------------------
BBox setup_bb(int M, int N, char c)
{
    int m1 = INF;
    int m2 = -INF;
    int n1 = INF;
    int n2 = -INF;
    for (int m=0; m<M; ++m)
        for (int n=0; n<N; ++n)
            if (grid[m][n] == c)
                {
                    m1 = min(m1, m);
                    m2 = max(m2, m);
                    n1 = min(n1, n);
                    n2 = max(n2, n);
                }
    return BBox(c, m1, n1, m2, n2);
}
Graph setup_graph(int M, int N, map<char,int>& to_rect, int K, const BBoxes& BB)
{
    Graph G(K);
    for (BBox B: BB)
    {
        set<int> vs;
        for (int m=B.m1; m<=B.m2; ++m)
            for (int n=B.n1; n<=B.n2; ++n)
                if (grid[m][n] != B.c)
                    vs.insert(to_rect[grid[m][n]]);
        int w = to_rect[B.c];
        for (int v: vs) G[v].push_back(w);
    }
    return G;
}
bool solve(int M, int N)
{
    //--------------------------------------------------------------------------
    // base cases:
    //--------------------------------------------------------------------------
    // init:
    vector<bool> marked(LETTER,false);
    for (int m=0; m<M; ++m)
        for (int i=0; i<N; ++i)
            if (grid[m][i] != FREE)
                marked[ grid[m][i]-'A' ] = true;

    vector<char> items;
    for (int c=0; c<LETTER; ++c)
        if (marked[c])
            items.push_back( c + 'A' );
    int K = items.size();
    if (K == 0) return true;
    //--------------------------------------------------------------------------
    // compute:
    map<char,int> to_rect;
    BBoxes BB(K);
    for (int k=0; k<K; ++k)
    {
        BB[k] = setup_bb(M, N, items[k]);
        if (DEBUG) BB[k].debug();

        if (!BB[k].is_rect()) return false;
        to_rect[items[k]] = k;
    }

    Graph G = setup_graph(M, N, to_rect, K, BB);
    if (DEBUG) debug_graph(K, G);
    if (cyclic(K, G))
    {
        if (DEBUG) printf("cyclic\n");
        return false;
    }
    return true;
}

//------------------------------------------------------------------------------
void test()
{

}

//------------------------------------------------------------------------------
int main()
{
    //test(); return 0;
    //DEBUG = true;
    //--------------------------------------------------------------------------
    /*
    int T, M, N, num;
    char c;
    cin >> T;
    while (T--)
    {
        cin >> M >> N;
        if (DEBUG) printf("M=%d, N=%d\n", M, N);
        for (int m=0; m<M; ++m)
        {
            for (int i=0; i<N; ++i)
            {
                cin >> c;
                grid[m][i] = c;
            }
        }
        if (DEBUG) {for (int m=0; m<M; ++m) { for (int n=0; n<N; ++n) printf("%c ",grid[m][n]); printf("\n"); }}
        if (solve(M, N)) printf("SAFE\n");
        else printf("SUSPICIOUS\n");
    }
    */
    int T, M, N, num;
    num = scanf("%d ", &T);
    while (T--)
    {
        num = scanf("%d %d ", &M, &N);
        for (int m=0; m<M; ++m) for (int i=0; i<N; ++i) num = scanf("%c ", &grid[m][i]);
        if (solve(M, N)) printf("SAFE\n");
        else printf("SUSPICIOUS\n");
    }
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 10
memory_kb: 3248
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...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

void Solve(int N, int M) {
    vector<string> S(N);
    rep(i,0,N) cin >> S[i];
    vector<int> lx(26), rx(26), ly(26), ry(26);
    while(1) {
        rep(i,0,26) lx[i] = inf, rx[i] = -inf, ly[i] = inf, ry[i] = -inf;
        rep(i,0,N) {
            rep(j,0,M) {
                if ('A' <= S[i][j] && S[i][j] <= 'Z') {
                    chmin(lx[S[i][j]-'A'],i);
                    chmax(rx[S[i][j]-'A'],i);
                    chmin(ly[S[i][j]-'A'],j);
                    chmax(ry[S[i][j]-'A'],j);
                }
            }
        }
        bool check = false;
        rep(i,0,26) {
            if (lx[i] == inf) continue;
            bool check2 = true;
            rep(j,lx[i],rx[i]+1) {
                rep(k,ly[i],ry[i]+1) {
                    if (S[j][k] == '.') {
                        cout << "SUSPICIOUS" << endl;
                        return;
                    }
                    if (S[j][k] != (char)('A'+i) && S[j][k] != '#') check2 = false;
                }
            }
            if (!check2) continue;
            check = true;
            rep(j,lx[i],rx[i]+1) {
                rep(k,ly[i],ry[i]+1) {
                    S[j][k] = '#';
                }
            }
        }
        if (!check) break;
    }
    bool ANS = true;
    rep(i,0,N) {
        rep(j,0,M) {
            if ('A' <= S[i][j] && S[i][j] <= 'Z') ANS = false;
        }
    }
    cout << (ANS ? "SAFE" : "SUSPICIOUS") << endl;
    return;
}

int main() {
    int T;
    cin >> T;
    rep(_,0,T) {
        int N, M;
        cin >> N >> M;
        if (N == 0 && M == 0) return 0;
        Solve(N,M);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3420
final_rank: 11

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <stdio.h>
#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <iomanip> //setprecision
#include <map> // map
#include <unordered_map> //unordered_map
#include <queue> // queue, priority_queue
#include <set> // set,multiset
#include <stack> // stack
#include <deque> // deque
#include <math.h>//pow,,,
#include <cmath>//abs,,,
#include <bitset> // bitset
#include <numeric> //accumulate,,,
#include <sstream>
#include <initializer_list>
#include <random>
#include <unordered_set>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <functional>
#include <climits>
#include <utility>
#include <cassert>
//#include <atcoder/all> // aclibraryを使う際は g++ a.cpp -O2 -std=c++17 -I . でコンパイルする
//using namespace atcoder;
using namespace std;
const long long INF = 4000000000000000001; // 4*10^18
const int inf = 2001001001;
const long long MOD = 998244353;
const double pi = 3.141592653589;
const vector<int> dh = {1,0,-1,0} , dw = {0,1,0,-1};
const vector<int> dh8 = {-1,-1,-1,0,0,1,1,1} , dw8 = {-1,0,1,-1,1,-1,0,1};
#define endl "\n";
long long modpow(long long a, long long n, long long mod) {
    a %= mod;
    long long ret = 1;
    while (n > 0) {
        if (n & 1) ret = ret * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ret % mod;
}
long long modinv(long long a, long long m) {
    long long b = m, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= m; 
    if (u < 0) u += m;
    return u;
}
long long gcd(long long a, long long b) {
    if (b == 0) return a; else return gcd(b, a % b);
}
long long lcm(long long a, long long b) {
    return a / gcd(a, b) * b ;
}
long long get_mod(long long res){
    if(res < 0) res += MOD;
    return res % MOD;
}
double DegToRad(double deg){
    return deg*(pi/180.0);
}
double RadToDeg(double rad){
    return rad/(pi/180.0);
}
int uniform_rand(int mini , int maxi){
    random_device seed;
    mt19937_64 engine(seed());
    uniform_real_distribution<> ran(mini , maxi+1);
    int ret = ran(engine);
    if(ret >= maxi+1) ret = maxi;
    return ret;
}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // FILE* in = freopen("mojain/in1.txt" , "r" , stdin); //2つ以上のケースを試したい場合はファイル名をループ回してin2.txt等で指定していく
    // FILE* out = freopen("mojaout/out1.txt", "w", stdout);
    // ifstream ifs("in.txt"); // 巨大ケースは in.txt に書いてifsで標準入力

    int N;cin >> N;
    for(int testcase = 0;testcase<N;testcase++){
        int H,W;cin >> H >> W;
        vector<vector<char>> ban(H,vector<char>(W));
        set<char> chars;
        for(int i = 0;i<H;i++){
            for(int j = 0;j<W;j++){
                cin >> ban.at(i).at(j);
                if(ban.at(i).at(j) != '.'){
                    chars.insert(ban.at(i).at(j));
                }
            }
        }

        string allchar = "";
        for(char c : chars){
            allchar += c;
        }
        sort(allchar.begin(),allchar.end());

        vector<int> minh(26,inf) , maxh(26,-1) , minw(26,inf) , maxw(26,-1);
        for(int i = 0;i<H;i++){
            for(int j = 0;j<W;j++){
                char c = ban.at(i).at(j);
                if(c != '.'){
                    int idx = c -= 'A';
                    minh.at(idx) = min(minh.at(idx) , i);
                    maxh.at(idx) = max(maxh.at(idx) , i);
                    minw.at(idx) = min(minw.at(idx) , j);
                    maxw.at(idx) = max(maxw.at(idx) , j);
                }
            }
        }

        do{
            vector<vector<char>> nban(H,vector<char>(W,'.'));
            for(char c : allchar){
                int sh,gh,sw,gw;
                sh = minh.at(c-'A'); gh = maxh.at(c-'A'); sw = minw.at(c-'A'); gw = maxw.at(c-'A');
                for(int h = sh;h<=gh;h++){
                    for(int w = sw;w<=gw;w++){
                        nban.at(h).at(w) = c;
                    }
                }
            }

            if(ban == nban){
                cout << "SAFE" << endl;
                goto SKIP;
            }


        }while(next_permutation(allchar.begin(),allchar.end()));
        
        cout << "SUSPICIOUS" << endl;

        SKIP:;

        
    }

    

    
    

    

    

}
accuracy: 1
time_ms: 1190
memory_kb: 3204
final_rank: 5

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

#ifdef LOCAL
#include "./debug.hpp"
#else
#define debug(...)
#define print_line
#endif

using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using pi = pair<int,int>;
using pl = pair<ll,ll>;
const int INF = 1e9 + 10;
const ll INFL = 4e18;
#define rep(i, a, b) for (ll i = (a); i < (ll)(b); i++)
#define all(x) x.begin(),x.end()

template <typename T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template <typename T> bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

// --------------------------------------------------------

int main(){
	int T;cin>>T;

	while(T--){
		int H,W;cin>>H>>W;
		vector<string>S(H);
		for(int i=0;i<H;i++)cin>>S[i];

		set<char>st;
		map<char,int>lo,hi,le,ri;
		for(int i=0;i<H;i++){
			for(int j=0;j<W;j++){
				if(S[i][j]=='.')continue;
				if(!st.count(S[i][j])){
					st.insert(S[i][j]);
					lo[S[i][j]]=i;
					hi[S[i][j]]=i;
					le[S[i][j]]=j;
					ri[S[i][j]]=j;
				}else{
					chmin(lo[S[i][j]],i);
					chmax(hi[S[i][j]],i);
					chmin(le[S[i][j]],j);
					chmax(ri[S[i][j]],j);
				}
			}
		}

		map<char,set<char>>G;
		bool ans=true;
		for(char c:st){
			for(int i=lo[c];i<=hi[c];i++){
				for(int j=le[c];j<=ri[c];j++){
					if(S[i][j]=='.')ans=false;
					else if(S[i][j]!=c)G[c].insert(S[i][j]);
				}
			}
		}

		map<char,int>D;
		for(char c:st)for(char nxt:G[c])D[nxt]++;
		queue<char>Q;
		for(char c:st)if(D[c]==0)Q.push(c);
		vector<char>to;
		while(!Q.empty()){
			char now=Q.front();Q.pop();
			to.push_back(now);
			for(char nxt:G[now])if(D[nxt]>0){
				D[nxt]--;
				if(D[nxt]==0)Q.push(nxt);
			}
		}

		if(to.size()==st.size()&&ans)cout<<"SAFE"<<endl;
		else cout<<"SUSPICIOUS"<<endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3392
final_rank: 9

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

using ll = long long;
using i64 = long long;
using pll = pair<ll,ll>;
using plll = pair<pll,ll>;
using pii =pair<int,int>;

constexpr ll mod = 998244353;

int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int dX[4]={1,0,-1,0};
int dY[4]={0,-1,0,1};

//library


//end


int main(){
    int n;
    cin>>n;
    for (int i00=0; i00<n; i00++){
        int h,w;
        cin>>h>>w;

        if (h==0)break;
        vector<string> F(h);

        for (int i=0; i<h; i++)cin>>F[i];

        //cout<<F[h-1]<<endl;
        map<char, int> dic;
        int k=0;
        for (int i=0; i<h; i++){
            for (int j=0; j<w; j++){
                if (F[i][j]=='.')continue;
                if (dic.count(F[i][j])==0) {
                    dic[F[i][j]] = k;
                    k++;
                }
                F[i][j]='0'+dic[F[i][j]];

            }
        }
        vector<int> vec(k);
        for (int i=0; i<k; i++)vec[i]=i;
        string ans="SUSPICIOUS";
        do{
            //cout<<endl;
            vector<string>nF(h);
            //cout<<F[4];
            for (int i=0; i<h; i++)nF[i]=F[i];
            for (int i0=0; i0<k; i0++) {
                char c = '0' + vec[i0];
                //cout<<c;
                int mx = 1000, Mx = 0, my = 1000, My = 0;
                for (int i = 0; i < h; i++) {
                    for (int j = 0; j < w; j++) {
                        if (F[i][j] == c) {
                            mx = min(mx, i);
                            Mx = max(Mx, i);
                            my = min(my, j);
                            My = max(My, j);

                        }
                    }
                }
                for (int i = mx; i <= Mx; i++) {
                    for (int j = my; j <= My; j++) {
                        if (F[i][j] == c || F[i][j] == '#') {
                            F[i][j] = '#';
                            continue;
                        }
                        goto go1;
                    }

                }
            }

            ans="SAFE";
            break;

            go1:;

            swap(nF,F);
        }while(next_permutation(vec.begin(),vec.end()));


        cout<<ans<<endl;






    }

}
accuracy: 1
time_ms: 1290
memory_kb: 3476
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i< (n); i++)
#define mkp(i,j) make_pair((i),(j))
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int mod = 998244353;
const int inf = (1<<30);


int main(){
    int q; cin>>q;
    rep(o,q){
        vector<vector<int>> c(8,vector<int>(4));//up,dw,le,ri
        rep(i,8){
            c[i][0] = inf;
            c[i][2] = inf; 
        }
        map<char,int> ctoi;
        int h,w; cin>>h>>w;
        vector<vector<int>> table(h,vector<int>(w));
        int count = 1;

        rep(i,h){
            rep(j,w){
                char s; cin>>s;
                if(s == '.') table[i][j] = 0;
                else{
                    int a  = ctoi[s];
                    if(a == 0){
                        ctoi[s] = count;
                        count++;
                    }
                    table[i][j] = ctoi[s];
                }
            }
        }
        rep(i,h){
            rep(j,w){
                int s = table[i][j];
                c[s][0] = min(i,c[s][0]);
                c[s][1] = max(i,c[s][1]);
                c[s][2] = min(j,c[s][2]);
                c[s][3] = max(j,c[s][3]);
            }
        }
        vector<int> p;
        for(int i = 1; i<count; i++) p.push_back(i);
        if(p.size() == 0){
            cout<<"SAFE"<<endl;
            continue;
        }
        bool ans = 0;
        do{
            set<int> v;
            bool res = 1;
            for(int s : p){
                for(int i = c[s][0]; i <= c[s][1]; i++){
                    for(int j = c[s][2]; j<=c[s][3]; j++){
                        if(table[i][j] == s) continue;
                        if(v.find(table[i][j]) == v.end()){
                            res = 0;
                            //cout<<i<<" "<<j<<endl;
                        }
                    }
                }
                v.insert(s);
            }
            if(res == 1) ans = 1;

        }while(next_permutation(p.begin(),p.end()));
        
        cout<<(ans ? "SAFE" : "SUSPICIOUS")<<endl;
    }
}
accuracy: 1
time_ms: 1670
memory_kb: 3420
final_rank: 16

code_snippet: # include <bits/stdc++.h>
using namespace std;
#define ll long long 
#define rep(i,n) for(ll i = 0;i <(ll)n;i++)
const ll INF = 1LL << 60;

bool chmin(ll &a,ll b){
  if(a > b){
    a = b;
    return true;
  }else{
    return false;
  }
}

bool chmax(ll & a,ll b){
  if(a < b){
    a = b;
    return true;
  }else{
    return false;
  }
}

void solve(){
  ll h,w;cin >> h >> w;
  vector<string> s(h);
  set<char>ch;
  rep(i,h){
    cin >> s[i];
    rep(j,w){
      if(isupper(s[i][j])){
        ch.insert(s[i][j]);
      }
    }
  }
  ll siz = 26;
  if(siz == 0){
    cout << "SAFE"  << endl;
    return ;
  }
  vector<ll> fin(siz,1);
  for(auto &p:ch){
    fin[p - 'A'] = 0;
  }
  vector<pair<ll,ll>> lr(siz,{INF,-INF}),ud(siz,{INF,-INF});
  auto getid = [](char x){
    return x - 'A';
  };

  rep(i,h){
    rep(j,w){
      if(isupper(s[i][j])){
        ll id =getid(s[i][j]);
        chmin(lr[id].first,j);
        chmax(lr[id].second,j);
        chmin(ud[id].first,i);
        chmax(ud[id].second,i);
      }
    }
  }
  while(true){
    bool isfin = true;
    rep(i,siz){
      if(fin[i])continue;
      bool able = true;
      for(ll x = lr[i].first;x <= lr[i].second;x++)for(ll y = ud[i].first ;y <= ud[i].second;y++){
        if(s[y][x] == char('A' + i) or s[y][x] == '*'){

        }else{
          able = false;
        }
      }
      if(able){
        for(ll x = lr[i].first;x <= lr[i].second;x++)for(ll y = ud[i].first ;y <= ud[i].second;y++){
          s[y][x] = '*';
        }
        fin[i] = 1;
        isfin = false;
      }
    }
    if(isfin){
      break;
    }
  }

  if(*min_element(fin.begin(),fin.end()) == 0){
    cout << "SUSPICIOUS" << endl;
  }else{
    cout << "SAFE" << endl;
  }
}


int main(){
  ll t;cin >> t;
  while(t--){
    solve();
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3372
final_rank: 8

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

#define rep(i,n) for(int i=0;i<n;i++)
#define Rep(i,a,b) for(int i=a;i<b;i++)
#define ALL(x) (x).begin(),(x).end()
#define dbgv(x); for(auto now : x) cout << now << " "; cout << endl;
void chmin(int &a,int b){if(a > b) a = b;}
void chmax(int &a,int b){if(a < b) a = b;}
int main(){
    int n; cin >> n;
    while(n--){
        int h,w;
        cin >> h >> w;
        vector<pair<int,int>> mn(30,make_pair(-1,-1)),mx(30,make_pair(-1,-1));
        vector<string> s(h); rep(i,h) cin >> s[i];
        rep(i,h)rep(j,w)if(s[i][j] != '.'){
            if(mn[s[i][j]-'A'].first == -1){
                mn[s[i][j]-'A'].first = i;
                mn[s[i][j]-'A'].second = j;
                mx[s[i][j]-'A'].first = i;
                mx[s[i][j]-'A'].second = j;
            }else{
                chmin(mn[s[i][j]-'A'].first,i);
                chmin(mn[s[i][j]-'A'].second,j);
                chmax(mx[s[i][j]-'A'].first,i);
                chmax(mx[s[i][j]-'A'].second,j);
            }
        }
        vector<int> v;
        rep(i,30)if(mn[i].first != -1){
            v.push_back(i);
        }
        auto ch = [&](int x)->bool{
            auto [sx,sy] = mn[x];
            auto [tx,ty] = mx[x];
            for(int i = sx;i <= tx;i++)for(int j = sy;j <= ty;j++){
                if(s[i][j]-'A' != x && s[i][j] != '#') return false;
            }
            return true;
        };
        auto val = [&](int x)->void{
            auto [sx,sy] = mn[x];
            auto [tx,ty] = mx[x];
            for(int i = sx;i <= tx;i++)for(int j = sy;j <= ty;j++){
                s[i][j] = '#';
            }
        };
        if(v.size() == 0){
            cout << "SAFE" << endl;
            continue;
        }
        while(1){
            vector<int> nv;
            for(int x : v){
                if(ch(x)){
                    val(x);
                }else{
                    nv.push_back(x);
                }
            }
            if(nv.size() == v.size()){
                break;
            }
            swap(nv,v);
        }
        if(v.size() == 0){
            cout << "SAFE" << endl;
        }else{
            cout << "SUSPICIOUS" << endl;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3360
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    int tc;
    cin >> tc;
    while(tc--) {
        int h, w;
        cin >> h >> w;
        vector<string> s(h);
        vector<char> c;
        vector<int> mi_x, ma_x, mi_y, ma_y;
        map<char, int> mp;
        rep(i, 0, h) {
            cin >> s[i];
            rep(j, 0, w) {
                if(s[i][j] == '.') continue;
                if(mp.find(s[i][j]) == mp.end()) {
                    c.push_back(s[i][j]);
                    mp[s[i][j]] = mp.size();
                    mi_x.push_back(i);
                    ma_x.push_back(i);
                    mi_y.push_back(j);
                    ma_y.push_back(j);
                } else {
                    mi_x[mp[s[i][j]]] = min(mi_x[mp[s[i][j]]], (int)i);
                    ma_x[mp[s[i][j]]] = max(ma_x[mp[s[i][j]]], (int)i);
                    mi_y[mp[s[i][j]]] = min(mi_y[mp[s[i][j]]], (int)j);
                    ma_y[mp[s[i][j]]] = max(ma_y[mp[s[i][j]]], (int)j);
                }
            }
        }
        vector<int> p(mp.size());
        rep(i, 0, (int)p.size()) {
            p[i] = i;
        }
        bool ans = false;
        do {
            vector<vector<char>> t(h, vector<char>(w, '.'));
            rep(i, 0, (int)p.size()) {
                rep(j, mi_x[p[i]], ma_x[p[i]] + 1) {
                    rep(k, mi_y[p[i]], ma_y[p[i]] + 1) {
                        t[j][k] = c[p[i]];
                    }
                }
            }
            bool flag = true;
            rep(i, 0, h) {
                rep(j, 0, w) {
                    if(s[i][j] != t[i][j]) {
                        flag = false;
                    }
                }
            }
            if(flag) {
                ans = true;
            }
        } while(next_permutation(p.begin(), p.end()));
        if(ans) {
            cout << "SAFE" << '\n';
        } else {
            cout << "SUSPICIOUS" << '\n';
        }
    }
}
accuracy: 1
time_ms: 2540
memory_kb: 3352
final_rank: 17

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

string solve(int H, int W){
    vc<string> S(H); rep(i, H) cin >> S[i];
    map<char, pair<int, int>> X, Y;
    rep(i, H) rep(j, W) if (S[i][j] != '.'){
        if (!X.count(S[i][j])){
            X[S[i][j]] = {inf, -1};
            Y[S[i][j]] = {inf, -1};
        }
        X[S[i][j]].first = min(X[S[i][j]].first, (int)i);
        X[S[i][j]].second = max(X[S[i][j]].second, (int)i);
        Y[S[i][j]].first = min(Y[S[i][j]].first, (int)j);
        Y[S[i][j]].second = max(Y[S[i][j]].second, (int)j);
    }
    vc<char> erased = {'.'};
    while (len(erased)){
        for (auto x : erased) if (X.count(x)){
            X.erase(x);
            Y.erase(x);
        }
        erased.clear();
        for (auto [k, v] : X){
            auto [si, gi] = v;
            auto [sj, gj] = Y[k];
            bool flag = true;
            srep(i, si, gi + 1) srep(j, sj, gj + 1) if (S[i][j] != k && S[i][j] != '#') flag = false;
            if (flag){
                srep(i, si, gi + 1) srep(j, sj, gj + 1) S[i][j] = '#';
                erased.push_back(k);
            }
        }
    }
    rep(i, H) rep(j, W) if (S[i][j] != '.' && S[i][j] != '#') return "SUSPICIOUS";
    return "SAFE";
}

int main(){
    int T; cin >> T;
    vc<string> ans;
    while (T--){
        int H, W; cin >> H >> W;
        ans.push_back(solve(H, W));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3236
final_rank: 3

code_snippet: #include<iostream>
using namespace std;
const int NUM = 8;
const int CONST = 51;

class Rectangle {
public:
	int left;
	int right;
	int top;
	int bottom;
	char material;

	void check(int h, int w) {
		if (w < left){
			left = w;
		}
		if (w > right){
			right = w;
		}
		if (h < top){
			top = h;
		}
		if (h > bottom){
			bottom = h;
		}
	}
} ;

class XRayScreening {
public:
	int hight, width;
	int mateN;
	char ch;

	Rectangle rct[NUM];
	int data[CONST][CONST] = {};
	bool position[NUM][NUM] = {};

	XRayScreening(int h, int w) {
		hight = h;
		width = w;
		mateN = 0;
		ch = '\0';
	}
	void set_data() {
		for (int i = 1; i <= hight; ++i) {
			for (int j = 1; j <= width; ++j) {
				cin >> ch;

				if (ch == '.') {
					data[i][j] = 0;
				} else {
					int k = 1;

					while (k <= mateN) {
						if (ch == rct[k].material) {
							data[i][j] = k;
							rct[k].check(i, j);
							break;
						}
						k++;
					}
					if (k == mateN + 1) {
						data[i][j] = k;
						rct[k].material = ch;
						rct[k].left = j;
						rct[k].right = j;
						rct[k].top = i;
						rct[k].bottom = i;
						mateN++;
					}
				}
			}
		}
	}
	bool check_xray() {
		bool flag = true;

		for (int i = 1; i <= mateN; i++) {
			for (int j = rct[i].top; j <= rct[i].bottom; ++j) {
				for (int k = rct[i].left; k <= rct[i].right; ++k) {

					if (data[j][k] == 0) {
						flag = false;

					} else if (data[j][k] != i) {

						if (position[i][data[j][k]] == false) {
							position[i][data[j][k]] = true;

							for (int l = 1; l <= mateN; l++) {

								position[i][l] = (position[i][l] || position[data[j][k]][l]);
								position[l][data[j][k]] = (position[l][i] || position[l][data[j][k]]);								
							}
						}
					}
				}
			}
		}
		for (int i = 1; i <= mateN; ++i) {
			if (position[i][i] == true)
				flag = false;
		}
		return flag;
	}
} ;

int main() {
	int n, h, w;
	cin >> n;


	for (int i = 0; i < n; ++i) {
		cin >> h >> w;

		XRayScreening xrs(h, w);
		xrs.set_data();

		if (xrs.check_xray())
			cout << "SAFE\n";
		else
			cout << "SUSPICIOUS\n";
	}
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3076
final_rank: 1

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

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  cin>>N;
  while(N--){
    int H,W;
    cin>>H>>W;
    vector<vector<char>> A(H,vector<char>(W));
    map<char,array<int,4>>C;
    for(int i=0;i<H;i++){
      for(int j=0;j<W;j++){
        cin>>A[i][j];
        if(A[i][j]!='.'){
          if(C.find(A[i][j])==C.end()){
            C[A[i][j]]={100,100,-1,-1};
          }
          C[A[i][j]][0]=min(C[A[i][j]][0],i);
          C[A[i][j]][1]=min(C[A[i][j]][1],j);
          C[A[i][j]][2]=max(C[A[i][j]][2],i);
          C[A[i][j]][3]=max(C[A[i][j]][3],j);
        }
      }
    }
    bool ans=!C.empty();
    vector<pair<char,array<int,4>>>S;
    for(auto i:C)S.push_back(i);
    do{
      bool now=true;
      vector<vector<bool>>ok(H,vector<bool>(W));
      for(int i=0;i<S.size();i++){
        for(int j=S[i].second[0];j<=S[i].second[2];j++){
          for(int k=S[i].second[1];k<=S[i].second[3];k++){
            if(!ok[j][k]&&A[j][k]!=S[i].first)now=false;
            ok[j][k]=true;
          }
        }
      }
      if(now)ans=false;
    }while(next_permutation(S.begin(),S.end()));
    cout<<(ans?"SUSPICIOUS\n":"SAFE\n");
  }
}
accuracy: 1
time_ms: 4710
memory_kb: 3416
final_rank: 20

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

using ll = long long;

bool is_end = false;

void calc()
{
	ll H, W; cin >> H >> W;
	vector<vector<ll>> vec(H, vector<ll>(W));
	set<ll> P;
	for (int i = 0; i < H; ++i)
	{
		string S; cin >> S;
		for (int j = 0; j < W; ++j)
		{
			if (S[j] == '.') {vec[i][j] = -1;}
			else {vec[i][j] = S[j] - 'A'; P.insert(vec[i][j]);}
		}
	}
	
	const ll INF = 1e15;
	vector<ll> minx(26, INF), maxx(26, -1), miny(26, INF), maxy(26, -1);
	for (ll i = 0; i < H; ++i)
	{
		for (ll j = 0; j < W; ++j)
		{
			int v = vec[i][j];
			if (v == -1) {continue;}
			
			minx[v] = min(minx[v], i);
			maxx[v] = max(maxx[v], i);
			miny[v] = min(miny[v], j);
			maxy[v] = max(maxy[v], j);
		}
	}
	for (int i = 0; i < 26; ++i)
	{
		if (minx[i] == INF) {minx[i] = -1;}
		if (miny[i] == INF) {miny[i] = -1;}
	}

	vector<vector<ll>> copy = vec;
	ll done = 0;
	while (1)
	{
		ll color = -1;
		for (auto p : P)
		{
			bool isok = true;
			for (int x = minx[p]; x <= maxx[p]; ++x)
			{
				for (int y = miny[p]; y <= maxy[p]; ++y)
				{
					if (copy[x][y] != p && copy[x][y] != 100) {isok = false;}
				}
			}
			
			if (isok) {color = p;}
		}
		
		if (color == -1) {break;}
		
		P.erase(color);
		for (int x = 0; x < H; ++x)
		{
			for (int y = 0; y < W; ++y)
			{
				if (copy[x][y] == color)
				{
					copy[x][y] = 100;
				}
			}
		}
		
	}
	
	string res = "SUSPICIOUS";
	if (P.size() == 0) {res = "SAFE";}
	
	cout << res << endl;
	
	return;
}

int main()
{
	ll T; cin >> T;
	while (T--)
	{
		calc();
	}
	
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3460
final_rank: 13