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 get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9') s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9') s = s * 10 + ch - '0';
  return s;
}
const int N = 2005;
int n, m1, m2;
struct edge {
  int x, nxt;
};
struct two_satisfiability {
  edge e[N * N];
  int h[N], tot;
  void inse(int x, int y) {
    e[++tot].x = y;
    e[tot].nxt = h[x];
    h[x] = tot;
  }
  void read(int m) {
    for (int i = 1; i <= n * 2 + 1; i++) h[i] = 0;
    tot = k = u = 0;
    for (int i = 1; i <= m; i++) {
      int x = get(), y = get();
      if (x > 0)
        x = x * 2;
      else
        x = -2 * x + 1;
      if (y > 0)
        y = y * 2;
      else
        y = -2 * y + 1;
      inse(x, y ^ 1);
      inse(y, x ^ 1);
    }
  }
  int k, dfn[N], f[N];
  int be[N], u;
  int sta[N], top;
  bool pd[N];
  void tarjan(int x) {
    dfn[x] = f[x] = ++k;
    pd[sta[++top] = x] = 1;
    for (int p = h[x]; p; p = e[p].nxt)
      if (!dfn[e[p].x]) {
        tarjan(e[p].x);
        f[x] = min(f[x], f[e[p].x]);
      } else if (pd[e[p].x])
        f[x] = min(f[x], dfn[e[p].x]);
    if (f[x] == dfn[x]) {
      u++;
      while (sta[top + 1] != x) {
        pd[sta[top]] = 0;
        be[sta[top]] = u;
        top--;
      }
    }
  }
  bitset<N> can[N];
  int vis[N], tim;
  bool sol;
  bool both[N][N];
  int nd[10];
  bool tr[10][10];
  bool circle(int x) {
    if (vis[x] == tim) return 1;
    vis[x] = tim;
    for (int i = 1; i <= 4; i++)
      if (x != i && tr[x][i])
        if (circle(i)) return 1;
    vis[x] = tim - 1;
    return 0;
  }
  void build(const bool sig = 0) {
    k = u = top = tim = 0;
    for (int i = 1; i <= n * 2 + 1; i++)
      pd[i] = 0, vis[i] = dfn[i] = f[i] = be[i] = 0;
    for (int i = 2; i <= n * 2 + 1; i++)
      if (!dfn[i]) tarjan(i);
    for (int i = 1; i <= u; i++) can[i].reset();
    for (int i = 1; i <= u; i++) can[i][i] = 1;
    for (int i = 1; i <= u; i++) {
      for (int x = 2; x <= n * 2 + 1; x++)
        if (be[x] == i)
          for (int p = h[x]; p; p = e[p].nxt)
            if (be[e[p].x] != be[x]) can[i] = can[i] | can[be[e[p].x]];
    }
    sol = 1;
    for (int i = 1; i <= n; i++)
      if (be[i * 2] == be[i * 2 + 1]) sol = 0;
    if (sig) return;
    for (int i = 2; i <= n * 2 + 1; i++)
      if (!can[be[i]][be[i ^ 1]])
        for (int j = 2; j <= n * 2 + 1; j++)
          if (!can[be[j]][be[j ^ 1]])
            if (i != j) {
              for (int x = 1; x <= 4; x++)
                for (int y = 1; y <= 4; y++) tr[x][y] = 0;
              nd[1] = i, nd[2] = i ^ 1;
              nd[3] = j, nd[4] = j ^ 1;
              for (int x = 1; x <= 4; x++)
                for (int y = 1; y <= 4; y++)
                  if (x != y && can[be[nd[x]]][be[nd[y]]]) tr[x][y] = 1;
              tr[2][1] = tr[4][3] = 1;
              both[i][j] = 1;
              for (int x = 1; x <= 4; x++) {
                tim++;
                if (circle(x)) both[i][j] = 0;
              }
            }
  }
  int col[N];
  int d[N], res;
  void color2(int x) {
    if (col[x]) return;
    col[x] = 2;
    for (int i = 1; i <= u; i++)
      if (can[i][x]) color2(i);
  }
  void getsol() {
    for (int i = 1; i <= u; i++) d[i] = col[i] = 0;
    for (int i = 1; i <= u; i++)
      for (int j = 1; j <= u; j++)
        if (i != j && can[i][j]) d[i]++;
    res = u;
    while (res) {
      int x;
      for (int i = 1; i <= u; i++)
        if (!d[i] && !col[i]) {
          x = i;
          break;
        }
      col[x] = 1;
      res--;
      for (int i = 1; i <= u; i++)
        if (!col[i] && can[i][x]) d[i]--;
      for (int i = 2; i <= n * 2 + 1; i++)
        if (be[i] == x) {
          color2(be[i ^ 1]);
        }
    }
    for (int i = 1; i <= n; i++)
      if (col[be[i * 2]] == 1)
        printf("0 ");
      else
        printf("1 ");
    putchar('\n');
  }
} A, B;
int main() {
  int tp = 1;
  n = get();
  m1 = get();
  m2 = get();
  A.read(m1);
  B.read(m2);
  A.build();
  B.build();
  if (!A.sol && !B.sol) return printf("SIMILAR\n"), 0;
  if (!A.sol && B.sol) {
    B.getsol();
    return 0;
  }
  if (A.sol && !B.sol) {
    A.getsol();
    return 0;
  }
  for (int i = 2; i <= n * 2 + 1; i++)
    for (int j = 2; j <= n * 2 + 1; j++)
      if (A.can[A.be[j]][A.be[i]] && B.both[i ^ 1][j]) {
        B.inse(i, i ^ 1);
        B.inse(j ^ 1, j);
        B.build(1);
        B.getsol();
        return 0;
      }
  for (int i = 2; i <= n * 2 + 1; i++)
    for (int j = 2; j <= n * 2 + 1; j++)
      if (B.can[B.be[j]][B.be[i]] && A.both[i ^ 1][j]) {
        A.inse(i, i ^ 1);
        A.inse(j ^ 1, j);
        A.build(1);
        A.getsol();
        return 0;
      }
  for (int i = 2; i <= n * 2 + 1; i++)
    if (!A.can[A.be[i]][A.be[i ^ 1]] && B.can[B.be[i]][B.be[i ^ 1]]) {
      A.inse(i ^ 1, i);
      A.build(1);
      A.getsol();
      return 0;
    }
  for (int i = 2; i <= n * 2 + 1; i++)
    if (A.can[A.be[i]][A.be[i ^ 1]] && !B.can[B.be[i]][B.be[i ^ 1]]) {
      B.inse(i ^ 1, i);
      B.build(1);
      B.getsol();
      return 0;
    }
  printf("SIMILAR\n");
  return 0;
}
