#include #include #include #include #include #include #include using namespace std; map mp; int c; struct Expr { int var, opt, num; Expr() {} Expr(int var, int opt, int num) { this->var = var; this->opt = opt; this->num = num; } }; struct Inp { char s[12345], *p; Inp() {} void read() { gets(s); p = s; } bool hasNext() { while (*p) { if (*p++ == ',') return true; } return false; } bool isAlp(char ch) {return ch >= 'a' && ch <= 'z';} int nextVar() { char *buf; while (*p == ' ') p++; buf = p; while (isAlp(*p)) p++; return mp[string(buf, p - buf)]? mp[string(buf, p - buf)] : (mp[string(buf, p - buf)] = ++c); } int nextOpt() { char *buf; while (*p == ' ') p++; buf = p; while (*p == '<' || *p == '>' || *p == '=') p++; string s(buf, p - buf); if (s == "==") return 0; if (s == "<") return 1; if (s == ">") return 2; if (s == "<=") return 3; if (s == ">=") return 4; } int nextNum() { int ans = 0, flag = 0; while (*p == ' ') p++; while (isdigit(*p) || *p == '-') { if (isdigit(*p)) ans = ans * 10 + *p - '0'; else flag = 1; p++; } return flag? -ans : ans; } Expr nextExp() { int a = nextVar(), b = nextOpt(), c = nextNum(); return Expr(a, b, c); } }; bool cmp(Expr a, Expr b) { return a.var == b.var? a.opt < b.opt : a.var < b.var; } int umin(int &a, int b) {if (a > b) a = b;} int umax(int &a, int b) {if (a < b) a = b;} struct Con { vector v; bool conflict, flag[33]; int bound[33][5]; void add(Con con) { int sz = con.v.size(); for (int i = 0; i < sz; i++) { v.push_back(con.v[i]); } } void init() { for (int i = 0; i < 33; i++) { bound[i][0] = bound[i][1] = bound[i][3] = 12345; bound[i][2] = bound[i][4] = -12345; } int sz = v.size(); for (int i = 0; i < sz; i++) { Expr cur = v[i]; flag[cur.var] = true; if (upd(cur, bound[cur.var])) { conflict = true; break; } } if (!conflict && chk()) conflict = true; } bool upd(Expr cur, int a[]) { if (cur.opt == 0) { if (a[0] != 12345 && a[0] != cur.num) return true; a[0] = cur.num; } if (cur.opt == 1) umin(a[1], cur.num); if (cur.opt == 2) umax(a[2], cur.num); if (cur.opt == 3) umin(a[3], cur.num); if (cur.opt == 4) umax(a[4], cur.num); return false; } bool chk(int a[5]) { int minv = a[1], maxv = a[2]; bool minf = 0, maxf = 0; if (a[3] < minv) { minv = a[3]; minf = 1; } if (a[4] > maxv) { maxv = a[4]; maxf = 1; } if (minf && maxf) { if (a[0] == 12345) return minv >= maxv; return a[0] <= minv && a[0] >= maxv; } if (minf && !maxf) { if (a[0] == 12345) return minv > maxv; return a[0] <= minv && a[0] > maxv; } if (!minf && maxf) { if (a[0] == 12345) return minv > maxv; return a[0] < minv && a[0] >= maxv; } if (!minf && !maxf) { if (a[0] == 12345) return minv > maxv + 1; return a[0] < minv && a[0] > maxv; } } bool chk() { for (int i = 1; i < 33; i++) { if (flag[i]) { if (!chk(bound[i])) return true; } } return false; } }; Inp inp; Con con[1234]; int n; int main() { //freopen("in.txt", "r", stdin); cin >> n; getchar(); for (int i = 1; i <= n; i++) { inp.read(); con[i].v.push_back(inp.nextExp()); while (inp.hasNext()) con[i].v.push_back(inp.nextExp()); vector ans; int n = i; for (int i = 1; i < n; i++) { Con newcon = con[n]; newcon.add(con[i]); newcon.init(); if (!newcon.conflict) ans.push_back(i); } int sz = ans.size(); if (sz == 0) puts("unique"); else { for (int i = 0; i < sz; i++) { printf("%d%c", ans[i], i == sz - 1? '\n' : ' '); } } } return 0; }