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;
const int inf = 1000000001;
const int MOD = 1000000007;
int n;
vector<int> g[3039], gt[3039];
vector<bool> used;
vector<int> order, comp;
void dfs1(int v) {
  used[v] = true;
  for (size_t i = 0; i < g[v].size(); ++i) {
    int to = g[v][i];
    if (!used[to]) dfs1(to);
  }
  order.push_back(v);
}
void dfs2(int v, int cl) {
  comp[v] = cl;
  for (size_t i = 0; i < gt[v].size(); ++i) {
    int to = gt[v][i];
    if (comp[to] == -1) dfs2(to, cl);
  }
}
int m1, m2;
const int N = 1009;
int x1[N * N + 1], x2[N * N + 1], jasdf[N * N + 1], y2[N * N + 1];
bool get2(vector<bool> &ans) {
  bool ret = 1;
  for (int i = (1); i <= (m2); ++i) {
    bool v1 = ans[abs(x2[i]) / 2];
    if (x2[i] & 1) v1 = !v1;
    bool v2 = ans[abs(y2[i]) / 2];
    if (y2[i] & 1) v2 = !v2;
    ret &= (v1 || v2);
  }
  return ret;
}
bool get1(vector<bool> &ans) {
  bool ret = 1;
  for (int i = (1); i <= (m1); ++i) {
    bool v1 = ans[abs(x1[i]) / 2];
    if (x1[i] & 1) v1 = !v1;
    bool v2 = ans[abs(jasdf[i]) / 2];
    if (jasdf[i] & 1) v2 = !v2;
    ret &= (v1 || v2);
    if (!ret) break;
  }
  return ret;
}
const int F = 2019;
int get(int v) {
  if (v > 0) return 2 * (v - 1);
  return 2 * (abs(v) - 1) + 1;
}
inline void add_edge(int x, int y) {
  g[x].push_back(y);
  gt[y].push_back(x);
}
int main() {
  int n;
  cin >> n >> m1 >> m2;
  for (int i = (1); i <= (m1); ++i) {
    scanf("%d %d", &x1[i], &jasdf[i]);
    x1[i] = get(x1[i]);
    jasdf[i] = get(jasdf[i]);
  }
  for (int i = (1); i <= (m2); ++i) {
    scanf("%d %d", &x2[i], &y2[i]);
    x2[i] = get(x2[i]);
    y2[i] = get(y2[i]);
  }
  srand(239);
  for (int iter = (0); iter <= (1); ++iter) {
    double was = clock();
    while (clock() - was < 1.1 * CLOCKS_PER_SEC) {
      for (int i = (0); i <= (F); ++i) g[i].clear(), gt[i].clear();
      for (int i = (1); i <= (m1); ++i) {
        add_edge(x1[i] ^ 1, jasdf[i]);
        add_edge(jasdf[i] ^ 1, x1[i]);
      }
      for (int i = (0); i <= (F); ++i) random_shuffle(g[i].begin(), g[i].end());
      for (int i = (0); i <= (F); ++i)
        random_shuffle(gt[i].begin(), gt[i].end());
      used.assign(F + 1, false);
      order.clear();
      vector<int> temp;
      for (int i = (0); i <= (n + n - 1); ++i) temp.push_back(i);
      random_shuffle(temp.begin(), temp.end());
      for (int ii = 0; ii < n + n; ++ii) {
        int i = temp[ii];
        if (!used[i]) dfs1(i);
      }
      comp.assign(F, -1);
      temp.clear();
      int j = 0;
      for (int i = (0); i <= (n + n - 1); ++i) temp.push_back(i);
      for (int ii = (0); ii <= ((int)((temp).size()) - 1); ++ii) {
        int i = temp[ii];
        int v = order[n + n - i - 1];
        if (comp[v] == -1) dfs2(v, j++);
      }
      vector<bool> ans;
      for (int i = 0; i < n + n; i += 2) {
        ans.push_back(comp[i] >= comp[i ^ 1]);
      }
      if (get1(ans) != get2(ans)) {
        for (int i = (0); i <= (n - 1); ++i) cout << ans[i] << " ";
        cout << endl;
        return 0;
      }
    }
    for (int i = (1); i <= (max(m1, m2)); ++i) {
      swap(x1[i], x2[i]);
      swap(jasdf[i], y2[i]);
    }
    swap(m1, m2);
  }
  cout << "SIMILAR" << endl;
}
