#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) cin>>a
#define pii pair<int,int>
//#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 5110;
const int M = 1e9+7;
int n,m,k,t = 15;

int head[maxn],to[maxn*2],Next[maxn*2],cnt = 1;

void add(int u,int v)
{
    to[cnt] = v;Next[cnt] = head[u];head[u] = cnt;cnt++;
}

int ans[maxn][maxn];
bool flag = true;

int d[maxn];
int fa[maxn][16];

void dfs(int u,int pre)
{
    d[u] = d[pre]+1;
    fa[u][0] = pre;
    for(int i = 1; (i<<1) <= d[u]; i++)
    {
        fa[u][i] = fa[fa[u][i-1]][i-1];
    }
    for(int i = head[u]; i ; i = Next[i])
    {
        int v = to[i];
        if(v == pre) continue;
        dfs(v,u);
    }
}

int lca(int x,int y)
{
    if(d[x] > d[y]) swap(x,y);
    for(int i = t; i >= 0; i--)
    {
        if(d[fa[y][i]] >= d[x]) y = fa[y][i];
    }
    if(y == x) return x;
    for(int i = t; i >= 0; i--)
    {
        if(fa[x][i] != fa[y][i])
        {
            x = fa[x][i];
            y = fa[y][i];
        }
    }
    return fa[x][0];
}

void solve(int u,int z)
{
    while(u != k)
    {
        int v = fa[u][0];

        if(ans[u][v] == 0)
        {
            ans[u][v] = ans[v][u] = z;
        }
        else
        {
            if(ans[u][v] < z)
            {
                flag = false;
            }
        }

        u = v;
    }
}

signed main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    cin>>n;
    for(int i = 1,x,y; i < n; i++)
    {
        cin>>x>>y;
        add(x,y);add(y,x);
    }
    dfs(1,0);
    cin>>m;
    for(int i = 1,x,y,z; i <= m; i++)
    {
        cin>>x>>y>>z;
        k = lca(x,y);
        solve(x,z);solve(y,z);
    }
    if(flag)
    {
        for(int i = 1; i < n; i++)
        {
            int u = to[i*2];
            int v = to[i*2-1];
            if(ans[u][v] == 0) ans[u][v] = 1;
            cout<<ans[u][v]<<' ';
        }
    }
    else puts("-1");
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) cin>>a
#define pii pair<int,int>
//#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 5110;
const int M = 1e9+7;
int n,m,k,t = 19;

int head[maxn],to[maxn*2],Next[maxn*2],cnt = 1;

void add(int u,int v)
{
    to[cnt] = v;Next[cnt] = head[u];head[u] = cnt;cnt++;
}

int ans[maxn][maxn];
bool flag = true;

int d[maxn];
int fa[maxn][20];

void dfs(int u,int pre)
{
    d[u] = d[pre]+1;
    fa[u][0] = pre;
    for(int i = 1; (i<<1) <= d[u]; i++)
    {
        fa[u][i] = fa[fa[u][i-1]][i-1];
    }
    for(int i = head[u]; i ; i = Next[i])
    {
        int v = to[i];
        if(v == pre) continue;
        dfs(v,u);
    }
}

int lca(int x,int y)
{
    if(d[x] > d[y]) swap(x,y);
    for(int i = t; i >= 0; i--)
    {
        if(d[fa[y][i]] >= d[x]) y = fa[y][i];
    }
    if(y == x) return x;
    for(int i = t; i >= 0; i--)
    {
        if(fa[x][i] != fa[y][i])
        {
            x = fa[x][i];
            y = fa[y][i];
        }
    }
    return fa[x][0];
}

struct node
{
    int x,y,z;
}q[maxn];

bool cmp(node a,node b)
{
    return a.z < b.z;
}

void solve(int u,int z)
{
    while(u != k)
    {
        int v = fa[u][0];
        ans[u][v] = max(ans[u][v],z);
        ans[v][u] = max(ans[v][u],z);
        //cout<<u<<' '<<v<<' '<<ans[u][v]<<' '<<ans[v][u]<<endl;
        u = v;
    }
}

int query(int u)
{
    int res = inf;
    while(u != k)
    {
        int v = fa[u][0];
        res = min(res,ans[u][v]);
        u = v;
    }
    return res;
}

signed main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif

    ios::sync_with_stdio(false);
    cin.tie(0);
    mem(d,0);
    vector<pii> v;
    cin>>n;
    for(int i = 1,x,y; i < n; i++)
    {
        cin>>x>>y;
        add(x,y);add(y,x);
        v.push_back({x,y});
    }
    dfs(1,0);
    cin>>m;
    for(int i = 0; i < m; i++)
    {
        cin>>q[i].x>>q[i].y>>q[i].z;
    }
    sort(q,q+m,cmp);
    for(int i = 0; i < m; i++)
    {
        k = lca(q[i].x,q[i].y);
        solve(q[i].x,q[i].z);solve(q[i].y,q[i].z);
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            if(ans[i][j] == 0) ans[i][j] = 1000000;
        }
    }
    for(int i = 0; i < m; i++)
    {
        k = lca(q[i].x,q[i].y);
        int tmp = query(q[i].x);
        tmp = min(tmp,query(q[i].y));
        if(tmp != q[i].z)
        {
            puts("-1");
            return 0;
        }
    }
    for(auto i : v)
    {
        cout<<ans[i.first][i.second]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) cin>>a
#define pii pair<int,int>
//#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 5110;
const int M = 1e9+7;
int n,m,k,t = 29;

int head[maxn],to[maxn*2],Next[maxn*2],cnt = 1;

void add(int u,int v)
{
    to[cnt] = v;Next[cnt] = head[u];head[u] = cnt;cnt++;
}

int ans[maxn][maxn];
bool flag = true;

int d[maxn];
int fa[maxn][30];

void dfs(int u,int pre)
{
    if(d[u]) return;
    d[u] = d[pre]+1;
    fa[u][0] = pre;
    for(int i = 1; (i<<1) <= d[u]; i++)
    {
        fa[u][i] = fa[fa[u][i-1]][i-1];
    }
    for(int i = head[u]; i ; i = Next[i])
    {
        int v = to[i];
        if(v == pre) continue;
        dfs(v,u);
    }
}

int lca(int x,int y)
{
    if(d[x] > d[y]) swap(x,y);
    for(int i = t; i >= 0; i--)
    {
        if(d[fa[y][i]] >= d[x]) y = fa[y][i];
    }
    if(y == x) return x;
    for(int i = t; i >= 0; i--)
    {
        if(fa[x][i] != fa[y][i])
        {
            x = fa[x][i];
            y = fa[y][i];
        }
    }
    return fa[x][0];
}

struct node
{
    int x,y,z;
}q[maxn];

bool cmp(node a,node b)
{
    return a.z < b.z;
}

void solve(int u,int z)
{
    while(u != k)
    {
        int v = fa[u][0];
        ans[u][v] = max(ans[u][v],z);
        ans[v][u] = max(ans[v][u],z);
        //cout<<u<<' '<<v<<' '<<ans[u][v]<<' '<<ans[v][u]<<endl;
        u = v;
    }
}

int query(int u)
{
    int res = inf;
    while(u != k)
    {
        int v = fa[u][0];
        res = min(res,ans[u][v]);
        u = v;
    }
    return res;
}

signed main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("data.in", "r", stdin);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    vector<pii> v;
    cin>>n;
    for(int i = 1,x,y; i < n; i++)
    {
        cin>>x>>y;
        add(x,y);add(y,x);
        v.push_back({x,y});
    }
    dfs(1,0);
    cin>>m;
    for(int i = 0; i < m; i++)
    {
        cin>>q[i].x>>q[i].y>>q[i].z;
    }
    sort(q,q+m,cmp);
    for(int i = 0; i < m; i++)
    {
        k = lca(q[i].x,q[i].y);
        solve(q[i].x,q[i].z);solve(q[i].y,q[i].z);
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            if(ans[i][j] == 0) ans[i][j] = 1000000;
        }
    }
    for(int i = 0; i < m; i++)
    {
        k = lca(q[i].x,q[i].y);
        int tmp = query(q[i].x);
        tmp = min(tmp,query(q[i].y));
        if(tmp != q[i].z)
        {
            puts("-1");
            return 0;
        }
    }
    for(auto i : v)
    {
        cout<<ans[i.first][i.second]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,m;
vector<int>v[N];
int ans[N];
struct uzi{
  int a,b,c;
  bool operator <(const uzi & t)const{
    return c>t.c;
  }
}p[N];
int pr[N];
int ed[5001][5001];
int dfs(int now,int d,int pre){
  pr[now]=pre;
  if(now==d){
    return 1;
  }
 // cout<<now<<' '<<pre<<endl;
  for(auto k:v[now]){
    if(k==pre)
      continue;
    if(dfs(k,d,now))return 1;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  for(int i=1;i<n;i++){
    int s,t;
    cin>>s>>t;
    ed[s][t]=ed[t][s]=i;
    v[s].pb(t);
    v[t].pb(s);
    ans[i]=1e6;
  }
  cin>>m;
  for(int i=1;i<=m;i++){
    int l,r,w;
    cin>>l>>r>>w;
    p[i]={l,r,w};
  }
  sort(p+1,p+1+m);
  for(int i=1;i<=m;i++){
    dfs(p[i].a,p[i].b,0);
    int sta=0;
    while(pr[p[i].b]){
      int x=p[i].b,y=pr[p[i].b];
      x=ed[x][y];
      if(!ans[x]){
        sta=1;
      }
      ans[x]=max(ans[x],p[i].c);
      p[i].b=pr[p[i].b];
    }
    if(!sta)return cout<<-1,0;
  }
  for(int i=1;i<n;i++)cout<<ans[i]<< ' ';
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,m;
vector<int>v[N];
int ans[N];
struct uzi{
  int a,b,c;
  bool operator <(const uzi & t)const{
    return c>t.c;
  }
}p[N];
int pr[N];
int ed[5001][5001];
int dfs(int now,int d,int pre){
  pr[now]=pre;
  if(now==d){
    return 1;
  }
 // cout<<now<<' '<<pre<<endl;
  for(auto k:v[now]){
    if(k==pre)
      continue;
    if(dfs(k,d,now))return 1;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  for(int i=1;i<n;i++){
    int s,t;
    cin>>s>>t;
    ed[s][t]=ed[t][s]=i;
    v[s].pb(t);
    v[t].pb(s);
    ans[i]=0;
  }
  cin>>m;
  for(int i=1;i<=m;i++){
    int l,r,w;
    cin>>l>>r>>w;
    p[i]={l,r,w};
  }
  sort(p+1,p+1+m);
  for(int i=1;i<=m;i++){
    dfs(p[i].a,p[i].b,0);
    int sta=0;
    while(pr[p[i].b]){
      int x=p[i].b,y=pr[p[i].b];
      x=ed[x][y];
      if(!ans[x]){
        sta=1;
      }
      ans[x]=max(ans[x],p[i].c);
      p[i].b=pr[p[i].b];
    }
    if(!sta)return cout<<-1,0;
  }
  for(int i=1;i<n;i++){
    if(!ans[i])ans[i]=1e6;
    cout<<ans[i]<< ' ';
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,m;
vector<int>v[N];
int ans[N];
struct uzi{
  int a,b,c;
  bool operator <(const uzi & t)const{
    return c>t.c;
  }
}p[N];
int pr[N];
int ed[5001][5001];
int dfs(int now,int d,int pre){
  pr[now]=pre;
  if(now==d){
    return 1;
  }
 // cout<<now<<' '<<pre<<endl;
  for(auto k:v[now]){
    if(k==pre)
      continue;
    if(dfs(k,d,now))return 1;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  for(int i=1;i<n;i++){
    int s,t;
    cin>>s>>t;
    ed[s][t]=ed[t][s]=i;
    v[s].pb(t);
    v[t].pb(s);
    ans[i]=0;
  }
  cin>>m;
  for(int i=1;i<=m;i++){
    int l,r,w;
    cin>>l>>r>>w;
    p[i]={l,r,w};
  }
  sort(p+1,p+1+m);
  for(int i=1;i<=m;i++){
    dfs(p[i].a,p[i].b,0);
    int sta=0;
    while(pr[p[i].b]){
      int x=p[i].b,y=pr[p[i].b];
      x=ed[x][y];
      if(!ans[x]||ans[x]==p[i].c){
        sta=1;
      }
      ans[x]=max(ans[x],p[i].c);
      p[i].b=pr[p[i].b];
    }
    if(!sta)return cout<<-1,0;
  }
  for(int i=1;i<n;i++){
    if(!ans[i])ans[i]=1e6;
    cout<<ans[i]<< ' ';
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,m;
vector<int>v[N];
int ans[N];
struct uzi{
  int a,b,c;
  bool operator <(const uzi & t)const{
    return c>t.c;
  }
}p[N];
int pr[N];
int ed[5001][5001];
int dfs(int now,int d,int pre){
  pr[now]=pre;
  if(now==d){
    return 1;
  }
 // cout<<now<<' '<<pre<<endl;
  for(auto k:v[now]){
    if(k==pre)
      continue;
    if(dfs(k,d,now))return 1;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin>>n;
  for(int i=1;i<n;i++){
    int s,t;
    cin>>s>>t;
    ed[s][t]=ed[t][s]=i;
    v[s].pb(t);
    v[t].pb(s);
    ans[i]=0;
  }
  cin>>m;
  for(int i=1;i<=m;i++){
    int l,r,w;
    cin>>l>>r>>w;
    p[i]={l,r,w};
  }
  sort(p+1,p+1+m);
  for(int i=1;i<=m;i++){
    dfs(p[i].a,p[i].b,0);
    int sta=0;
    while(pr[p[i].b]){
      int x=p[i].b,y=pr[p[i].b];
      x=ed[x][y];
      if(ans[x]<=p[i].c){
        sta=1;
      }
      ans[x]=max(ans[x],p[i].c);
      p[i].b=pr[p[i].b];
    }
    if(!sta)return cout<<-1,0;
  }
  for(int i=1;i<n;i++){
    if(!ans[i])ans[i]=1e6;
    cout<<ans[i]<< ' ';
  }
  return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef tuple<int, int, int> iii;

#define g(a, i) get<(i)>((a))

const int mx = 5005;
const int val = 1000000;

vector< pii > pairs;
vector< int > adj[mx];

int n;
int vis[mx];
int par[mx][mx];
int ans[mx][mx];

int root;
void dfs(int u, int p){
    vis[u] = 1;
    par[root][u] = p;
    for(int v:adj[u])
        if(!vis[v])
            dfs(v, u);
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);

    cin >> n; int u, v, w;
    for(int i=1; i<n; i++){
        cin >> u >> v;
        pairs.push_back({u,v});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

//    for(int i=1; i<=n; i++)
//    for(int j=1; j<=n; j++)
//        ans[i][j] = val;

    for(int i=1; i<=n; i++){
        memset(vis, 0, sizeof vis);
        root = i;
        dfs(i, i);
    }

    int q; cin >> q; iii qq[q];
    for(int i=0; i<q; i++){
        cin >> get<0>(qq[i]);
        cin >> get<1>(qq[i]);
        cin >> get<2>(qq[i]);
    }

    sort(qq, qq+q, [&](iii &a, iii &b){
        return get<2>(a) < get<2>(b);});

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        while(1){
            int p = par[u][v];
            if(ans[p][v]<=w)
                ans[p][v] = ans[v][p] = w;
            if(p == u) break; v = p;
        }
    }

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        int tmp = val;
        while(1){
            int p = par[u][v];
            tmp = min(tmp, ans[p][v]);
            if(p == u) break; v = p;
        }
        if(tmp != w)
            return cout << "-1\n", 0;
    }

    for(auto p:pairs){
        u = ans[p.first][p.second];
        if(u == 0) u = val;
        cout << u << " ";
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef tuple<int, int, int> iii;

#define g(a, i) get<(i)>((a))

const int mx = 5005;
const int val = 1000000;

vector< pii > pairs;
vector< int > adj[mx];

int n;
int vis[mx];
int par[mx][mx];
int ans[mx][mx];

int root;
void dfs(int u, int p){
    vis[u] = 1;
    par[root][u] = p;
    for(int v:adj[u])
        if(!vis[v])
            dfs(v, u);
}

int main(){
    ///ios_base::sync_with_stdio(0); cin.tie(0);

    cin >> n; int u, v, w;
    for(int i=1; i<n; i++){
        cin >> u >> v;
        pairs.push_back({u,v});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

//    for(int i=1; i<=n; i++)
//    for(int j=1; j<=n; j++)
//        ans[i][j] = val;

    for(int i=1; i<=n; i++){
        memset(vis, 0, sizeof vis);
        root = i;
        dfs(i, i);
    }

    int q; cin >> q; iii qq[q];
    for(int i=0; i<q; i++){
        cin >> get<0>(qq[i]);
        cin >> get<1>(qq[i]);
        cin >> get<2>(qq[i]);
    }

    sort(qq, qq+q, [&](iii &a, iii &b){
        return get<2>(a) < get<2>(b);});

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        while(1){
            int p = par[u][v];
            if(ans[p][v]<=w)
                ans[p][v] = ans[v][p] = w;
            if(p == u) break; v = p;
        }
    }

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        int tmp = val;
        while(1){
            int p = par[u][v];
            tmp = min(tmp, ans[p][v]);
            if(p == u) break; v = p;
        }
        if(tmp != w)
            return cout << "-1\n", 0;
    }

    for(auto p:pairs){
        u = ans[p.first][p.second];
        if(u == 0) u = val;
        cout << u << " ";
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef tuple<int, int, int> iii;

#define g(a, i) get<(i)>((a))

const int mx = 5005;
const int val = 1000000;

vector< pii > pairs;
vector< int > adj[mx];

int n;
int vis[mx];
int par[mx][mx];
int ans[mx][mx];

int root;
void dfs(int u, int p){
    vis[u] = 1;
    par[root][u] = p;
    for(int v:adj[u])
        if(!vis[v])
            dfs(v, u);
}

int main(){
    ///ios_base::sync_with_stdio(0); cin.tie(0);

    cin >> n; int u, v, w;
    for(int i=1; i<n; i++){
        cin >> u >> v;
        pairs.push_back({u,v});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

//    for(int i=1; i<=n; i++)
//    for(int j=1; j<=n; j++)
//        ans[i][j] = val;

    for(int i=1; i<=n; i++){
        memset(vis, 0, sizeof vis);
        root = i;
        dfs(i, i);
    }

    int q; cin >> q; iii qq[q];
    for(int i=0; i<q; i++){
        cin >> get<0>(qq[i]);
        cin >> get<1>(qq[i]);
        cin >> get<2>(qq[i]);
    }

    sort(qq, qq+q, [&](iii &a, iii &b){
        return get<2>(a) < get<2>(b);});

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        while(1){
            int p = par[u][v];
            if(ans[p][v]<=w)
                ans[p][v] = ans[v][p] = w;
            if(p == u) break; v = p;
        }
    }

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        int tmp = val;
        while(1){
            int p = par[u][v];
            tmp = min(tmp, ans[p][v]);
            if(p == u) break; v = p;
        }
        if(tmp != w)
            return cout << "-1\n", 0;
    }

    for(auto p:pairs)
        cout << ans[p.first][p.second] << " ";

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef tuple<int, int, int> iii;

#define g(a, i) get<(i)>((a))

const int mx = 5005;
const int val = 1000000;

vector< pii > pairs;
vector< int > adj[mx];

int n;
int vis[mx][mx];
int par[mx][mx];
int ans[mx][mx];

int root;
void dfs(int u, int p){
    vis[root][u] = 1;
    par[root][u] = p;
    for(int v:adj[u])
        if(!vis[root][v])
            dfs(v, u);
}

int main(){
    ///ios_base::sync_with_stdio(0); cin.tie(0);

    cin >> n; int u, v, w;
    for(int i=1; i<n; i++){
        cin >> u >> v;
        pairs.push_back({u,v});
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

//    for(int i=1; i<=n; i++)
//    for(int j=1; j<=n; j++)
//        ans[i][j] = val;

    for(int i=1; i<=n; i++){
        root = i;
        dfs(i, i);
    }

    int q; cin >> q; iii qq[q];
    for(int i=0; i<q; i++){
        cin >> get<0>(qq[i]);
        cin >> get<1>(qq[i]);
        cin >> get<2>(qq[i]);
    }

    sort(qq, qq+q, [&](iii &a, iii &b){
        return get<2>(a) < get<2>(b);});

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        while(1){
            int p = par[u][v];
            if(ans[p][v]<=w)
                ans[p][v] = ans[v][p] = w;
            if(p == u) break; v = p;
        }
    }

    for(int i=0; i<q; i++){
        u = get<0>(qq[i]);
        v = get<1>(qq[i]);
        w = get<2>(qq[i]);

        int tmp = val;
        while(1){
            int p = par[u][v];
            tmp = min(tmp, ans[p][v]);
            if(p == u) break; v = p;
        }
        if(tmp != w)
            return cout << "-1\n", 0;
    }

    for(auto p:pairs)
        cout << ans[p.first][p.second] << " ";

    return 0;
}


#include <bits/stdc++.h>
#define foi(i,k,n) for (int i = (int)k; i < (int)n; ++i)

using namespace std;
using ii = pair<int,int>;
using ll = long long;

constexpr int MAXN = 5 + 5000;
constexpr int INF = 1000000;
int c[MAXN];
vector<ii> g[MAXN];
array<int,3> q[MAXN];

bool solve(int u, int t, int cost, int p) {
  if (u == t) return true;
  for (auto x : g[u]) {
    if (x.first == p) continue;
    if (solve(x.first,t,cost,u)) {
      int& e = c[x.second];
      if (e == -1) e = cost;
      else e = max(e, cost);
      return true;
    }
  }
  return false;
}

pair<int,bool> minedge(int u, int t, int p) {
  int ans = INF;
  bool ok = false;
  if (u == t) return {INF, true};
  for (auto x : g[u]) {
    if (x.first == p) continue;
    auto xv = minedge(x.first,t,u);
    if (xv.second) {
      ans = min(ans, min(xv.first, c[x.second]));
      ok = true;
    }
  }
  return {ans, ok};
}

int main() {
  ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
  int n,m; cin >> n;
  foi (i,0,n-1) {
    int u,v; cin >> u >> v;
    g[u].push_back({v, i});
    g[v].push_back({u, i});
    c[i] = -1;
  }
  cin >> m;
  foi (i,0,m) {
    foi (j,0,3) cin >> q[i][j];
    solve(q[i][0],q[i][1],q[i][2],-1);
  }
  foi (i,0,n-1) if (c[i] == -1) c[i] = INF;
  bool ok = true;
  foi (i,0,m) {
    ok &= (minedge(q[i][0], q[i][1], -1).first == q[i][2]);
    assert(minedge(q[i][0], q[i][1], -1).second);
  }
  if (ok) {
    foi (i,0,n-1) cout << c[i] << ' ';
    cout << '\n';
  } else {
    cout << -1 << '\n';
  }
  return 0;
}


#include <bits/stdc++.h>
#define foi(i,k,n) for (int i = (int)k; i < (int)n; ++i)

using namespace std;
using ii = pair<int,int>;
using ll = long long;

constexpr int MAXN = 5 + 5000;
constexpr int INF = 1000000;
int c[MAXN];
vector<ii> g[MAXN];
array<int,3> q[MAXN];

bool solve(int u, int t, int cost, int p) {
  if (u == t) return true;
  for (auto x : g[u]) {
    if (x.first == p) continue;
    if (solve(x.first,t,cost,u)) {
      int& e = c[x.second];
      if (e == -1) e = cost;
      else e = max(e, cost);
    }
  }
  return false;
}

pair<int,bool> minedge(int u, int t, int p) {
  int ans = INF;
  bool ok = false;
  if (u == t) return {INF, true};
  for (auto x : g[u]) {
    if (x.first == p) continue;
    auto xv = minedge(x.first,t,u);
    if (xv.second) {
      ans = min(ans, min(xv.first, c[x.second]));
      ok = true;
    }
  }
  return {ans, ok};
}

int main() {
  ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
  int n,m; cin >> n;
  foi (i,0,n-1) {
    int u,v; cin >> u >> v;
    g[u].push_back({v, i});
    g[v].push_back({u, i});
    c[i] = -1;
  }
  cin >> m;
  foi (i,0,m) {
    foi (j,0,3) cin >> q[i][j];
    solve(q[i][0],q[i][1],q[i][2],-1);
  }
  foi (i,0,n-1) if (c[i] == -1) c[i] = INF;
  bool ok = true;
  foi (i,0,m) {
    ok &= (minedge(q[i][0], q[i][1], -1).first == q[i][2]);
    assert(minedge(q[i][0], q[i][1], -1).second);
  }
  if (ok) {
    foi (i,0,n-1) cout << c[i] << ' ';
    cout << '\n';
  } else {
    cout << -1 << '\n';
  }
  return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <cstring>

using namespace std;

#define pb push_back
#define len length()
#define clr clear()

#define eps 0.0000001
#define PI  3.14159265359
#define inf 1999888777

int a[555333],req[555333],zd[555333];

int main() {

    int n,m,i,t,s,h,T,mn,br,lt,tt,bru;
    bool bio;

    scanf("%d%d%d", &n, &m, &T);

    br = 0;

    bio = false;

    bru = 0;

    lt = -1;

    for(i=0; i<n; i++) {
        scanf("%d:%d:%d", &h, &mn, &s);
        t = s + mn*60 + h*60*60;

        for(tt=lt+1; tt<=t; tt++) {
            if (tt >= T) br -= req[tt-T];
        }
        lt = t;

        req[t]++;

        br++;
        if (br <= m) {
            bru++;
            if (br == m) bio = true;
        } else {
            req[zd[bru]]--;
            br--;
        }
        a[i] = bru;
        zd[bru] = t;
    }

    if (bio) {
        printf("%d\n", bru);
        for(i=0; i<n; i++) printf("%d\n", a[i]);
    } else {
        printf("No solution\n");
    }

    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <cstring>

using namespace std;

#define pb push_back
#define len length()
#define clr clear()

#define eps 0.0000001
#define PI  3.14159265359
#define inf 1999888777

int a[555333],req[555333];

int main() {

    int n,m,i,t,s,h,T,mn,br,lt,tt,bru;
    bool bio;

    scanf("%d%d%d", &n, &m, &T);

    br = 0;

    bio = false;

    bru = 0;

    lt = -1;

    for(i=0; i<n; i++) {
        scanf("%d:%d:%d", &h, &mn, &s);
        t = s + mn*60 + h*60*60;

        for(tt=lt+1; tt<=t; tt++) {
            if (tt >= T) br -= req[tt-T];
        }
        lt = t;

        req[t]++;

        br++;
        if (br <= m) {
            bru++;
            a[i] = bru;
            if (br == m) bio = true;
        } else {
            a[i] = bru;
            br--;
        }
    }

    if (bio) {
        printf("%d\n", bru);
        for(i=0; i<n; i++) printf("%d\n", a[i]);
    } else {
        printf("No solution\n");
    }

    return 0;
}


#include <iostream>
#include <stdio.h>
#include <stdint.h>
#include <vector>
#include <deque>
#include <list>
#include <queue>
#include <set>
#include <utility>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <algorithm>

using namespace::std;

int main()
{
	int N, M, T;
	cin >> N >> M >> T;

	vector<vector<int> > A(86400);
	for (int i = 0; i < N; i++)
	{
		string str;
		cin >> str;

		int x = 3600 * (10 * (str[0] - '0') + str[1] - '0') + 60 * (10 * (str[3] - '0') + str[4] - '0') + (10 * (str[6] - '0') + str[7] - '0');
		A[x].push_back(i);
	}

	vector<int> id(N, -1);
	int cnt = 0;
	int mx = 0;

	map<int, int> mp;
	int last = -1;

	for (int i = 0; i < 86400; i++)
	{
		if (i >= T)
		{
			for (int j = 0; j < A[i - T].size(); j++)
			{
				int x = A[i - T][j];
				mp[id[x]]--;

				if (mp[id[x]] == 0)
					cnt--;
			}
		}

		for (int j = 0; j < A[i].size(); j++)
		{
			int x = A[i][j];

			if (cnt < M)
			{
				last++;
				cnt++;

				mx = max(mx, cnt);
			}

			id[x] = last;
			mp[last]++;
		}
	}

	if (mx != M)
	{
		std::cout << "No solution" << std::endl;
		return 0;
	}

	std::cout << (1 + last) << std::endl;
	for (int i = 0; i < N; i++)
		std::cout << (1 + id[i]) << std::endl;

	return 0;
}


#include<bits/stdc++.h>
#define MAX   200200
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i=i+1)
#define REP(i,n) for (int i=0,_n=(n);i<_n;i=i+1)
#define FORE(i,v) for (__typeof((v).begin()) i=(v).begin();i!=(v).end();i++)
using namespace std;
const char noSol[]="No solution";
vector<int> startAt[MAX],endAt[MAX];
int n,lim,len;
int ans[MAX];
map<int,int> cnt;
void init(void) {
    scanf("%d%d%d",&n,&lim,&len);
    FOR(i,1,n) {
        int h,m,s;
        scanf("%d:%d:%d",&h,&m,&s);
        int t=h*3600+m*60+s;
        startAt[t].push_back(i);
        endAt[t+len].push_back(i);
    }
}
void add(int x) {
    cnt[x]++;
}
void rem(int x) {
    if (--cnt[x]==0) cnt.erase(x);
}
void process(void) {
    bool equ=false;
    int res=0;
    int prev=0;
    FOR(i,0,MAX/2) {
        FORE(it,endAt[i]) rem(ans[*it]);
        FORE(it,startAt[i]) {
            ans[*it]=cnt.size()<lim?++res:prev;
            add(ans[*it]);
            prev=ans[*it];
            equ|=cnt.size()==lim;
        }
    }
    if (!equ) {
        printf("%s\n",noSol);
        return;
    }
    printf("%d\n",res);
    FOR(i,1,n) printf("%d\n",ans[i]);
}
int main(void) {
    init();
    process();
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<ctype.h>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<iomanip>
#include<complex>
#include<utility>

#define X first
#define Y second
#define REP_0(i,n) for(int i=0;i<(n);++i)
#define REP_1(i,n) for(int i=1;i<=(n);++i)
#define REP_2(i,a,b) for(int i=(a);i<(b);++i)
#define REP_3(i,a,b) for(int i=(a);i<=(b);++i)
#define REP_4(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define DOW_0(i,n) for(int i=(n)-1;-1<i;--i)
#define DOW_1(i,n) for(int i=(n);0<i;--i)
#define DOW_2(i,a,b) for(int i=(b);(a)<i;--i)
#define DOW_3(i,a,b) for(int i=(b);(a)<=i;--i)
#define FOREACH(a,b) for(typeof((b).begin()) a=(b).begin();a!=(b).end();++a)
#define RFOREACH(a,b) for(typeof((b).rbegin()) a=(b).rbegin();a!=(b).rend();++a)
#define PB push_back
#define PF push_front
#define MP make_pair
#define IS insert
#define ES erase
#define IT iterator
#define RI reserve_iterator
#define PQ priority_queue
#define LB lower_bound
#define UB upper_bound
#define ALL(x) x.begin(),x.end()

#define PI 3.1415926535897932384626433832795
#define EXP 2.7182818284590452353602874713527

using namespace std;

typedef long long LL;
typedef long double LD;
typedef double DB;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef pair<int,PII> PIII;
typedef pair<LD,int> PLDI;
typedef vector<PII> VII;

template<class T>
T Mul(T x,T y,T P){
	T F1=0;
	while(y)
	{
		if(y&1)
		{
			F1+=x;
			if(F1<0||F1>=P)F1-=P;
		}
		x<<=1;
		if(x<0||x>=P)x-=P;
		y>>=1;
	}
	return F1;
}

template<class T>
T Pow(T x,T y,T P){
	T F1=1;x%=P;
	while(y)
	{
		if(y&1)
		{
			F1=Mul(F1,x,P);
		}
		x=Mul(x,x,P);
		y>>=1;
	}
	return F1;
}

template<class T>
T Gcd(T x,T y){
	if(y==0)return x;
	T z;
	while(z=x%y){
		x=y,y=z;
	}
	return y;
}

template<class T>
void UpdateMin(T &x,T y){
	if(y<x)
	{
		x=y;
	}
}

template<class T>
void UpdateMax(T &x,T y){
	if(x<y)
	{
		x=y;
	}
}

template<class T>
T Sqr(const T x){
	return x*x;
}

template<class T>
T Abs(const T x){
	return x<0?-x:x;
}

#define MaxBuffer 20000000
class ReadBuffer{
	private:
	char buff[MaxBuffer];
	char *buf;
	public:
	void init(int size=MaxBuffer)
	{
		fread(buff,1,size,stdin);
		buf=buff;
	}
	template<class T>
	bool readInteger(T &x)
	{
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag;
		flag=0;
		if(*buf=='-') flag=true;
		else x=*buf-'0';
		while(isdigit(*++buf)) x=x*10+*buf-'0';
		if(flag) x=-x;
		return true;
	}
	template<class T>
	bool readFloat(T &x)
	{
		long double nowpos=0.1;
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag,decimal;
		decimal=flag=0;
		if(*buf=='-') flag=true,++buf;
		else if(*buf=='.') decimal=true;
		while(isdigit(*buf)||*buf=='.')
		{
			if(*buf=='.') decimal=true;
			else
			{
				if(decimal)
				{
					x+=nowpos*(*buf-'0');
					nowpos*=0.1;
				}
				else
				{
					x=x*10+*buf-'0';
				}
			}
			++buf;
		}
		return true;
	}
	bool readChar(char c)
	{
		if(*buf==0) return 0;
		return c=*buf++,1;
	}
	bool readString(char *s)
	{
		while(*buf&&isspace(*buf)) ++buf;
		if(!*buf) return false;
		while(!isspace(*buf)) *s++=*buf++;
		*s++=0;
		return true;
	}
	int countSpacetonext(){
		int total=0;
		while(*buf&&*buf==' ') ++total,++buf;
		return total;
	}
	bool splitBycharactor(char *s,char Split='\n'){
		while(*buf&&*buf!=Split) *s++=*buf++;
		*s++=0;
		return *buf!=0;
	}
};

struct EDGE{
	int T;EDGE *Nxt;
};

int N,M,T;
int A[30001];
int QQ[30001];
int ans[30001];
int maxx[30001];
int st[30001],ed[30001];
int maxnow,QH,QT;
int tot;
inline bool checkall(){
	int nownd=2*N;
	DOW_1(i,N){
		int nd=M-(ed[i]-st[i]+1);
		if(i+nd<=N&&st[i]>nd){
			nownd=min(nownd,nd);
		}
	}
	if(nownd==2*N) return false;
	else{
		for(int i=0;i<nownd;++i) ans[N-i]=i+1;
		tot-=nownd;
		return true;
	}
}
int main(){
	scanf("%d%d%d",&N,&M,&T);
	QH=0,QT=-1;
	REP_1(i,N){
		int x,y,z;
		scanf(" %d:%d:%d",&x,&y,&z);
		int V=x*3600+y*60+z;
		A[i]=V;
		while(QH<=QT&&QQ[QH]<V) ++QH;
		if(QT-QH+1<M) QQ[++QT]=V+T-1,ans[i]=QT+1;
		else QQ[QT]=V+T+1,ans[i]=QT+1;
		st[i]=QH+1,ed[i]=QT+1;
		maxnow=max(maxnow,QT-QH+1);
	}
	tot=ans[N];
	if(maxnow==M||checkall()){
		printf("%d\n",tot);
		REP_1(i,N) printf("%d\n",ans[i]);
	}
	else{
		printf("No solution\n");
	}
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<ctype.h>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<iomanip>
#include<complex>
#include<utility>

#define X first
#define Y second
#define REP_0(i,n) for(int i=0;i<(n);++i)
#define REP_1(i,n) for(int i=1;i<=(n);++i)
#define REP_2(i,a,b) for(int i=(a);i<(b);++i)
#define REP_3(i,a,b) for(int i=(a);i<=(b);++i)
#define REP_4(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define DOW_0(i,n) for(int i=(n)-1;-1<i;--i)
#define DOW_1(i,n) for(int i=(n);0<i;--i)
#define DOW_2(i,a,b) for(int i=(b);(a)<i;--i)
#define DOW_3(i,a,b) for(int i=(b);(a)<=i;--i)
#define FOREACH(a,b) for(typeof((b).begin()) a=(b).begin();a!=(b).end();++a)
#define RFOREACH(a,b) for(typeof((b).rbegin()) a=(b).rbegin();a!=(b).rend();++a)
#define PB push_back
#define PF push_front
#define MP make_pair
#define IS insert
#define ES erase
#define IT iterator
#define RI reserve_iterator
#define PQ priority_queue
#define LB lower_bound
#define UB upper_bound
#define ALL(x) x.begin(),x.end()

#define PI 3.1415926535897932384626433832795
#define EXP 2.7182818284590452353602874713527

using namespace std;

typedef long long LL;
typedef long double LD;
typedef double DB;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef pair<int,PII> PIII;
typedef pair<LD,int> PLDI;
typedef vector<PII> VII;

template<class T>
T Mul(T x,T y,T P){
	T F1=0;
	while(y)
	{
		if(y&1)
		{
			F1+=x;
			if(F1<0||F1>=P)F1-=P;
		}
		x<<=1;
		if(x<0||x>=P)x-=P;
		y>>=1;
	}
	return F1;
}

template<class T>
T Pow(T x,T y,T P){
	T F1=1;x%=P;
	while(y)
	{
		if(y&1)
		{
			F1=Mul(F1,x,P);
		}
		x=Mul(x,x,P);
		y>>=1;
	}
	return F1;
}

template<class T>
T Gcd(T x,T y){
	if(y==0)return x;
	T z;
	while(z=x%y){
		x=y,y=z;
	}
	return y;
}

template<class T>
void UpdateMin(T &x,T y){
	if(y<x)
	{
		x=y;
	}
}

template<class T>
void UpdateMax(T &x,T y){
	if(x<y)
	{
		x=y;
	}
}

template<class T>
T Sqr(const T x){
	return x*x;
}

template<class T>
T Abs(const T x){
	return x<0?-x:x;
}

#define MaxBuffer 20000000
class ReadBuffer{
	private:
	char buff[MaxBuffer];
	char *buf;
	public:
	void init(int size=MaxBuffer)
	{
		fread(buff,1,size,stdin);
		buf=buff;
	}
	template<class T>
	bool readInteger(T &x)
	{
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag;
		flag=0;
		if(*buf=='-') flag=true;
		else x=*buf-'0';
		while(isdigit(*++buf)) x=x*10+*buf-'0';
		if(flag) x=-x;
		return true;
	}
	template<class T>
	bool readFloat(T &x)
	{
		long double nowpos=0.1;
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag,decimal;
		decimal=flag=0;
		if(*buf=='-') flag=true,++buf;
		else if(*buf=='.') decimal=true;
		while(isdigit(*buf)||*buf=='.')
		{
			if(*buf=='.') decimal=true;
			else
			{
				if(decimal)
				{
					x+=nowpos*(*buf-'0');
					nowpos*=0.1;
				}
				else
				{
					x=x*10+*buf-'0';
				}
			}
			++buf;
		}
		return true;
	}
	bool readChar(char c)
	{
		if(*buf==0) return 0;
		return c=*buf++,1;
	}
	bool readString(char *s)
	{
		while(*buf&&isspace(*buf)) ++buf;
		if(!*buf) return false;
		while(!isspace(*buf)) *s++=*buf++;
		*s++=0;
		return true;
	}
	int countSpacetonext(){
		int total=0;
		while(*buf&&*buf==' ') ++total,++buf;
		return total;
	}
	bool splitBycharactor(char *s,char Split='\n'){
		while(*buf&&*buf!=Split) *s++=*buf++;
		*s++=0;
		return *buf!=0;
	}
};

struct EDGE{
	int T;EDGE *Nxt;
};

int N,M,T;
int A[30001];
int QQ[30001];
int ans[30001];
int maxx[30001];
int st[30001],ed[30001];
int maxnow,QH,QT;
int tot;
inline bool checkall(){
	if(QT<M) return false;
	int nownd=N;
	DOW_1(i,N){
		int nd=M-(ed[i]-st[i]+1);
		if(i+nd<=N&&st[i]>nd){
			nownd=min(nownd,nd);
		}
	}
	if(nownd==N) return false;
	else{
		for(int i=0;i<nownd;++i) ans[N-i]=i+1;
		tot-=nownd;
		return true;
	}
}
int main(){
	scanf("%d%d%d",&N,&M,&T);
	QH=0,QT=-1;
	REP_1(i,N){
		int x,y,z;
		scanf(" %d:%d:%d",&x,&y,&z);
		int V=x*3600+y*60+z;
		A[i]=V;
		while(QH<=QT&&QQ[QH]<V) ++QH;
		if(QT-QH+1<M) QQ[++QT]=V+T-1,ans[i]=QT+1;
		else QQ[QT]=V+T+1,ans[i]=QT+1;
		st[i]=QH,ed[i]=QT;
		maxnow=max(maxnow,QT-QH+1);
	}
	tot=ans[N];
	if(maxnow==M||checkall()){
		printf("%d\n",tot);
		REP_1(i,N) printf("%d\n",ans[i]);
	}
	else{
		printf("No solution\n");
	}
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<ctype.h>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<iomanip>
#include<complex>
#include<utility>

#define X first
#define Y second
#define REP_0(i,n) for(int i=0;i<(n);++i)
#define REP_1(i,n) for(int i=1;i<=(n);++i)
#define REP_2(i,a,b) for(int i=(a);i<(b);++i)
#define REP_3(i,a,b) for(int i=(a);i<=(b);++i)
#define REP_4(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define DOW_0(i,n) for(int i=(n)-1;-1<i;--i)
#define DOW_1(i,n) for(int i=(n);0<i;--i)
#define DOW_2(i,a,b) for(int i=(b);(a)<i;--i)
#define DOW_3(i,a,b) for(int i=(b);(a)<=i;--i)
#define FOREACH(a,b) for(typeof((b).begin()) a=(b).begin();a!=(b).end();++a)
#define RFOREACH(a,b) for(typeof((b).rbegin()) a=(b).rbegin();a!=(b).rend();++a)
#define PB push_back
#define PF push_front
#define MP make_pair
#define IS insert
#define ES erase
#define IT iterator
#define RI reserve_iterator
#define PQ priority_queue
#define LB lower_bound
#define UB upper_bound
#define ALL(x) x.begin(),x.end()

#define PI 3.1415926535897932384626433832795
#define EXP 2.7182818284590452353602874713527

using namespace std;

typedef long long LL;
typedef long double LD;
typedef double DB;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef pair<int,PII> PIII;
typedef pair<LD,int> PLDI;
typedef vector<PII> VII;

template<class T>
T Mul(T x,T y,T P){
	T F1=0;
	while(y)
	{
		if(y&1)
		{
			F1+=x;
			if(F1<0||F1>=P)F1-=P;
		}
		x<<=1;
		if(x<0||x>=P)x-=P;
		y>>=1;
	}
	return F1;
}

template<class T>
T Pow(T x,T y,T P){
	T F1=1;x%=P;
	while(y)
	{
		if(y&1)
		{
			F1=Mul(F1,x,P);
		}
		x=Mul(x,x,P);
		y>>=1;
	}
	return F1;
}

template<class T>
T Gcd(T x,T y){
	if(y==0)return x;
	T z;
	while(z=x%y){
		x=y,y=z;
	}
	return y;
}

template<class T>
void UpdateMin(T &x,T y){
	if(y<x)
	{
		x=y;
	}
}

template<class T>
void UpdateMax(T &x,T y){
	if(x<y)
	{
		x=y;
	}
}

template<class T>
T Sqr(const T x){
	return x*x;
}

template<class T>
T Abs(const T x){
	return x<0?-x:x;
}

#define MaxBuffer 20000000
class ReadBuffer{
	private:
	char buff[MaxBuffer];
	char *buf;
	public:
	void init(int size=MaxBuffer)
	{
		fread(buff,1,size,stdin);
		buf=buff;
	}
	template<class T>
	bool readInteger(T &x)
	{
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag;
		flag=0;
		if(*buf=='-') flag=true;
		else x=*buf-'0';
		while(isdigit(*++buf)) x=x*10+*buf-'0';
		if(flag) x=-x;
		return true;
	}
	template<class T>
	bool readFloat(T &x)
	{
		long double nowpos=0.1;
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag,decimal;
		decimal=flag=0;
		if(*buf=='-') flag=true,++buf;
		else if(*buf=='.') decimal=true;
		while(isdigit(*buf)||*buf=='.')
		{
			if(*buf=='.') decimal=true;
			else
			{
				if(decimal)
				{
					x+=nowpos*(*buf-'0');
					nowpos*=0.1;
				}
				else
				{
					x=x*10+*buf-'0';
				}
			}
			++buf;
		}
		return true;
	}
	bool readChar(char c)
	{
		if(*buf==0) return 0;
		return c=*buf++,1;
	}
	bool readString(char *s)
	{
		while(*buf&&isspace(*buf)) ++buf;
		if(!*buf) return false;
		while(!isspace(*buf)) *s++=*buf++;
		*s++=0;
		return true;
	}
	int countSpacetonext(){
		int total=0;
		while(*buf&&*buf==' ') ++total,++buf;
		return total;
	}
	bool splitBycharactor(char *s,char Split='\n'){
		while(*buf&&*buf!=Split) *s++=*buf++;
		*s++=0;
		return *buf!=0;
	}
};

struct EDGE{
	int T;EDGE *Nxt;
};

int N,M,T;

int QQ[30001];
int ans[30001];
int maxnow,QH,QT;
int main(){
	scanf("%d%d%d",&N,&M,&T);
	QH=0,QT=-1;
	REP_1(i,N){
		int x,y,z;
		scanf(" %d:%d:%d",&x,&y,&z);
		int V=x*3600+y*60+z;
		while(QH<=QT&&QQ[QH]<V) ++QH;
		if(QT-QH+1<M) QQ[++QT]=V+T-1,ans[i]=ans[i-1]+1;
		else QQ[QT]=V+T+1,ans[i]=ans[i-1];
		maxnow=max(maxnow,QT-QH+1);
	}
	if(maxnow==M){
		printf("%d\n",ans[N]);
		REP_1(i,N) printf("%d\n",ans[i]);
	}
	else{
		printf("No solution\n");
	}
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<iostream>
#include<ctype.h>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<iomanip>
#include<complex>
#include<utility>

#define X first
#define Y second
#define REP_0(i,n) for(int i=0;i<(n);++i)
#define REP_1(i,n) for(int i=1;i<=(n);++i)
#define REP_2(i,a,b) for(int i=(a);i<(b);++i)
#define REP_3(i,a,b) for(int i=(a);i<=(b);++i)
#define REP_4(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define DOW_0(i,n) for(int i=(n)-1;-1<i;--i)
#define DOW_1(i,n) for(int i=(n);0<i;--i)
#define DOW_2(i,a,b) for(int i=(b);(a)<i;--i)
#define DOW_3(i,a,b) for(int i=(b);(a)<=i;--i)
#define FOREACH(a,b) for(typeof((b).begin()) a=(b).begin();a!=(b).end();++a)
#define RFOREACH(a,b) for(typeof((b).rbegin()) a=(b).rbegin();a!=(b).rend();++a)
#define PB push_back
#define PF push_front
#define MP make_pair
#define IS insert
#define ES erase
#define IT iterator
#define RI reserve_iterator
#define PQ priority_queue
#define LB lower_bound
#define UB upper_bound
#define ALL(x) x.begin(),x.end()

#define PI 3.1415926535897932384626433832795
#define EXP 2.7182818284590452353602874713527

using namespace std;

typedef long long LL;
typedef long double LD;
typedef double DB;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef pair<int,PII> PIII;
typedef pair<LD,int> PLDI;
typedef vector<PII> VII;

template<class T>
T Mul(T x,T y,T P){
	T F1=0;
	while(y)
	{
		if(y&1)
		{
			F1+=x;
			if(F1<0||F1>=P)F1-=P;
		}
		x<<=1;
		if(x<0||x>=P)x-=P;
		y>>=1;
	}
	return F1;
}

template<class T>
T Pow(T x,T y,T P){
	T F1=1;x%=P;
	while(y)
	{
		if(y&1)
		{
			F1=Mul(F1,x,P);
		}
		x=Mul(x,x,P);
		y>>=1;
	}
	return F1;
}

template<class T>
T Gcd(T x,T y){
	if(y==0)return x;
	T z;
	while(z=x%y){
		x=y,y=z;
	}
	return y;
}

template<class T>
void UpdateMin(T &x,T y){
	if(y<x)
	{
		x=y;
	}
}

template<class T>
void UpdateMax(T &x,T y){
	if(x<y)
	{
		x=y;
	}
}

template<class T>
T Sqr(const T x){
	return x*x;
}

template<class T>
T Abs(const T x){
	return x<0?-x:x;
}

#define MaxBuffer 20000000
class ReadBuffer{
	private:
	char buff[MaxBuffer];
	char *buf;
	public:
	void init(int size=MaxBuffer)
	{
		fread(buff,1,size,stdin);
		buf=buff;
	}
	template<class T>
	bool readInteger(T &x)
	{
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag;
		flag=0;
		if(*buf=='-') flag=true;
		else x=*buf-'0';
		while(isdigit(*++buf)) x=x*10+*buf-'0';
		if(flag) x=-x;
		return true;
	}
	template<class T>
	bool readFloat(T &x)
	{
		long double nowpos=0.1;
		x=0;
		while(*buf&&isspace(*buf)) ++buf;
		if(*buf==0) return false;
		static bool flag,decimal;
		decimal=flag=0;
		if(*buf=='-') flag=true,++buf;
		else if(*buf=='.') decimal=true;
		while(isdigit(*buf)||*buf=='.')
		{
			if(*buf=='.') decimal=true;
			else
			{
				if(decimal)
				{
					x+=nowpos*(*buf-'0');
					nowpos*=0.1;
				}
				else
				{
					x=x*10+*buf-'0';
				}
			}
			++buf;
		}
		return true;
	}
	bool readChar(char c)
	{
		if(*buf==0) return 0;
		return c=*buf++,1;
	}
	bool readString(char *s)
	{
		while(*buf&&isspace(*buf)) ++buf;
		if(!*buf) return false;
		while(!isspace(*buf)) *s++=*buf++;
		*s++=0;
		return true;
	}
	int countSpacetonext(){
		int total=0;
		while(*buf&&*buf==' ') ++total,++buf;
		return total;
	}
	bool splitBycharactor(char *s,char Split='\n'){
		while(*buf&&*buf!=Split) *s++=*buf++;
		*s++=0;
		return *buf!=0;
	}
};

struct EDGE{
	int T;EDGE *Nxt;
};

int N,M,T;
int A[30001];
int QQ[30001];
int ans[30001];
int maxx[30001];
int st[30001],ed[30001];
int maxnow,QH,QT;
int tot;
int main(){
	scanf("%d%d%d",&N,&M,&T);
	QH=0,QT=-1;
	REP_1(i,N){
		int x,y,z;
		scanf(" %d:%d:%d",&x,&y,&z);
		int V=x*3600+y*60+z;
		A[i]=V;
		while(QH<=QT&&QQ[QH]<V) ++QH;
		if(QT-QH+1<M) QQ[++QT]=V+T-1,ans[i]=QT+1;
		else QQ[QT]=V+T-1,ans[i]=QT+1;
		st[i]=QH+1,ed[i]=QT+1;
		maxnow=max(maxnow,QT-QH+1);
	}
	tot=ans[N];
	if(maxnow==M){
		printf("%d\n",tot);
		REP_1(i,N) printf("%d\n",ans[i]);
	}
	else{
		printf("No solution\n");
	}
	return 0;
}


#include <cstdio>
#include <queue>
#include <deque>
#include <utility>

#define mp make_pair

using namespace std;

typedef pair<int,int> pii;

int N, M, T;

int timeToInt( const char * s )
{
    int ret = 0;
    ret += 36000  * ( s[0]-'0' );
    ret += 3600  * ( s[1]-'0' );
    ret += 600  * ( s[3]-'0' );
    ret += 60  * ( s[4]-'0' );
    ret += 10 * ( s[6]-'0' );
    ret += 1 * ( s[7]-'0' );
    return ret;
}

int main()
{
    deque<pii> curr;
    queue<int> events;
    queue<int> users;

    char str[10];

    scanf( "%d %d %d", &N, &M, &T );
    while ( N-- )
    {
        scanf( "%s", str );
        events.push( timeToInt(str) );
    }

    int tot_users = 0;
    bool reach = false;
    while ( not events.empty() )
    {
        int t = events.front();
        events.pop();
        while ( not curr.empty() and t > curr.front().first ) curr.pop_front();
        if ( curr.size() == M )
        {
            curr.back().first = t+T-1;
            users.push( curr.back().second );
        }
        else
        {
            curr.push_back( mp(t+T-1, ++tot_users) );
            users.push( tot_users );
            if ( curr.size() == M )
                reach = true;
        }
    }

    if ( not reach ) printf( "No solution\n" );
    else
    {
        printf( "%d\n", tot_users );
        while ( not users.empty() )
        {
            printf( "%d\n", users.front() );
            users.pop();
        }
    }

    return 0;
}


#include <cstdio>
#include <queue>
#include <deque>
#include <utility>

#define mp make_pair

using namespace std;

typedef pair<int,int> pii;

const int MAXS = 30000;

int N, M, T;

int timeToInt( const char * s )
{
    int ret = 0;
    ret += 36000  * ( s[0]-'0' );
    ret += 3600  * ( s[1]-'0' );
    ret += 600  * ( s[3]-'0' );
    ret += 60  * ( s[4]-'0' );
    ret += 10 * ( s[6]-'0' );
    ret += 1 * ( s[7]-'0' );
    return ret;
}

int main()
{
    deque<pii> curr;
    queue<int> events;
    queue<int> users;

    char str[8];

    scanf( "%d %d %d", &N, &M, &T );
    while ( N-- )
    {
        scanf( "%s", str );
        events.push( timeToInt(str) );
    }

    int tot_users = 0;
    bool reach = false;
    while ( not events.empty() )
    {
        int t = events.front();
        events.pop();
        while ( not curr.empty() and t > curr.front().first ) curr.pop_front();
        if ( curr.size() == M )
        {
            curr.back().first = t+T-1;
            users.push( curr.back().second );
        }
        else
        {
            curr.push_back( mp(t+T-1, ++tot_users) );
            users.push( tot_users );
            if ( curr.size() == M )
                reach = true;
        }
    }

    if ( not reach ) printf( "No solution\n" );
    else
    {
        printf( "%d\n", tot_users );
        while ( not users.empty() )
        {
            printf( "%d\n", users.front() );
            users.pop();
        }
    }

    return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cstdlib>
#include<string>
#include<bitset>
#define INF 1000000000
#define N 100005
#define fi first
#define se second
#define debug(x) cout<<#x<<"="<<x<<endl
#define MP(x,y) make_pair(x,y)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
char _temp;
bool _flag;
inline void getint(int &_num)
{
    _num=_flag=0;
    while(1)
    {
        _temp=getchar();
        if(_temp>=48&&_temp<=57)
        {
            _num=_num*10+_temp-48;
            _flag=1;
        }
        else if(_flag)
            return;
    }
}
set<pii> s;
int ed[N],rel[N];
int main()
{
    int n,m,T,now,a,nr,ans,mx=0,i;
    cin>>n>>m>>T;
    nr=ans=0;
    for(i=1;i<=n;i++)
    {
        now=0;
        getint(a);
        now+=a*3600;
        getint(a);
        now+=a*60;
        getint(a);
        now+=a;
        while(!s.empty()&&(*s.begin()).fi<=now)
        {
            s.erase(s.begin());
            nr--;
        }
        if(nr<m)
        {
            ans++;
            rel[i]=ans;
            ed[rel[i]]=now+T;
            s.insert(MP(ed[rel[i]],rel[i]));
            nr++;
        }
        else
        {
            rel[i]=(*s.rbegin()).se;
            s.erase(*s.rbegin());
            ed[rel[i]]=now+T;
            s.insert(MP(ed[rel[i]],rel[i]));
        }
        mx=max(mx,nr);
    }
    if(mx<m)
        printf("No solution\n");
    else
    {
        cout<<ans<<endl;
        for(i=1;i<=n;i++)
            printf("%d\n",rel[i]);
    }
    return 0;
}
// davidlee1999WTK 2015/
// srO myk Orz
//ios::sync_with_stdio(false);


#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;

#define MAXN 20005
int t[MAXN];
struct Node
{
    int time, person, type;
};

Node node[MAXN*2];
int n, maxperson, duration;
int assign[MAXN];
bool in[MAXN];
int cnt[MAXN];
int end[MAXN];

bool cmp(const Node &a, const Node &b)
{
    if(a.time == b.time)
        return a.type > b.type;
    return a.time < b.time;
}

int gettime(string str)
{
    int h = (str[0] - '0') * 10 + str[1] - '0';
    int m = (str[3] - '0') * 10 + str[4] - '0';
    int s = (str[6] - '0') * 10 + str[7] - '0';

    return h * 3600 + m * 60 + s;
}

int main()
{
    memset(assign, -1, sizeof(assign));
    memset(cnt, 0, sizeof(cnt));
    memset(in, false, sizeof(in));
    cin>>n>>maxperson>>duration;
    for(int i = 0; i < n; ++i)
    {
        string str;
        cin>>str;
        int start = gettime(str);
        node[i*2].time = start;
        node[i*2].person = i;
        node[i*2].type = 0;
        node[i*2+1].time = start + duration;
        node[i*2+1].person = i;
        node[i*2+1].type = 1;
        //cout<<i<<": "<<start<<" "<<start+duration<<endl;
        end[i] = start + duration;
    }

    sort(node, node+(n*2), cmp);

/*  for(int i = 0; i < n*2; ++i)
        cout<<node[i].person<<" "<<node[i].type<<" "<<node[i].time<<endl;
*/
    int cur = 0;
    int reqmax = -1, reqidx;
    bool ok = false;
    int idx = 1;
    priority_queue<pair<int, int>, vector<pair<int, int> >, less<pair<int, int> > > q;
    for(int i = 0; i < n*2; ++i)
    {
        if(node[i].type == 0)
        {
            in[node[i].person] = true;

            if(cur >= maxperson)
            {
                //assign[node[i].person] = *(in.begin());
                int idxtoassign;
                idxtoassign = q.top().second;
                assign[node[i].person] = idxtoassign;
            }
            else
            {
                cur++;
                assign[node[i].person] = idx++;
            }

            if(cur >= maxperson)
                ok = true;

            q.push(make_pair(end[node[i].person], assign[node[i].person]));
            cnt[assign[node[i].person]]++;
        }
        else
        {
            cnt[assign[node[i].person]]--;
            if(cnt[assign[node[i].person]] == 0)
                cur--;
        }
    }

    if(!ok)
    {
        cout<<"No solution"<<endl;
        return 0;
    }

    cout<<idx-1<<endl;
    for(int i = 0; i < n; ++i)
        cout<<assign[i]<<endl;
    return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;

#define MAXN 20005
int t[MAXN];
struct Node
{
    int time, person, type;
};

Node node[MAXN*2];
int n, maxperson, duration;
int assign[MAXN];
bool in[MAXN];

bool cmp(const Node &a, const Node &b)
{
    if(a.time == b.time)
        return a.type > b.type;
    return a.time < b.time;
}

int gettime(string str)
{
    int h = (str[0] - '0') * 10 + str[1] - '0';
    int m = (str[2] - '0') * 10 + str[3] - '0';
    int s = (str[5] - '0') * 10 + str[6] - '0';

    return h * 3600 + m * 60 + s;
}

int main()
{
    memset(assign, -1, sizeof(assign));
    cin>>n>>maxperson>>duration;
    for(int i = 0; i < n; ++i)
    {
        string str;
        cin>>str;
        int start = gettime(str);
        node[i*2].time = start;
        node[i*2].person = i;
        node[i*2].type = 0;
        node[i*2+1].time = start + duration;
        node[i*2+1].person = i;
        node[i*2+1].type = 1;
    }

    sort(node, node+(n*2), cmp);
    int cur = 0;
    int reqmax = -1, reqidx;
    for(int i = 0; i < n*2; ++i)
    {
        if(node[i].type == 0)
        {
            cur++;
            if(cur > reqmax)
            {
                reqmax = cur;
                reqidx = i;
            }
        }
        else
        {
            cur--;
        }
    }

    if(reqmax <= maxperson)
    {
        cout<<"No solution"<<endl;
        return 0;
    }

    memset(in, false, sizeof(in));
    for(int i = 0; i <= reqidx; ++i)
    {
        if(node[i].type == 0)
            in[node[i].person] = true;
        else
            in[node[i].person] = false;
    }

    int curidx = 1;
    for(int i = 0; i < n; ++i)
    {
        if(in[i] == true)
        {
            assign[i] = min(curidx, maxperson);
            curidx++;
        }
    }
    curidx = maxperson + 1;
    for(int i = 0; i < n; ++i)
    {
        if(!in[i])
        {
            assign[i] = curidx++;
        }
    }

    cout<<curidx-1<<endl;
    for(int i = 0; i < n; ++i)
        cout<<assign[i]<<endl;
    return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;

#define MAXN 20005
int t[MAXN];
struct Node
{
    int time, person, type;
};

Node node[MAXN*2];
int n, maxperson, duration;
int assign[MAXN];
bool in[MAXN];
int cnt[MAXN];

bool cmp(const Node &a, const Node &b)
{
    if(a.time == b.time)
        return a.type > b.type;
    return a.time < b.time;
}

int gettime(string str)
{
    int h = (str[0] - '0') * 10 + str[1] - '0';
    int m = (str[3] - '0') * 10 + str[4] - '0';
    int s = (str[6] - '0') * 10 + str[7] - '0';

    return h * 3600 + m * 60 + s;
}

int main()
{
    memset(assign, -1, sizeof(assign));
    memset(cnt, 0, sizeof(cnt));
    cin>>n>>maxperson>>duration;
    for(int i = 0; i < n; ++i)
    {
        string str;
        cin>>str;
        int start = gettime(str);
        node[i*2].time = start;
        node[i*2].person = i;
        node[i*2].type = 0;
        node[i*2+1].time = start + duration;
        node[i*2+1].person = i;
        node[i*2+1].type = 1;
    }

    sort(node, node+(n*2), cmp);
    int cur = 0;
    int reqmax = -1, reqidx;
    set<int> in;
    bool ok = false;
    int idx = 1;
    for(int i = 0; i < n*2; ++i)
    {
        if(node[i].type == 0)
        {
            cur++;
            if(cur > maxperson)
            {
                ok = true;
                assign[node[i].person] = *(in.begin());
                cnt[assign[node[i].person]]++;
            }
            else
            {
                in.insert(idx);
                cnt[idx]++;
                assign[node[i].person] = idx++;
            }
        }
        else
        {
            cur--;
            cnt[assign[node[i].person]]--;
            if(cnt[assign[node[i].person]] == 0)
                in.erase(assign[node[i].person]);
        }
    }

    if(!ok)
    {
        cout<<"No solution"<<endl;
        return 0;
    }

    cout<<idx-1<<endl;
    for(int i = 0; i < n; ++i)
        cout<<assign[i]<<endl;
    return 0;
}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;

#define MAXN 20005
int t[MAXN];
struct Node
{
    int time, person, type;
};

Node node[MAXN*2];
int n, maxperson, duration;
int assign[MAXN];
bool in[MAXN];
int cnt[MAXN];
int end[MAXN];

bool cmp(const Node &a, const Node &b)
{
    if(a.time == b.time)
        return a.type > b.type;
    return a.time < b.time;
}

int gettime(string str)
{
    int h = (str[0] - '0') * 10 + str[1] - '0';
    int m = (str[3] - '0') * 10 + str[4] - '0';
    int s = (str[6] - '0') * 10 + str[7] - '0';

    return h * 3600 + m * 60 + s;
}

int main()
{
    memset(assign, -1, sizeof(assign));
    memset(cnt, 0, sizeof(cnt));
    memset(in, false, sizeof(in));
    cin>>n>>maxperson>>duration;
    for(int i = 0; i < n; ++i)
    {
        string str;
        cin>>str;
        int start = gettime(str);
        node[i*2].time = start;
        node[i*2].person = i;
        node[i*2].type = 0;
        node[i*2+1].time = start + duration;
        node[i*2+1].person = i;
        node[i*2+1].type = 1;
        //cout<<i<<": "<<start<<" "<<start+duration<<endl;
        end[i] = start + duration;
    }

    sort(node, node+(n*2), cmp);

/*  for(int i = 0; i < n*2; ++i)
        cout<<node[i].person<<" "<<node[i].type<<" "<<node[i].time<<endl;
*/
    int cur = 0;
    int reqmax = -1, reqidx;
    bool ok = false;
    int idx = 1;
    priority_queue<pair<int, int>, vector<pair<int, int> >, less<pair<int, int> > > q;
    for(int i = 0; i < n*2; ++i)
    {
        if(node[i].type == 0)
        {
            in[node[i].person] = true;
            if(cur >= maxperson)
                ok = true;
            if(cur >= maxperson)
            {
                //assign[node[i].person] = *(in.begin());
                int idxtoassign;
                idxtoassign = q.top().second;
                assign[node[i].person] = idxtoassign;
            }
            else
            {
                cur++;
                assign[node[i].person] = idx++;
            }

            q.push(make_pair(end[node[i].person], assign[node[i].person]));
            cnt[assign[node[i].person]]++;
        }
        else
        {
            cnt[assign[node[i].person]]--;
            if(cnt[assign[node[i].person]] == 0)
                cur--;
        }
    }

    if(!ok)
    {
        cout<<"No solution"<<endl;
        return 0;
    }

    cout<<idx-1<<endl;
    for(int i = 0; i < n; ++i)
        cout<<assign[i]<<endl;
    return 0;
}


#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>
#include <queue>
#include <bitset>
#define LL long long
#define UN unsigned short
#define ULL unsigned long long
#define pii pair <int, int>
#define piii pair <pii, int>
#define xx first
#define yy second
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l, m
#define rson rs, m + 1, r
using namespace std;

const int N = 101000;
int mx[N * 4], res[N], rn;

void updata (int rt, int l, int r, int x) {
//    cout << rt << ' ' << l << ' ' << r << ' '<<x <<endl;
    if (l == r) { mx[rt]++; return; }
    int m = (l + r) >> 1;
    if (x <= m) updata (lson, x);
    else updata (rson, x);
    mx[rt] = max (mx[ls], mx[rs]);
}

int query (int rt, int l, int r, int tl, int tr) {
//    cout << rt << ' ' << l <<' ' <<r << ' ' << tl << ' ' <<tr << endl;
    if (tl <= l && r <= tr) return mx[rt];
    int m = (l + r) >> 1;
    if (tr <= m) return query(lson, tl, tr);
    else if (m < tl) return query(rson, tl, tr);
    else return query (lson, tl, m) + query (rson, m + 1, tr);
}

int main () {
//    freopen ("in.txt", "r", stdin);
    int n, m, t, h, mi, s, flag = 0;
    cin >> n >> m >> t;
    for (int i = 1; i <= n; i++) {
        scanf ("%d:%d:%d", &h, &mi, &s);
        int time = h * 60 * 60 + mi * 60 + s + 1;
//        cout << time << endl;
        int tmp = query (1, 1, 100000, max (1, time - t + 1), time);
//        cout << tmp << endl;
        if (tmp < m) res[i] = ++rn;
        else res[i] = rn;
        if (tmp >= m) flag = 1;
        updata (1, 1, 100000, time);
    }
    if (!flag) cout << "No solution\n";
    else {
        cout << rn << endl;
        for (int i = 1; i <= n; i++) {
            printf ("%d\n", res[i]);
        }
    }
}


#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>
#include <queue>
#include <bitset>
#define LL long long
#define UN unsigned short
#define ULL unsigned long long
#define pii pair <int, int>
#define piii pair <pii, int>
#define xx first
#define yy second
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l, m
#define rson rs, m + 1, r
using namespace std;

const int N = 101000;
int sum[N * 4], res[N], rn, last[N];

void updata (int rt, int l, int r, int x, int c) {
//    cout << rt << ' ' << l << ' ' << r << ' '<<x <<endl;
    if (l == r) { sum[rt] += c; return; }
    int m = (l + r) >> 1;
    if (x <= m) updata (lson, x, c);
    else updata (rson, x, c);
    sum[rt] = sum[ls] + sum[rs];
}

int query (int rt, int l, int r, int tl, int tr) {
//    cout << rt << ' ' << l <<' ' <<r << ' ' << tl << ' ' <<tr << endl;
    if (tl <= l && r <= tr) return sum[rt];
    int m = (l + r) >> 1;
    if (tr <= m) return query(lson, tl, tr);
    else if (m < tl) return query(rson, tl, tr);
    else return query (lson, tl, m) + query (rson, m + 1, tr);
}

int main () {
//    freopen ("in.txt", "r", stdin);
    int n, m, t, h, mi, s, flag = 0;
    cin >> n >> m >> t;
    for (int i = 1; i <= n; i++) {
        scanf ("%d:%d:%d", &h, &mi, &s);
        int time = h * 60 * 60 + mi * 60 + s + 1;
//        cout << time << endl;
        int tmp = query (1, 1, 100000, max (1, time - t + 1), time);
//        cout << tmp << endl;
        if (tmp < m) {
            res[i] = ++rn;
            last[rn] = time;
            updata (1, 1, 100000, time, 1);
        }
        else {
            res[i] = rn;
            updata (1, 1, 100000, time, 1);
            updata (1, 1, 100000, last[rn], -1);
            last[rn] = time;
        }
        if (tmp + 1 >= m) flag = 1;
    }
    if (!flag) cout << "No solution\n";
    else {
        cout << rn << endl;
        for (int i = 1; i <= n; i++) {
            printf ("%d\n", res[i]);
        }
    }
}


#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>
#include <queue>
#include <bitset>
#define LL long long
#define UN unsigned short
#define ULL unsigned long long
#define pii pair <int, int>
#define piii pair <pii, int>
#define xx first
#define yy second
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l, m
#define rson rs, m + 1, r
using namespace std;

const int N = 101000;
int sum[N * 4], res[N], rn;

void updata (int rt, int l, int r, int x) {
//    cout << rt << ' ' << l << ' ' << r << ' '<<x <<endl;
    if (l == r) { sum[rt]++; return; }
    int m = (l + r) >> 1;
    if (x <= m) updata (lson, x);
    else updata (rson, x);
    sum[rt] = sum[ls] + sum[rs];
}

int query (int rt, int l, int r, int tl, int tr) {
//    cout << rt << ' ' << l <<' ' <<r << ' ' << tl << ' ' <<tr << endl;
    if (tl <= l && r <= tr) return sum[rt];
    int m = (l + r) >> 1;
    if (tr <= m) return query(lson, tl, tr);
    else if (m < tl) return query(rson, tl, tr);
    else return query (lson, tl, m) + query (rson, m + 1, tr);
}

int main () {
//    freopen ("in.txt", "r", stdin);
    int n, m, t, h, mi, s, flag = 0;
    cin >> n >> m >> t;
    for (int i = 1; i <= n; i++) {
        scanf ("%d:%d:%d", &h, &mi, &s);
        int time = h * 60 * 60 + mi * 60 + s + 1;
//        cout << time << endl;
        int tmp = query (1, 1, 100000, max (1, time - t + 1), time);
//        cout << tmp << endl;
        if (tmp < m) res[i] = ++rn;
        else res[i] = rn;
        if (tmp + 1 >= m) flag = 1;
        updata (1, 1, 100000, time);
    }
    if (!flag) cout << "No solution\n";
    else {
        cout << rn << endl;
        for (int i = 1; i <= n; i++) {
            printf ("%d\n", res[i]);
        }
    }
}


#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>
#include <queue>
#include <bitset>
#define LL long long
#define UN unsigned short
#define ULL unsigned long long
#define pii pair <int, int>
#define piii pair <pii, int>
#define xx first
#define yy second
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l, m
#define rson rs, m + 1, r
using namespace std;

const int N = 101000;
int sum[N * 4], res[N], rn;

void updata (int rt, int l, int r, int x) {
//    cout << rt << ' ' << l << ' ' << r << ' '<<x <<endl;
    if (l == r) { sum[rt]++; return; }
    int m = (l + r) >> 1;
    if (x <= m) updata (lson, x);
    else updata (rson, x);
    sum[rt] = max (sum[ls], sum[rs]);
}

int query (int rt, int l, int r, int tl, int tr) {
//    cout << rt << ' ' << l <<' ' <<r << ' ' << tl << ' ' <<tr << endl;
    if (tl <= l && r <= tr) return sum[rt];
    int m = (l + r) >> 1;
    if (tr <= m) return query(lson, tl, tr);
    else if (m < tl) return query(rson, tl, tr);
    else return query (lson, tl, m) + query (rson, m + 1, tr);
}

int main () {
//    freopen ("in.txt", "r", stdin);
    int n, m, t, h, mi, s, flag = 0;
    cin >> n >> m >> t;
    for (int i = 1; i <= n; i++) {
        scanf ("%d:%d:%d", &h, &mi, &s);
        int time = h * 60 * 60 + mi * 60 + s + 1;
//        cout << time << endl;
        int tmp = query (1, 1, 100000, max (1, time - t + 1), time);
//        cout << tmp << endl;
        if (tmp < m) res[i] = ++rn;
        else res[i] = rn;
        if (tmp + 1 >= m) flag = 1;
        updata (1, 1, 100000, time);
    }
    if (!flag) cout << "No solution\n";
    else {
        cout << rn << endl;
        for (int i = 1; i <= n; i++) {
            printf ("%d\n", res[i]);
        }
    }
}


#include <cstdio>
#include <vector>
#include <set>
using namespace std;
const int MAX = 100005;
vector<int> open[MAX];
int ans[MAX];
set<pair<int, int> > s;
int main()
{
	int n, m, t;
	scanf("%d %d %d", &n, &m, &t);
	for (int i = 0; i < n; i++)
	{
		int h, m, s;
		scanf("%d:%d:%d", &h, &m, &s);
		open[h * 3600 + m * 60 + s].push_back(i);
	}
	int res = 0;
	bool flag = false;
	for (int i = 0; i < MAX; i++)
	{
		while (!s.empty() && s.begin()->first + t == i)
			s.erase(s.begin());
		for (int j = 0; j < open[i].size(); j++)
		{
			int id = open[i][j];
			if (s.size() == m)
			{
				flag = true;
				pair<int, int> p = *s.rbegin();
				s.erase(p);
				p.first = i;
				ans[id] = p.second;
				s.insert(p);
			}
			else
			{
				ans[id] = ++res;
				s.insert(make_pair(i, res));
			}
		}
	}
	if (!flag)
		printf("No solution\n");
	else
	{
		printf("%d\n", res);
		for (int i = 0; i < n; i++)
			printf("%d\n", ans[i]);
	}
	return 0;
}


#include <cstdio>
#include <vector>
#include <set>
using namespace std;
const int MAX = 100005;
vector<int> open[MAX];
int ans[MAX];
set<pair<int, int> > s;
int main()
{
	int n, m, t;
	scanf("%d %d %d", &n, &m, &t);
	for (int i = 0; i < n; i++)
	{
		int h, m, s;
		scanf("%d:%d:%d", &h, &m, &s);
		open[h * 3600 + m * 60 + s].push_back(i);
	}
	int res = 0;
	bool flag = false;
	for (int i = 0; i < MAX; i++)
	{
		while (!s.empty() && s.begin()->first + t == i)
			s.erase(s.begin());
		for (int j = 0; j < open[i].size(); j++)
		{
			int id = open[i][j];
			if (s.size() == m)
			{
				flag = true;
				pair<int, int> p = *s.rbegin();
				s.erase(p);
				p.first = i;
				ans[id] = p.second;
			}
			else
			{
				ans[id] = ++res;
				s.insert(make_pair(i, res));
			}
		}
	}
	if (!flag)
		printf("No solution\n");
	else
	{
		printf("%d\n", res);
		for (int i = 0; i < n; i++)
			printf("%d\n", ans[i]);
	}
	return 0;
}


#include <cstdio>
#include <vector>
#include <set>
using namespace std;
const int MAX = 100005;
vector<int> open[MAX];
int ans[MAX];
set<pair<int, int> > s;
int main()
{
	int n, m, t;
	scanf("%d %d %d", &n, &m, &t);
	for (int i = 0; i < n; i++)
	{
		int h, m, s;
		scanf("%d:%d:%d", &h, &m, &s);
		open[h * 3600 + m * 60 + s].push_back(i);
	}
	int res = 0;
	bool flag = false;
	for (int i = 0; i < MAX; i++)
	{
		while (!s.empty() && s.begin()->first + t == i)
			s.erase(s.begin());
		for (int j = 0; j < open[i].size(); j++)
		{
			int id = open[i][j];
			if (s.size() == m - 1)
				flag = true;
			if (s.size() == m)
			{
				pair<int, int> p = *s.rbegin();
				s.erase(p);
				p.first = i;
				ans[id] = p.second;
				s.insert(p);
			}
			else
			{
				ans[id] = ++res;
				s.insert(make_pair(i, res));
			}
		}
	}
	if (!flag)
		printf("No solution\n");
	else
	{
		printf("%d\n", res);
		for (int i = 0; i < n; i++)
			printf("%d\n", ans[i]);
	}
	return 0;
}


#include <stdio.h>

int a[20009];
char input[9];
int ans[20009];
int last[20009];

int main()
{
    int n, m, t;
    scanf("%d %d %d", &n, &m, &t);

    for (int i = 0; i < n; i++) {
        scanf("%s", input);
        a[i] = 3600*( (input[0]-'0')*10 + input[1]-'0' ) + 60*( (input[3]-'0')*10 + input[4]-'0' ) + (input[6]-'0')*10 + input[7]-'0';
    }

    ans[0] = 1;
    last[1] = 0;
    int r = 1;
    int maxOnline = 1;
    int online = 1;
    int j = 0;

    for (int i = 1; i < n; i++) {
        while (a[j] + t <= a[i]) {
            if (last[ ans[j] ] == j) online--;
            j++;
        }

        if (online == m) {
            ans[i] = ans[i-1];
        }
        else {
            r++;
            ans[i] = r;
            online++;

            if (maxOnline < online)
                maxOnline = online;
        }
        last[ ans[i] ] = i;
    }

    if (maxOnline < m) {
        printf("No solution");
    }
    else {
        printf("%d\n", r);
        for (int i = 0; i < n; i++) printf("%d\n", ans[i]);
    }
}


#include<cstdio>
#define N 20100
using namespace std;
int a[N],s[N],f[N];
int pre[N],nxt[N];
void add(int x){
	while(x<N){
		f[x]++;
		x+=x&-x;
	}
}
int sum(int x){
	int r=0;
	while(x){
		r+=f[x];
		x-=x&-x;
	}
	return r;
}
int main(){
	int i,j,n,m,t,hh,mm,ss,cut,now,k,R;
	bool flag=false,eq=false;
	scanf("%d%d%d",&n,&m,&t);
	R=n;
	for(i=0;i<n;i++){
		scanf("%d:%d:%d",&hh,&mm,&ss);
		a[i]=hh*3600+mm*60+ss;
		pre[i]=i-1;
		nxt[i]=i+1;
	}
	j=0;
	for(i=0;i<n;i++){
		while(i+1<n&&a[i]==a[i+1]) i++;
		while(a[j]+t<=a[i]) j++;
		cut=i-j+1-sum(i)+sum(j)-m;
		if(cut>=0) eq=true;
		k=i;
		while(cut>0&&k>j){
			pre[nxt[k]]=pre[k];
			s[k]=1;
			R--;
			cut--;
			add(k);
			k=pre[k];
		}
		if(cut>0){
			flag=true;
			break;
		}
	}
	if(flag||!eq){
		puts("No solution");
	}
	else{
		printf("%d\n",R);
		now=0;
		for(i=0;i<n;i++){
			if(s[i]) printf("%d\n",now);
			else printf("%d\n",++now);
		}
	}
	return 0;
}


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include <cmath>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <string.h>
#include <map>
#include <set>
#include <assert.h>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define ll long long
#define inf 1000000007
#define mod 1000000007
#define all(x) x.begin(),x.end()
#define N 20010
#define pi acos(-1.)
#define DBG(x) cerr<<#x<<"="<<x<<"\n";
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)
using namespace std;

pii a[N];int v[N],sz[N];
bool cmp(pii a,pii b){return a.y<b.y;}
int main()
{
    int i,j,k,ca=0,m,n,t;
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d",&n,&m,&t);
    for(i=0;i<n;i++){
        int h,m,s;
        scanf("%d:%d:%d",&h,&m,&s);
        s=h*3600+m*60+s;
        a[i]=mp(s,s+t-1);
    }
    sort(a,a+n,cmp);
    int id=0,cnt=0,ok=0;
    for(i=0,j=0;i<n;i++){
        int y=a[i].y;
        while(j<n&&a[j].x<=y){
            if(cnt>=m){ok=1;break;}
            if(!v[j])v[j]=++id,sz[id]++,cnt++;
            j++;
        }
        if(cnt>=m){
            k=v[j-1];
            while(j<n&&a[j].x<=y){
                if(!v[j])v[j]=k,sz[k]++;
                j++;
            }
        }
        k=v[i];sz[k]--;
        if(sz[k]==0)cnt--;
    }
    if(!ok)puts("No solution");
    else{
        printf("%d\n",id);
        for(i=0;i<n;i++)printf("%d\n",v[i]);
    }
}


#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <stdlib.h>
#include <ctime>
#include <cmath>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <string.h>
#include <map>
#include <set>
#include <assert.h>
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define ll long long
#define inf 1000000007
#define mod 1000000007
#define all(x) x.begin(),x.end()
#define N 20010
#define pi acos(-1.)
#define DBG(x) cerr<<#x<<"="<<x<<"\n";
#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)
using namespace std;

pii a[N];int v[N],sz[N];
bool cmp(pii a,pii b){return a.y<b.y;}
int main()
{
    int i,j,k,ca=0,m,n,t;
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d%d%d",&n,&m,&t);
    for(i=0;i<n;i++){
        int h,m,s;
        scanf("%d:%d:%d",&h,&m,&s);
        s=h*3600+m*60+s;
        a[i]=mp(s,s+t-1);
    }
    sort(a,a+n);
    int id=0,cnt=0,ok=0;
    for(i=0,j=0;i<n;i++){
        int y=a[i].y;
        while(j<n&&a[j].x<=y){
            if(cnt>=m){break;}
            if(!v[j])v[j]=++id,sz[id]++,cnt++;
            j++;
        }
        if(cnt>=m){
            ok=1;
            k=v[j-1];
            while(j<n&&a[j].x<=y){
                if(!v[j])v[j]=k,sz[k]++;
                j++;
            }
        }
        k=v[i];sz[k]--;
        if(sz[k]==0)cnt--;
    }
    if(!ok)puts("No solution");
    else{
        printf("%d\n",id);
        for(i=0;i<n;i++)printf("%d\n",v[i]);
    }
}


#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cstdio>
#include<cmath>
#include<string>
#define ll long long
using namespace std;
struct node
{
	int id;
	ll time;
	bool in;
};
bool operator < (node n1,node n2)
{
	if(n1.time != n2.time)return n1.time > n2.time;
	if(n2.in && !n1.in) return 1;
	if(n1.in && !n2.in) return 0;
	return n1.id > n2.id;
}
int main()
{
	ll n,m,t;
	cin>>n>>m>>t;
	int ans=0;
	int cnt=0;
	bool fnd=0;
	vector<int> fans(n);
	priority_queue<node> myq;
	vector<int> out(n,-1);
	for(int i=0;i<n;++i)
	{
		string s;
		cin>>s;
		node now;
		now.id=i;
		now.time=0;
		now.in=1;
		ll h=s[0]-'0';
		h *= 10;
		h+=s[1]-'0';
		ll m = 10*(s[3]-'0')+s[4]-'0';
		ll sec = 10*(s[6]-'0') + s[7]-'0';
		now.time = 3600ll * h + 60 *m + sec;
		myq.push(now);
	}
	while(!myq.empty())
	{
		node now=myq.top();
		myq.pop();
		if(cnt==m)fnd=1;
		if(now.in)
		{
			if(cnt==m)
			{
				fnd=1;
				fans[now.id]=ans;
				out[ans]=now.time+t-1;
				node next={ans,now.time+t-1,0};
				myq.push(next);

			}
			else
			{
				ans++;
				fans[now.id]=ans;
				cnt++;
				out[ans]=now.time+t-1;
				node next={ans,now.time+t-1,0};
				myq.push(next);
			}
		}
		else
		{
			if(out[now.id]==now.time)
			{
				cnt--;
				out[now.id]=-1;
			}
		}
	}
	if(!fnd)cout<<"No solution\n";
	else
	{
		cout<<ans<<endl;
		for(int i=0;i<n;++i)cout<<fans[i]<<endl;
	}
	return 0;
}


#include <iostream>

using namespace std;

int n,M,T;

int tiempo[100000];
int i1=0,i2=-1;
int sol[100000];

int main()
{
  ios::sync_with_stdio(false);
  cin>>n>>M>>T;
  int nextid=1;
  bool llega=false;
  for (int i=0;i<n;i++) {
    int h,m,s;
    char c1,c2;
    cin>>h>>c1>>m>>c2>>s;
    int t=3600*h+60*m+s;
    while (i1<=i2 and tiempo[i1]+T<=t) i1++;
    if (i2-i1+1==M) {
      sol[i]=nextid-1;
      tiempo[i2]=t;
    } else {
      i2++;
      tiempo[i2]=t;
      sol[i]=nextid++;
      if (i2-i1+1==M) llega=true;
    }
  }
  if (llega) {
    cout<<nextid-1<<endl;
    for (int i=0;i<n;i++)
      cout<<sol[i]<<endl;
  } else cout<<"No solution"<<endl;
}


#include <iostream>

using namespace std;

int n,M,T;

int tiempo[100000];
int i1=0,i2=-1;
int sol[100000];

int main()
{
  ios::sync_with_stdio(false);
  cin>>n>>M>>T;
  int nextid=1;
  bool llega=false;
  for (int i=0;i<n;i++) {
    int h,m,s;
    char c1,c2;
    cin>>h>>c1>>m>>c2>>s;
    int t=3600*h+60*m+s;
    while (i1<=i2 and tiempo[i2]+T<=t) i1++;
    if (i2-i1+1==M) {
      sol[i]=nextid-1;
      tiempo[i2]=t;
    } else {
      i2++;
      tiempo[i2]=t;
      sol[i]=nextid++;
      if (i2-i1+1==M) llega=true;
    }
  }
  if (llega) {
    cout<<nextid-1<<endl;
    for (int i=0;i<n;i++)
      cout<<sol[i]<<endl;
  } else cout<<"No solution"<<endl;
}


#include <iostream>
#include<memory.h>
#include <map>
#include <list>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
using namespace std;

/*
*/

int main()
{
	int n, m, t;
	cin>>n>>m>>t;
	vector<int> a(n);
	for (int i = 0; i < n; i++)
	{
		string s;
		cin>>s;
		int x = (s[0]-'0')*10 + (s[1]-'0');
		x *= 60;
		x += (s[3]-'0')*10 + (s[4]-'0');
		x *= 60;
		x += (s[6]-'0')*10 + (s[7]-'0');
		a[i] = x;
	}
	int r = 1;
	bool ok = false;
	vector<int> ans;
	for (int i = 0; i < n; i++)
	{
		vector<int> :: iterator it;
		it = lower_bound(a.begin(), a.end(), a[i]+t);
		int in = it-a.begin();
		int sz = in-i;
		if (sz >= m) ok = true;
		ans.push_back(r);
		if (sz <= m) r++;
	}
	if (!ok)
	{
		cout<<"No solution"<<endl;
		return 0;
	}
	cout<<r-1<<endl;
	for (int i = 0; i < ans.size(); i++) cout<<ans[i]<<endl;
}


#include <iostream>
#include<memory.h>
#include <map>
#include <list>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
using namespace std;

/*
*/

int main()
{
	int n, m, t;
	cin>>n>>m>>t;
	vector<int> a(n);
	for (int i = 0; i < n; i++)
	{
		string s;
		cin>>s;
		int x = (s[0]-'0')*10 + (s[1]-'0');
		x *= 60;
		x += (s[3]-'0')*10 + (s[4]-'0');
		x *= 60;
		x += (s[6]-'0')*10 + (s[7]-'0');
		a[i] = x;
	}
	int r = 1;
	bool ok = false;
	if (m > n)
	{
		cout<<"No solution"<<endl;
		return 0;
	}
	vector<int> ans(n, -1);

	int j = 0;
	for (int i = 0; i < n; i++)
	{
		if (ans[i] == -1)
		{
			if (i == 0) ans[i] = 1;
			else ans[i] = ans[i-1]+1;
		}
		while (j < a.size() && a[j]-a[i] < t)
		{
			if (ans[j] == -1)
			{
				ans[j] = ans[j-1];
				if (ans[j]-ans[i]+1 < m) ans[j]++;
			}
			j++;
		}
		if (ans[j-1]-ans[i]+1 == m) ok = true;
	}
	if (!ok)
	{
		cout<<"No solution"<<endl;
		return 0;
	}
	cout<<ans[n-1]<<endl;
	for (int i = 0; i < ans.size(); i++) cout<<ans[i]<<endl;
}


// Nugusha

#include<iostream>
#include<fstream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<ctype.h>
#include<algorithm>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<iomanip>
#include<vector>
#include<map>
#define PB(x) push_back(x)
#define MP(x, y) make_pair(x, y)
#define ff first
#define ss second
#define ll long long
#define pii pair< int, int >
#define MEM(p, v) memset(p, v, sizeof(p))
#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
#define S system("pause")
#define R return(0)
#define INF int(1e9)
#define MAX_5 int(1e5+5)
#define MAX_6 int(1e6+6)
#define ll long long
#define tree int h,int l1,int r1
#define left 2*h,l1,(l1+r1)/2
#define right 2*h+1,(l1+r1)/2+1,r1
using namespace std;
int a[MAX_5],b[MAX_5],C[MAX_5],i,m,ans,k,l,j,q,x,n,ma,mi,t,rao,TT=0,F;
string s;
char c;
vector<int>v,AN;
main()
{
    cin>>n>>m>>t;
    for(int i=0;i<n;i++)cin>>k>>c>>l>>c>>q,v.push_back(k*60*60+l*60+q),a[k*60*60+l*60+q]++;

    k=0;
    for(int i=0;i<24*60*60;i++)
    {
        k-=b[i];

        if(a[i]==0)continue;
        int ls=i;

        for(int j=0;j<a[i];j++)
        {
//          cout<<"  "<<i<<" "<<i+t-1<<"-"<<k<<" "<<m<<endl;
            if(k<m)
            {
                k++;
                AN.push_back(++TT);
                C[TT]=i+t;
            }else
            {
                AN.push_back(TT);
                b[C[TT]]--;
                C[TT]=i+t;
            }
                b[i+t]++;

            if(k==m){F=1;}

//          cout<<AN.back()<<" "<<i<<" "<<i+t-1<<"-"<<k<<" "<<m<<endl;
        }

    }
    if(!F){cout<<"No solution";return 0;}
    cout<<TT<<endl;
    for(int i=0;i<n;i++)cout<<AN[i]<<endl;
}

/*

12 4 10000
00:49:31
01:13:17
01:34:19
01:43:42
02:41:39
02:43:22
02:50:46
02:53:19
03:49:16
04:28:38
05:12:21
05:33:27

*/


#include <bits/stdc++.h>

using namespace std;

template<class T, class U>
void ckmin(T &a, U b)
{
	a = min(a, b);
}
template<class T, class U>
void ckmax(T &a, U b)
{
	a = max(a, b);
}

#define MP make_pair
#define PB push_back
#define LB lower_bound
#define UB upper_bound
#define fi first
#define se second
#define FOR(i, a, b) for (auto i = (a); i < (b); i++)
#define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--)
#define SZ(x) ((int) ((x).size()))
#define ALL(x) (x).begin(), (x).end()
#define INF 1000000007
#define LLINF 2696969696969696969ll
#define MAXN 100013

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

int N, M, T, K;
int arr[MAXN];
vi ins[MAXN], del[MAXN];
int ans[MAXN];
int freq[MAXN];
set<int> ids;

int trans(string s)
{
	int ho = ((s[0] - '0') * 10 + (s[1] - '0'));
	int mi = ((s[3] - '0') * 10 + (s[4] - '0'));
	int se = ((s[6] - '0') * 10 + (s[7] - '0'));
	return se + 60 * mi + 1440 * ho;
}

int32_t main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> N >> M >> T;
	FOR(i, 0, N)
	{
		string s; cin >> s;
		arr[i] = trans(s);
		ins[arr[i]].PB(i);
		del[arr[i] + T].PB(i);
	}
	bool ok = false;
	FOR(i, 0, 86400)
	{
		//if there are too many people, you want to choose the guy that ends latest. wait wtf
		for (int x : del[i])
		{
			freq[ans[x]]--;
			if (freq[ans[x]] == 0)
			{
				ids.erase(ans[x]);
			}
		}
		for (int x : ins[i])
		{
			if (SZ(ids) < M) K++;
			ans[x] = K - 1;
			ids.insert(ans[x]);
			freq[ans[x]]++;
		}
		if (SZ(ids) == M) ok = true;
	}
	if (!ok)
	{
		cout << "No solution\n";
		return 0;
	}
	cout << K << '\n';
	FOR(i, 0, N)
	{
		cout << ans[i] + 1 << '\n';
	}
	//distinct users!
}


#include <bits/stdc++.h>

using namespace std;

template<class T, class U>
void ckmin(T &a, U b)
{
	a = min(a, b);
}
template<class T, class U>
void ckmax(T &a, U b)
{
	a = max(a, b);
}

#define MP make_pair
#define PB push_back
#define LB lower_bound
#define UB upper_bound
#define fi first
#define se second
#define FOR(i, a, b) for (auto i = (a); i < (b); i++)
#define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--)
#define SZ(x) ((int) ((x).size()))
#define ALL(x) (x).begin(), (x).end()
#define INF 1000000007
#define LLINF 2696969696969696969ll
#define MAXN 100013

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

int N, M, T, K;
int arr[MAXN];
vi ins[MAXN], del[MAXN];
int ans[MAXN];
int freq[MAXN];
set<int> ids;

int trans(string s)
{
	int ho = ((s[0] - '0') * 10 + (s[1] - '0'));
	int mi = ((s[3] - '0') * 10 + (s[4] - '0'));
	int se = ((s[6] - '0') * 10 + (s[7] - '0'));
	return se + 60 * mi + 3600 * ho;
}

int32_t main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> N >> M >> T;
	FOR(i, 0, N)
	{
		string s; cin >> s;
		arr[i] = trans(s);
		// cerr << arr[i] << endl;
		ins[arr[i]].PB(i);
		del[arr[i] + T].PB(i);
	}
	bool ok = false;
	FOR(i, 0, 86400)
	{
		//if there are too many people, you want to choose the guy that ends latest. wait wtf
		for (int x : del[i])
		{
			freq[ans[x]]--;
			if (freq[ans[x]] == 0)
			{
				ids.erase(ans[x]);
			}
		}
		for (int x : ins[i])
		{
			if (SZ(ids) < M) K++;
			ans[x] = K - 1;
			ids.insert(ans[x]);
			freq[ans[x]]++;
		}
		if (SZ(ids) == M) ok = true;
	}
	if (!ok)
	{
		cout << "No solution\n";
		return 0;
	}
	cout << K << '\n';
	FOR(i, 0, N)
	{
		cout << ans[i] + 1 << '\n';
	}
	//distinct users!
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
//---

const int N = 101010;

bool reach;
int n, m, t, cnt, l, r;
int a[N], ans[N], que[N];

int main() {
	scanf("%d%d%d", &n, &m, &t);
	rep(i, 1, n+1) {
		int x, y, z;
		scanf("%d:%d:%d", &x, &y, &z);
		a[i] = x * 3600 + y * 60 + z;
	}
	l = 1, r = 0;
	rep(i, 1, n+1) {
		while(l <= r && a[que[l]] < a[i] - t + 1) ++l;
		if(r - l + 1 < m) {
			ans[i] = ++cnt;
			que[++r] = i;
		} else {
			reach = 1;
			ans[i] = cnt;
			que[r] = i;
		}
	}
	if(reach) {
		printf("%d\n", cnt);
		rep(i, 1, n+1) printf("%d\n", ans[i]);
	} else {
		puts("No solution");
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
//---

const int N = 101010;

bool reach;
int n, m, t, cnt, l, r;
int a[N], ans[N], que[N];

int main() {
	scanf("%d%d%d", &n, &m, &t);
	rep(i, 1, n+1) {
		int x, y, z;
		scanf("%d:%d:%d", &x, &y, &z);
		a[i] = x * 3600 + y * 60 + z;
	}
	l = 1, r = 0;
	rep(i, 1, n+1) {
		while(l <= r && a[que[l]] < a[i] - t + 1) ++l;
		if(r - l + 1 < m) {
			ans[i] = ++cnt;
			que[++r] = i;
		} else {
			ans[i] = cnt;
			que[r] = i;
		}
		if(r - l + 1 >= m) reach = 1;
	}
	if(reach) {
		printf("%d\n", cnt);
		rep(i, 1, n+1) printf("%d\n", ans[i]);
	} else {
		puts("No solution");
	}
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define debug(x) cerr << #x << " : " << x << '\n'

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef string str;
typedef pair<ll, ll> pll;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const ll Mod = 1000000007LL;
const int Maxn = 2e5 + 10;
const int Maxm = 86500;
const ll Inf = 2242545357980376863LL;
const ll Log = 30;

vector<ll> rec[Maxm];
multiset<pll> ms;
vector<ll> G[Maxn];
ll mk[Maxn];

void DFS(ll u, ll c){
	mk[u] = c;
	for(auto adj : G[u]) if(!mk[adj]) DFS(adj, c);
}

vector<ll> V;

int main(){
	//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	ll n, m, T;
	scanf("%lld%lld%lld", &n, &m, &T);
	int h, mt, s;
	for(int i = 0; i < n; i++){
		scanf("%2d:%2d:%2d", &h, &mt, &s);
		rec[3600 * h + 60 * mt + s].pb(i);
	}
	ll mx = 0, mn, nw, U;
	for(int i = 0; i < Maxm; i++){
		while(!ms.empty() && (ms.begin() -> F < i) ) ms.erase(--ms.end());
		for(auto x : rec[i]) ms.insert({i + T - 1, x});
		mx = max(mx, (ll) ms.size());
		if(ms.size() <= m) continue;
		//mn = ms.begin() -> S;
		nw = ms.rbegin() -> F;
		V.clear();
		while(ms.size() > m){
			U = ms.rbegin() -> S;
			V.pb(U);
			ms.erase(--ms.end());
		}
		mn = ms.rbegin() -> S;
		for(auto x : V){
			G[x].pb(mn);
			G[mn].pb(x);
		}
		ms.erase(--ms.end());
		ms.insert({nw, mn});
	}
	if(mx < m) return cout << "No solution", 0;
	ll ans = 0;
	for(int i = 0; i < n; i++) if(!mk[i]) DFS(i, ++ans);
	cout << ans << '\n';
	for(int i = 0; i < n; i++) cout << mk[i] << '\n';
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define debug(x) cerr << #x << " : " << x << '\n'

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef string str;
typedef pair<ll, ll> pll;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const ll Mod = 1000000007LL;
const int Maxn = 2e4 + 10;
const int Maxm = 86500;
const ll Inf = 2242545357980376863LL;
const ll Log = 30;

vector<ll> rec[Maxm];
multiset<pll> ms;
vector<ll> G[Maxn];
ll mk[Maxn];

void DFS(ll u, ll c){
	mk[u] = c;
	for(auto adj : G[u]) if(!mk[adj]) DFS(adj, c);
}

vector<ll> V;

int main(){
	//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	ll n, m, T;
	scanf("%lld%lld%lld", &n, &m, &T);
	int h, mt, s;
	for(int i = 0; i < n; i++){
		scanf("%2d:%2d:%2d", &h, &mt, &s);
		rec[3600 * h + 60 * mt + s].pb(i);
	}
	ll mx = 0, mn, nw, U;
	for(int i = 0; i < Maxm; i++){
		while(!ms.empty() && (ms.begin() -> F < i) ) ms.erase(--ms.end());
		for(auto x : rec[i]) ms.insert({i + T - 1, x});
		mx = max(mx, (ll) ms.size());
		if(ms.size() <= m) continue;
		//mn = ms.begin() -> S;
		nw = ms.rbegin() -> F;
		V.clear();
		while(ms.size() > m){
			U = ms.rbegin() -> S;
			V.pb(U);
			ms.erase(--ms.end());
		}
		mn = ms.rbegin() -> S;
		for(auto x : V){
			G[x].pb(mn);
			G[mn].pb(x);
		}
		ms.erase(--ms.end());
		ms.insert({nw, mn});
	}
	if(mx < m) return cout << "No solution", 0;
	ll ans = 0;
	for(int i = 0; i < n; i++) if(!mk[i]) DFS(i, ++ans);
	cout << ans << '\n';
	for(int i = 0; i < n; i++) cout << mk[i] << '\n';
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define debug(x) cerr << #x << " : " << x << '\n'

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef string str;
typedef pair<ll, ll> pll;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const ll Mod = 1000000007LL;
const int Maxn = 2e4 + 10;
const int Maxm = 86500;
const ll Inf = 2242545357980376863LL;
const ll Log = 30;

vector<ll> rec[Maxm];
multiset<pll> ms;
vector<ll> G[Maxn];
ll mk[Maxn];

void DFS(ll u, ll c){
	mk[u] = c;
	for(auto adj : G[u]) if(!mk[adj]) DFS(adj, c);
}

int main(){
	//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	ll n, m, T;
	scanf("%lld%lld%lld", &n, &m, &T);
	int h, mt, s;
	for(int i = 0; i < n; i++){
		scanf("%2d:%2d:%2d", &h, &mt, &s);
		rec[3600 * h + 60 * mt + s].pb(i);
	}
	ll mx = 0, mn, nw, U;
	for(int i = 0; i < Maxm; i++){
		while(!ms.empty() && (ms.rbegin() -> F < i) ) ms.erase(--ms.end());
		for(auto x : rec[i]) ms.insert({i + T - 1, x});
		mx = max(mx, (ll) ms.size());
		if(ms.size() <= m) continue;
		mn = ms.begin() -> S;
		nw = ms.rbegin() -> F;
		while(ms.size() > m){
			U = ms.rbegin() -> S;
			G[U].pb(mn);
			G[mn].pb(U);
			ms.erase(--ms.end());
		}
		ms.erase(ms.begin());
		ms.insert({nw, mn});
	}
	if(mx < m) return cout << "No solution", 0;
	ll ans = 0;
	for(int i = 0; i < n; i++) if(!mk[i]) DFS(i, ++ans);
	cout << ans << '\n';
	for(int i = 0; i < n; i++) cout << mk[i] << '\n';
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define debug(x) cerr << #x << " : " << x << '\n'

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef string str;
typedef pair<ll, ll> pll;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const ll Mod = 1000000007LL;
const int Maxn = 2e4 + 10;
const int Maxm = 86500;
const ll Inf = 2242545357980376863LL;
const ll Log = 30;

vector<ll> rec[Maxm];
multiset<pll> ms;
vector<ll> G[Maxn];
ll mk[Maxn];

void DFS(ll u, ll c){
	mk[u] = c;
	for(auto adj : G[u]) if(!mk[adj]) DFS(adj, c);
}

int main(){
	//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	ll n, m, T;
	scanf("%lld%lld%lld", &n, &m, &T);
	int h, mt, s;
	for(int i = 0; i < n; i++){
		scanf("%2d:%2d:%2d", &h, &mt, &s);
		rec[3600 * h + 60 * mt + s].pb(i);
	}
	ll mx = 0, mn, nw, U;
	for(int i = 0; i < Maxm; i++){
		while(!ms.empty() && (ms.rbegin() -> F < i) ) ms.erase(--ms.end());
		for(auto x : rec[i]) ms.insert({i + T, x});
		mx = max(mx, (ll) ms.size());
		if(ms.size() <= m) continue;
		mn = ms.begin() -> S;
		nw = ms.rbegin() -> F;
		while(ms.size() > m){
			U = ms.rbegin() -> S;
			G[U].pb(mn);
			G[mn].pb(U);
			ms.erase(--ms.end());
		}
		ms.erase(ms.begin());
		ms.insert({nw, mn});
	}
	if(mx < m) return cout << "No solution", 0;
	ll ans = 0;
	for(int i = 0; i < n; i++) if(!mk[i]) DFS(i, ++ans);
	cout << ans << '\n';
	for(int i = 0; i < n; i++) cout << mk[i] << '\n';
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define debug(x) cerr << #x << " : " << x << '\n'

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef string str;
typedef pair<ll, ll> pll;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const ll Mod = 1000000007LL;
const int Maxn = 2e5 + 10;
const int Maxm = 86500;
const ll Inf = 2242545357980376863LL;
const ll Log = 30;

vector<ll> rec[Maxm];
multiset<pll> ms;
vector<ll> G[Maxn];
ll mk[Maxn];

void DFS(ll u, ll c){
	mk[u] = c;
	for(auto adj : G[u]) if(!mk[adj]) DFS(adj, c);
}

vector<ll> V;

int main(){
	//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	ll n, m, T;
	scanf("%lld%lld%lld", &n, &m, &T);
	int h, mt, s;
	for(int i = 0; i < n; i++){
		scanf("%2d:%2d:%2d", &h, &mt, &s);
		rec[3600 * h + 60 * mt + s].pb(i);
	}
	ll mx = 0, mn, nw, U;
	for(int i = 0; i < Maxm; i++){
		while(!ms.empty() && (ms.begin() -> F < i) ) ms.erase(ms.begin());
		for(auto x : rec[i]) ms.insert({i + T - 1, x});
		mx = max(mx, (ll) ms.size());
		if(((ll)ms.size()) <= m) continue;
		//mn = ms.begin() -> S;
		nw = ms.rbegin() -> F;
		V.clear();
		while(((ll)ms.size()) > m){
			U = ms.rbegin() -> S;
			V.pb(U);
			ms.erase(--ms.end());
		}
		mn = ms.rbegin() -> S;
		for(auto x : V){
			G[x].pb(mn);
			G[mn].pb(x);
		}
		ms.erase(--ms.end());
		ms.insert({nw, mn});
	}
	if(mx < m) return cout << "No solution", 0;
	ll ans = 0;
	for(int i = 0; i < n; i++) if(!mk[i]) DFS(i, ++ans);
	cout << ans << '\n';
	for(int i = 0; i < n; i++) cout << mk[i] << '\n';
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n, m, t;
int ans[20005];
int tot, found;
priority_queue <pair <int, int> > q;

int cv(char a, char b) { return 10 * (a - '0') + (b - '0'); }

int main(void) {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n >> m >> t;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        int l = 3600 * cv(s[0], s[1]) + 60 * cv(s[3], s[4]) + cv(s[6], s[7]);
        int r = l + t - 1;
        while (!q.empty() && q.top().first < l) q.pop();
        if (q.size() < m) ans[i] = ++tot;
        else {
            int id = q.top().second; q.pop();
            ans[i] = id;
        }
        q.push(make_pair(r, ans[i]));
        if (q.size() == m) found = 1;
    }
    if (!found) return cout << "No solution\n", 0;
    cout << tot << '\n';
    for (int i = 0; i < n; ++i) cout << ans[i] << '\n';
}


#include <bits/stdc++.h>

using namespace std;

int n, m, t;
int ans[20005];
int tot, found;
set<pair <int, int> > q;

int cv(char a, char b) { return 10 * (a - '0') + (b - '0'); }

int main(void) {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n >> m >> t;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        int l = 3600 * cv(s[0], s[1]) + 60 * cv(s[3], s[4]) + cv(s[6], s[7]);
        int r = l + t - 1;
        while (!q.empty() && q.begin()->first < l) q.erase(q.begin());
        if (q.size() < m) ans[i] = ++tot;
        else {
            int id = (--q.end())->second; q.erase(--q.end());
            ans[i] = id;
        }
        q.insert(make_pair(r, ans[i]));
        if (q.size() == m) found = 1;
    }
    if (!found) return cout << "No solution\n", 0;
    cout << tot << '\n';
    for (int i = 0; i < n; ++i) cout << ans[i] << '\n';
}


#include <cstdio>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;

typedef pair <int, int> ii;

int n, M, T;
int res;
vector <int> seq;
deque <ii> D;
bool was;

int getTim(char s[])
{
	int h = (s[0] - '0') * 10 + s[1] - '0';
	int mn = (s[3] - '0') * 10 + s[4] - '0';
	int sc = (s[6] - '0') * 10 + s[7] - '0';
	return sc + 60 * (mn + 60 * h);
}

int main()
{
	scanf("%d %d %d", &n, &M, &T);
	char str[15];
	for (int i = 0; i < n; i++) {
		scanf("%s", str);
		int tim = getTim(str);
		if (!D.empty() && D[0].first < tim) D.pop_front();
		if (D.size() < M) {
			D.push_back(ii(tim + T - 1, ++res));
			seq.push_back(res);
		} else {
			D.back().first = tim + T - 1;
			seq.push_back(D.back().second);
		}
		if (D.size() == M) was = true;
	}
	if (was) {
		printf("%d\n", res);
		for (int i = 0; i < seq.size(); i++)
			printf("%d\n", seq[i]);
	} else printf("No solution\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 20004;
int users[N];

int main() {
//  ios::sync_with_stdio(0), cin.tie(NULL), cout.tie(NULL);
#ifndef ONLINE_JUDGE
  freopen("test.in", "rt", stdin);
//  freopen("o.txt", "wt", stdout);
#endif

  deque<int> curr;

  int n, m, t;
  cin >> n >> m >> t;
  --t;
  bool reached = false;
  int cnt_users = 0;
  for (int i = 0; i < n; ++i) {
    int a, b, c;
    char tmp;
    cin >> a >> tmp >> b >> tmp >> c;
    c += 60 * (b + 60 * a);
    while (!curr.empty() && curr.back() < c) {
      curr.pop_back();
    }
    if (curr.size() == m) {
      curr.pop_front();
    } else {
      ++cnt_users;
    }
    users[i] = cnt_users;
    curr.push_front(c + t);
    reached |= curr.size() == m;
  }

  if (!reached) {
    cout << "No solution\n";
  } else {
    cout << cnt_users << '\n';
    for (int i = 0; i < n; ++i) {
      cout << users[i] << '\n';
    }
  }

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = 20004;
int users[N];

int main() {
//  ios::sync_with_stdio(0), cin.tie(NULL), cout.tie(NULL);
#ifndef ONLINE_JUDGE
  freopen("test.in", "rt", stdin);
//  freopen("o.txt", "wt", stdout);
#else
  freopen("matrix.in", "rt", stdin);
  freopen("matrix.out", "wt", stdout);
#endif

  deque<int> curr;

  int n, m, t;
  cin >> n >> m >> t;
  --t;
  bool reached = false;
  int cnt_users = 0;
  for (int i = 0; i < n; ++i) {
    int a, b, c;
    char tmp;
    cin >> a >> tmp >> b >> tmp >> c;
    c += 60 * (b + 60 * a);
    while (!curr.empty() && curr.back() < c) {
      curr.pop_back();
    }
    if (curr.size() == m) {
      curr.pop_front();
    } else {
      ++cnt_users;
    }
    users[i] = cnt_users;
    curr.push_front(c + t);
    reached |= curr.size() == m;
  }

  if (!reached) {
    cout << "No solution\n";
  } else {
    cout << cnt_users << '\n';
    for (int i = 0; i < n; ++i) {
      cout << users[i] << '\n';
    }
  }

  return 0;
}