Little Artem is a very smart programmer. He knows many different difficult algorithms. Recently he has mastered in 2-SAT one.

In computer science, 2-satisfiability (abbreviated as 2-SAT) is the special case of the problem of determining whether a conjunction (logical AND) of disjunctions (logical OR) have a solution, in which all disjunctions consist of no more than two arguments (variables). For the purpose of this problem we consider only 2-SAT formulas where each disjunction consists of exactly two arguments.

Consider the following 2-SAT problem as an example: <image>. Note that there might be negations in 2-SAT formula (like for x1 and for x4).

Artem now tries to solve as many problems with 2-SAT as possible. He found a very interesting one, which he can not solve yet. Of course, he asks you to help him. 

The problem is: given two 2-SAT formulas f and g, determine whether their sets of possible solutions are the same. Otherwise, find any variables assignment x such that f(x) ≠ g(x). 

Input

The first line of the input contains three integers n, m1 and m2 (1 ≤ n ≤ 1000, 1 ≤ m1, m2 ≤ n2) — the number of variables, the number of disjunctions in the first formula and the number of disjunctions in the second formula, respectively.

Next m1 lines contains the description of 2-SAT formula f. The description consists of exactly m1 pairs of integers xi ( - n ≤ xi ≤ n, xi ≠ 0) each on separate line, where xi > 0 corresponds to the variable without negation, while xi < 0 corresponds to the variable with negation. Each pair gives a single disjunction. Next m2 lines contains formula g in the similar format.

Output

If both formulas share the same set of solutions, output a single word "SIMILAR" (without quotes). Otherwise output exactly n integers xi (<image>) — any set of values x such that f(x) ≠ g(x).

Examples

Input

2 1 1
1 2
1 2


Output

SIMILAR


Input

2 1 1
1 2
1 -2


Output

0 0 

Note

First sample has two equal formulas, so they are similar by definition.

In second sample if we compute first function with x1 = 0 and x2 = 0 we get the result 0, because <image>. But the second formula is 1, because <image>.
#include <bits/stdc++.h>
using namespace std;
int n;
template <int i>
class bibitset {
 public:
  bitset<i> a, b;
  bibitset<i>(const bitset<i> &a, const bitset<i> &b) : a(a), b(b){};
  bibitset<i>(){};
  bool operator[](int ind) {
    assert(ind < 2 * n);
    if (ind < n) {
      return a[ind];
    }
    return b[ind - n];
  }
  void set(int ind, int val) {
    assert(ind < 2 * n);
    if (ind < n) {
      a[ind] = val;
    } else {
      b[ind - n] = val;
    }
  }
  size_t count() { return a.count() + b.count(); }
  friend ostream &operator<<(ostream &os, const bibitset<i> &a) {
    os << a.a << endl << a.b << endl << endl;
    return os;
  }
  friend bibitset<i> operator|(const bibitset<i> &a, const bibitset<i> &b) {
    return bibitset(a.a | b.a, a.b | b.b);
  }
  friend bibitset<i> &operator&(const bibitset<i> &a, const bibitset<i> &b) {
    return bibitset(a.a & b.a, a.b & b.b);
  }
  friend bibitset<i> &operator^(const bibitset<i> &a, const bibitset<i> &b) {
    return bibitset(a.a ^ b.a, a.b ^ b.b);
  }
  bool norm() {
    if ((a & b).count()) {
      return 0;
    }
    return 1;
  }
};
const int MAXN = 2000;
const int MAXM = 1000 * 1000;
pair<int, int> f1[MAXM], f2[MAXM];
bool ans[MAXN];
int inv(int a) {
  if (a < n) {
    return a + n;
  }
  return a - n;
}
bool get(int ind, bool *val) { return val[ind]; }
bool get(pair<int, int> *f, int m, bool *ans) {
  for (int i = 0; i < m; i++) {
    if (!(get(f[i].first, ans) || get(f[i].second, ans))) {
      return 0;
    }
  }
  return 1;
}
vector<int> g[MAXN], _g[MAXN];
vector<int> ord;
bool was[MAXN];
int col[MAXN];
vector<int> who[MAXN];
bibitset<MAXN> down[MAXN];
void find_ord(int v) {
  if (was[v]) {
    return;
  }
  was[v] = 1;
  for (int u : g[v]) {
    find_ord(u);
  }
  ord.push_back(v);
}
void find_comp(int v, int _col) {
  if (was[v]) {
    return;
  }
  was[v] = 1;
  for (int u : _g[v]) {
    find_comp(u, _col);
  }
  col[v] = _col;
  who[col[v]].push_back(v);
}
void find_down(int cur_col, bibitset<MAXN> &one) {
  if (was[cur_col]) {
    return;
  }
  was[cur_col] = 1;
  for (int v : who[cur_col]) {
    for (int u : g[v]) {
      int ne_col = col[u];
      find_down(ne_col, one);
      down[cur_col] = down[cur_col] | down[ne_col];
    }
  }
  for (int v : who[cur_col]) {
    if (down[cur_col][inv(v)]) {
      one = one | down[col[inv(v)]];
    }
    down[cur_col].set(v, 1);
  }
}
bibitset<MAXN> one;
bool solve(pair<int, int> *f1, int m1, pair<int, int> *f2, int m2, int n,
           bool *ans) {
  for (int i = 0; i < 2 * n; i++) {
    one.set(i, 0);
  }
  for (int i = 0; i < 2 * n; i++) {
    g[i].clear();
    _g[i].clear();
    who[i].clear();
    for (int j = 0; j < 2 * n; j++) {
      down[i].set(j, 0);
    }
  }
  for (int i = 0; i < m1; i++) {
    g[inv(f1[i].first)].push_back(f1[i].second);
    g[inv(f1[i].second)].push_back(f1[i].first);
    _g[f1[i].first].push_back(inv(f1[i].second));
    _g[f1[i].second].push_back(inv(f1[i].first));
  }
  ord.clear();
  memset(was, 0, sizeof was);
  for (int i = 0; i < 2 * n; i++) {
    find_ord(i);
  }
  assert(((int)(ord.size())) == 2 * n);
  reverse(ord.begin(), ord.end());
  int cnt_comp = 0;
  memset(was, 0, sizeof was);
  for (int i = 0; i < 2 * n; i++) {
    if (!was[ord[i]]) {
      find_comp(ord[i], cnt_comp++);
    }
  }
  for (int i = 0; i < 2 * n; i++) {
    if (col[i] == col[inv(i)]) {
      return 0;
    }
  }
  memset(was, 0, sizeof was);
  for (int i = 0; i < cnt_comp; i++) {
    find_down(i, one);
  }
  for (int i = 0; i < 2 * n; i++) {
    assert(down[col[i]][i] == 1);
  }
  for (int i = 0; i < m2; i++) {
    if ((one | down[col[inv(f2[i].first)]] | down[col[inv(f2[i].second)]])
            .norm()) {
      one = one | down[col[inv(f2[i].first)]] | down[col[inv(f2[i].second)]];
      for (int i = 0; i < n; i++) {
        if (one[i] == 0 && one[i + n] == 0) {
          one = one | down[col[i]];
        }
        assert((one[i] ^ one[i + n]) == 1);
      }
      for (int i = 0; i < 2 * n; i++) {
        ans[i] = one[i];
      }
      return 1;
    }
  }
  return 0;
}
void remake(int &a) {
  if (a > 0) {
    a += n - 1;
  } else {
    a = -a;
    a--;
  }
}
void read(int m, pair<int, int> *f) {
  for (int i = 0; i < m; i++) {
    scanf("%i %i", &f[i].first, &f[i].second);
    remake(f[i].first);
    remake(f[i].second);
  }
}
int main() {
  int m1, m2;
  scanf("%i %i %i", &n, &m1, &m2);
  read(m1, f1);
  read(m2, f2);
  bool fl;
  fl = solve(f2, m2, f1, m1, n, ans);
  if (fl) {
    for (int i = 0; i < n; i++) {
      printf("%i ", ans[i + n]);
    }
    printf("\n");
    assert(get(f1, m1, ans) == 0);
    assert(get(f2, m2, ans) == 1);
    return 0;
  }
  fl = solve(f1, m1, f2, m2, n, ans);
  if (fl) {
    assert(get(f1, m1, ans) == 1);
    assert(get(f2, m2, ans) == 0);
    for (int i = 0; i < n; i++) {
      printf("%i ", ans[i + n]);
    }
    printf("\n");
    return 0;
  }
  printf("SIMILAR\n");
  return 0;
}
