/** 
 *    author:  pankaj_m05
 *    created: 02.01.2021 17:42:10
**/ 
#include<bits/stdc++.h>

using namespace std;

int main(void) {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n;
  cin >> n;
  map<string, bool> mp1, mp2;
  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;
    mp1[s] = true;
    if (s[0] != '!') {
      mp2[s] = true;
    }
  }
  for (auto& it : mp2) {
    string t1 = it.first, t2 = "!" + it.first;
    if (mp1[t1] && mp1[t2]) {
      cout << t1;
      return 0;
    }
  }
  cout << "satisfiable"; 
  return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)  FOR(i,0,n)
#define req(i,n) for(int i = 1;i <=n;i++)
#define pai 3.14159265358979323846
const int INF = 1001001001;
typedef long long ll;
int A[3][3], N;
bool punched[3][3];

//using Graph = vector<vector<int>>;


const int MOD = 1000000007;
typedef pair<int,int> P;

//最大公約数
ll gcd(ll a,ll b){
	if (a%b == 0){
		return b;
	}
	else{
		return gcd(b,a%b);
	}

}

//最小公倍数
ll lcm(ll a,ll b){
	return a /gcd(a,b) * b;
}

//素数判定
bool is_prime(long long N) {
    if (N == 1) return false;
    for (long long i = 2; i * i <= N; ++i) {
        if (N % i == 0) return false;
    }
    return true;
}

// 素因数分解
vector<pair<long long, long long> > prime_factorize(long long n) {
    vector<pair<long long, long long> > res;
    for (long long p = 2; p * p <= n; ++p) {
        if (n % p != 0) continue;
        int num = 0;
        while (n % p == 0) { ++num; n /= p; }
        res.push_back(make_pair(p, num));
    }
    if (n != 1) res.push_back(make_pair(n, 1));
    return res;
}

// 10進数から2進数
int binary(int bina){
    int ans = 0;
    for (int i = 0; bina>0 ; i++)
    {
        ans = ans+(bina%2)*pow(10,i);
        bina = bina/2;
    }
    return ans;
}

//Union-Find
struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

    UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }

    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    }

    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }
};






ll powmod(ll x,ll y){
    ll res=1;
    for(ll i=0;i<y;i++){
        res=res*x%MOD;
    }
    return res;
}


 
bool ok(int v, int b) {
    while (v) {
        if (v % b == 7) return false;
        v /= b;
    }
    return true;
}

int main() {
   int n;
   cin >> n;
   string s[n];
   set <string> ans1,ans2;
   rep (i,n) {
       cin >> s[i];
       if (s[i][0] != '!') ans1.insert(s[i]);
       else ans2.insert(s[i]);
   }
    int d = ans2.size();
    string ans = "satisfiable";
   for (auto x:ans1) {
       string s = "!";
       s += x;
       ans2.insert(s);
       if (d == ans2.size()){
           ans = x ;
           break;
       }
       else {
           d = ans2.size();
           continue;
       }
   }
   cout << ans << endl;
}