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>
#pragma comment(linker, "/STACK:256000000")
using namespace std;
const int inf = 1e9;
const double eps = 1e-9;
const double pi = 4 * atan(1.0);
const int N = 1010;
struct func {
  int n;
  pair<int, int> a[N * N];
  inline void read(int _n) {
    n = _n;
    for (int i = 0; i < n; ++i) {
      scanf("%d %d", &a[i].first, &a[i].second);
    }
  }
};
int n, sz;
func f, g;
vector<int> topsort;
bool used[2 * N];
int col[2 * N], xs[N];
bool can[2 * N][2 * N];
bitset<2 * N> go[2 * N];
inline void add(int xnum, int x, int ynum, int y) {
  can[xnum * 2 + x][ynum * 2 + y] = true;
}
void dfs1(int v) {
  used[v] = true;
  for (int i = 0; i < 2 * n; ++i) {
    if (can[v][i] && !used[i]) {
      dfs1(i);
    }
  }
  topsort.push_back(v);
}
void dfs2(int v) {
  col[v] = sz;
  for (int i = 0; i < 2 * n; ++i) {
    if (can[i][v] && col[i] == -1) {
      dfs2(i);
    }
  }
}
inline bool check(int x, int y) { return go[col[x]].test(col[y]); }
inline void build() {
  memset(used, 0, sizeof(used));
  topsort.clear();
  for (int i = 0; i < 2 * n; ++i) {
    if (!used[i]) {
      dfs1(i);
    }
  }
  reverse((topsort).begin(), (topsort).end());
  memset(col, -1, sizeof(col));
  sz = 0;
  for (int v : topsort) {
    if (col[v] == -1) {
      dfs2(v);
      ++sz;
    }
  }
  for (int i = 0; i < n; ++i) {
    xs[i] = (col[2 * i] < col[2 * i + 1] ? 1 : 0);
  }
}
inline bool check(const func& f) {
  for (int i = 0; i < f.n; ++i) {
    pair<int, int> p = f.a[i];
    int xnum = abs(p.first) - 1, ynum = abs(p.second) - 1;
    int xval = (p.first < 0 ? (1 - xs[xnum]) : xs[xnum]);
    int yval = (p.second < 0 ? (1 - xs[ynum]) : xs[ynum]);
    if ((xval | yval) == 0) {
      return false;
    }
  }
  return true;
}
inline void solve(const func& f, const func& g) {
  memset(can, 0, sizeof(can));
  for (int i = 0; i < g.n; ++i) {
    int x = 1, y = 1, xnum = abs(g.a[i].first) - 1,
        ynum = abs(g.a[i].second) - 1;
    if (g.a[i].first < 0) {
      x = 0;
    }
    if (g.a[i].second < 0) {
      y = 0;
    }
    add(xnum, 1 - x, ynum, y);
    add(ynum, 1 - y, xnum, x);
  }
  build();
  for (int i = 0; i < n; ++i) {
    if (col[2 * i] == col[2 * i + 1]) {
      return;
    }
  }
  for (int i = 0; i < 2 * n; ++i) {
    go[i].reset();
    go[i].set(i);
  }
  for (int i = ((int)(topsort).size()) - 1; i >= 0; --i) {
    int v = topsort[i];
    for (int j = i + 1; j < ((int)(topsort).size()); ++j) {
      int u = topsort[j];
      if (can[v][u] && col[v] != col[u]) {
        go[col[v]] |= go[col[u]];
      }
    }
  }
  for (int i = 0; i < f.n; ++i) {
    int x = 0, y = 0, xnum = abs(f.a[i].first) - 1,
        ynum = abs(f.a[i].second) - 1;
    if (f.a[i].first < 0) {
      x = 1;
    }
    if (f.a[i].second < 0) {
      y = 1;
    }
    if (xnum == ynum) {
      if (x != y) {
        continue;
      }
      if (!check(2 * xnum + x, 2 * xnum + (1 - x))) {
        add(xnum, 1 - x, xnum, x);
        build();
        for (int j = 0; j < n; ++j) {
          printf("%d ", xs[j]);
        }
        puts("");
        exit(0);
      }
      continue;
    }
    if (check(2 * xnum + x, 2 * xnum + (1 - x))) {
      continue;
    }
    if (check(2 * xnum + x, 2 * ynum + (1 - y)) &&
        check(2 * ynum + y, 2 * xnum + (1 - x))) {
      continue;
    }
    if (check(2 * ynum + y, 2 * ynum + (1 - y))) {
      continue;
    }
    if (check(2 * ynum + y, 2 * xnum + (1 - x)) &&
        check(2 * xnum + x, 2 * ynum + (1 - y))) {
      continue;
    }
    add(xnum, 1 - x, xnum, x);
    add(ynum, 1 - y, ynum, y);
    build();
    for (int j = 0; j < n; ++j) {
      printf("%d ", xs[j]);
    }
    puts("");
    exit(0);
  }
}
int main() {
  int m1, m2;
  scanf("%d %d %d", &n, &m1, &m2);
  f.read(m1);
  g.read(m2);
  solve(f, g);
  solve(g, f);
  puts("SIMILAR");
  return 0;
}
