#include <bits/stdc++.h>
const int N = 5e2, M = 1e3;
int Mod;
void inc(int &x, int y) { x -= Mod - y, x += x >> 31 & Mod; }
int add(int x, int y) { inc(x, y); return x; }
void dec(int &x, int y) { x -= y, x += x >> 31 & Mod; }
int del(int x, int y) { dec(x, y); return x; }
int qpow(int x, int y) {
int ans = 1;
for (; y; x = 1ll * x * x % Mod, y >>= 1) if (y & 1) ans = 1ll * ans * x % Mod;
return ans;
}
int n, m;
struct Edge { int x, y, z; }ed[M + 5];
std::vector<std::array<int, 2>> v[N + 5];
bool ont[M + 5], vis[N + 5];
int dep[N + 5], fa[N + 5];
void dfs(int x) {
vis[x] = 1;
for (auto [i, c] : v[x]) if (!vis[i]) ont[c] = 1, dep[i] = dep[x] + 1, fa[i] = c, dfs(i);
}
struct DSU {
int fa[M + 5];
void init() { for (int i = 1; i <= m; ++i) fa[i] = i; }
int getfa(int x) { return x ^ fa[x] ? fa[x] = getfa(fa[x]) : x; }
void merge(int x, int y) { fa[getfa(x)] = getfa(y); }
}ds;
int sum[M + 5];
std::set<int> nd[M + 5];
int cv[M + 5], rep[M + 5];
std::vector<std::vector<int>> ans;
std::vector<int> tmp;
void opt(int x, int y, int v) {
tmp.push_back(v);
if (y) tmp.push_back(y);
for (int i = 1; i <= m; ++i) if (ont[i] and i != x) tmp.push_back(i);
ans.push_back(tmp), tmp.clear();
}
int seq[M + 5];
int main() {
// freopen("code.in", "r", stdin);
// freopen("code.out", "w", stdout);
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m >> Mod;
for (int i = 1; i <= m; ++i) {
std::cin >> ed[i].x >> ed[i].y >> ed[i].z;
v[ed[i].x].push_back({ed[i].y, i}), v[ed[i].y].push_back({ed[i].x, i});
}
dfs(1);
for (int i = 1; i <= m; ++i) if (dep[ed[i].x] < dep[ed[i].y]) std::swap(ed[i].x, ed[i].y);
ds.init();
for (int i = 1; i <= m; ++i)
for (int j = ed[i].x; j != ed[i].y and j; j = ed[fa[j]].y) ds.merge(i, fa[j]);
for (int i = 1; i <= m; ++i) {
int x = ds.getfa(i);
inc(sum[x], ed[i].z), nd[x].insert(ed[i].x), nd[x].insert(ed[i].y);
}
int pre = -1;
for (int i = 1; i <= m; ++i) if (nd[i].size()) {
if (!((nd[i].size() - 1) % Mod)) {
if (sum[i]) { std::cout << "-1\n"; return 0; }
continue;
}
sum[i] = 1ll * sum[i] * qpow(nd[i].size() - 1, Mod - 2) % Mod;
if ((~pre) and sum[i] != pre) { std::cout << "-1\n"; return 0; }
pre = sum[i];
}
if (~pre) opt(0, 0, pre);
for (int i = 1; i <= m; ++i) if (ont[i]) dec(ed[i].z, pre);
for (int i = 1; i <= m; ++i) if (!ont[i]) {
for (int j = ed[i].x; j != ed[i].y; j = ed[fa[j]].y) {
if (ed[fa[j]].y == ed[i].y) cv[i] = fa[j];
else cv[fa[j]] = i;
}
opt(cv[i], i, ed[i].z), opt(0, 0, del(0, ed[i].z)), inc(ed[cv[i]].z, ed[i].z), ed[i].z = 0;
}
for (int i = 1; i <= m; ++i) seq[i] = i;
std::sort(seq + 1, seq + 1 + m, [&](int p, int q) { return dep[ed[p].x] > dep[ed[q].x]; });
for (int i = 1; i <= m; ++i) if (ont[seq[i]] and cv[seq[i]]) {
int p = seq[i], q = cv[cv[p]];
assert(ed[p].z < Mod and ed[p].z >= 0)
opt(q, cv[p], ed[p].z);
opt(p, cv[p], del(0, ed[p].z));
inc(ed[q].z, ed[p].z), ed[p].z = 0;
}
std::cout << ans.size() << "\n";
for (auto v : ans) {
for (auto i : v) std::cout << i << " ";
std::cout << "\n";
}
return 0;
}