#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T gcd(T a, T b) {
  if (a < 0) return gcd(-a, b);
  if (b < 0) return gcd(a, -b);
  return (b == 0) ? a : gcd(b, a % b);
}
template <class T>
inline T lcm(T a, T b) {
  if (a < 0) return lcm(-a, b);
  if (b < 0) return lcm(a, -b);
  return a * (b / gcd(a, b));
}
template <class T>
T power(T N, T P) {
  return (P == 0) ? 1 : N * power(N, P - 1);
}
long long toInt64(string s) {
  long long r = 0;
  istringstream sin(s);
  sin >> r;
  return r;
}
double LOG(long long N, long long B) { return (log10l(N)) / (log10l(B)); }
string itoa(long long a) {
  if (a == 0) return "0";
  string ret;
  for (long long i = a; i > 0; i = i / 10) ret.push_back((i % 10) + 48);
  reverse(ret.begin(), ret.end());
  return ret;
}
vector<string> token(string a, string b) {
  const char *q = a.c_str();
  while (count(b.begin(), b.end(), *q)) q++;
  vector<string> oot;
  while (*q) {
    const char *e = q;
    while (*e && !count(b.begin(), b.end(), *e)) e++;
    oot.push_back(string(q, e));
    q = e;
    while (count(b.begin(), b.end(), *q)) q++;
  }
  return oot;
}
int Set(int N, int pos) { return N = N | (1 << pos); }
int reset(int N, int pos) { return N = N & ~(1 << pos); }
int check(int N, int pos) { return (N & (1 << pos)); }
int toggle(int N, int pos) {
  if (check(N, pos)) return N = reset(N, pos);
  return N = Set(N, pos);
}
void pbit(int N) {
  printf("(");
  for (int i = 10; i >= 0; i--) {
    bool x = check(N, i);
    cout << x;
  }
  puts(")");
}
int fx[] = {0, 0, 1, -1, 1, -1, 1, -1};
int fy[] = {-1, 1, 0, 0, -1, -1, 1, 1};
int n, e;
vector<int> g[1000], r[1000], DAG[1000];
vector<int> C[1000];
int color[1000];
vector<int> out;
bool vis[1000];
void AND(int u, int v) {
  g[u].push_back(v);
  g[v].push_back(u);
  g[u + n].push_back(v + n);
  g[v + n].push_back(u + n);
}
void XOR(int u, int v) {
  g[v + n].push_back(u);
  g[u].push_back(v + n);
  g[u + n].push_back(v);
  g[v].push_back(u + n);
}
void make_reverse(int n) {
  for (int u = 1; u <= (int)n + n; u++) {
    for (int i = 0; i < (int)g[u].size(); i++) {
      int v = g[u][i];
      r[v].push_back(u);
    }
  }
}
void dfs(int u) {
  if (!vis[u]) {
    vis[u] = 1;
    for (int i = 0; i < (int)g[u].size(); i++) dfs(g[u][i]);
    out.push_back(u);
  }
}
vector<int> sort(int n) {
  for (int i = 1; i <= n + n; i++) dfs(i);
  reverse(out.begin(), out.end());
  return out;
}
void scc(int u, int mark) {
  C[mark].push_back(u);
  color[u] = mark;
  for (int i = 0; i < (int)r[u].size(); i++) {
    int v = r[u][i];
    if (!vis[v]) {
      vis[v] = 1;
      scc(v, mark);
    }
  }
}
bool two_sat(int n, vector<int> &res) {
  vector<int> out = sort(n);
  memset(vis, 0, sizeof(vis));
  ;
  int comp = 0;
  for (int i = 0; i < (int)out.size(); i++) {
    int u = out[i];
    if (!vis[u]) {
      vis[u] = 1;
      scc(u, ++comp);
    }
  }
  for (int u = 1; u <= (int)n + n; u++) {
    if (color[u] == color[u + n]) {
      return 0;
    }
    for (int j = 0; j < (int)g[u].size(); j++) {
      int v = g[u][j];
      if (color[u] == color[v]) continue;
      DAG[color[u]].push_back(color[v]);
    }
  }
  bool valid[1000];
  memset(valid, 1, sizeof(valid));
  ;
  for (int i = comp; i >= 1; i--) {
    for (int j = 0; j < (int)DAG[i].size(); j++) {
      if (!valid[DAG[i][j]]) {
        valid[i] = 0;
        break;
      }
    }
    if (!valid[i]) continue;
    for (int j = 0; j < (int)C[i].size(); j++) {
      int u = C[i][j];
      if (u <= n) {
        res.push_back(u);
      }
      valid[color[u + n]] = 0;
    }
  }
  return true;
}
int main() {
  cin >> n >> e;
  for (int i = 1; i <= e; i++) {
    int u, v, c;
    cin >> u >> v >> c;
    if (c == 0) XOR(u, v);
    if (c == 1) AND(u, v);
  }
  make_reverse(n);
  vector<int> res;
  int ret = two_sat(n, res);
  if (ret) {
    cout << res.size() << endl;
    for (int i = 0; i < (int)res.size(); i++) cout << res[i] << " ";
    puts("");
  } else
    puts("Impossible");
  return 0;
}
