#include <bits/stdc++.h>

#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif

#ifdef __WIN32
#define LLFORMAT "I64"
#define Rand() ((rand() << 15) + rand())
#else
#define LLFORMAT "ll"
#define Rand() (rand())
#endif

using namespace std;

const int maxn = 1e5 + 10;

set<int> foo;
int n, q, clk, fst[maxn], out[maxn], pre[maxn], nxt[maxn], cnt_fst[maxn][10], cnt_out[maxn][10], cnt[10];
char s[maxn];

int main(int argc, char *argv[]) {
	scanf("%d%d", &n, &q);
	scanf("%s", s + 1);
	for (int i = 1; i <= n; ++i) {
		pre[i] = i - 1;
		nxt[i] = i + 1;
		foo.insert(i);
	}
	nxt[0] = 1;
	pre[n + 1] = n;
	s[0] = '>';
	for (int i = nxt[0], dir = 1; i <= n; ) {
		++clk;
		if(!i) {
			dir = 1;
			i = nxt[i];
			continue;
		}
		if(!fst[i]) {
			fst[i] = clk;
			memcpy(cnt_fst[i], cnt, sizeof cnt);
		}
		if(s[i] == '<') {
			dir = 0;
		}
		if(s[i] == '>') {
			dir = 1;
		}
		int j = (dir == 1 ? nxt[i] : pre[i]);
		if(s[i] == '<' || s[i] == '>') {
			if(j <= n) {
				if(s[j] == '<' || s[j] == '>') {
					pre[nxt[i]] = pre[i];
					nxt[pre[i]] = nxt[i];
				}
			}
		}
		else {
			++cnt[s[i] - '0'];
			if(s[i] == '0') {
				pre[nxt[i]] = pre[i];
				nxt[pre[i]] = nxt[i];
			}
			else {
				--s[i];
			}
		}
		i = j;
		for(;;) {
			auto it = foo.lower_bound(j + 1);
			if(it == foo.end() || !fst[*it]) {
				break;
			}
			out[*it] = clk;
			memcpy(cnt_out[*it], cnt, sizeof cnt);
			foo.erase(it);
		}
	}
	fst[n + 1] = ++clk;
	memcpy(cnt_fst[n + 1], cnt, sizeof cnt);
	while(q--) {
		int l, r;
		scanf("%d%d", &l, &r);
		if(!out[l] || out[l] > fst[r + 1]) {
			for (int c = 0; c < 10; ++c) {
				printf("%d%c", cnt_fst[r + 1][c] - cnt_fst[l][c], " \n"[c == 9]);
			}
		}
		else {
			for (int c = 0; c < 10; ++c) {
				printf("%d%c", cnt_out[l][c] - cnt_fst[l][c], " \n"[c == 9]);
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
template<class T>inline void tense(T &a,const T &b){
	if(b<a)
		a=b;
}
const int MaxN = 100005;
const int MaxM = 100005;
const int ND = 10;
int n, m;
char prog[MaxN];
int prev[MaxN];
int next[MaxN];
int occur_l[MaxN][ND];
int occur_r[MaxN][ND];
int occur[ND];
int book[MaxN];

inline void init_l(){
	for(int i=0;i<=n+1;++i)
		prev[i]=i-1,next[i]=i+1;
}

inline void remove_l(const int &x){
	prev[next[x]]=prev[x];
	next[prev[x]]=next[x];
}

inline bool is_dir(const char &c){
	return c=='<'||c=='>';
}

inline void prog_run(int now){
	int last=0;
	char dir='>';
	while(now>0&&now<=n){
		if(!book[now]){
			for(int i=0;i<ND;++i)
				occur_l[now][i]=occur[i];
			book[now]=1;
		}
		if(is_dir(prog[now])){
			dir=prog[now];
			if(is_dir(prog[last])){
				if(book[last]==2)
					remove_l(last);
				else
					prog[last] = 'R';
			}
			last=now;
	}else
		if(prog[now]>='0'&&prog[now]<='9'){
				++occur[prog[last=now]-'0'];
			if(prog[now]>'0')
				--prog[now];
			else{
				if(book[now]==2)
					remove_l(now);
				else
					prog[now]='R';
			}
		}
		if(dir=='<'&&book[now]==1){
			book[now]=2;
			for(int i=0;i<ND;++i)
				occur_r[now][i]=occur[i];
			if(prog[now]=='R')
				remove_l(now);
		}
		if(dir=='<')
			now=prev[now];
		else
			now=next[now];
	}
}

inline void prog_run(){
	init_l();
	while (next[0] != n + 1){
		prog_run(next[0]);
		while(next[0]!=n+1&&book[next[0]])
			remove_l(next[0]);
	}
	for(int i=0;i<ND;++i)
		occur_l[n+1][i]=occur[i];
}

inline void query(int l,int r){
	for(int i=0;i<ND;++i)
		occur[i]=occur_l[r+1][i];
	if(book[l]==2)
		for(int i=0;i<ND;++i)
			tense(occur[i],occur_r[l][i]);
	for(int i=0;i<ND;++i)
		printf("%d ",occur[i]-occur_l[l][i]);
	printf("\n");
}

int main(){
	scanf("%d %d",&n,&m);
	scanf("%s",prog+1);
	prog_run();
	while(m--){
		int l,r;
		scanf("%d %d",&l,&r);
		query(l,r);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int INF=1000000;
int n;
int a[INF+10];
bool vis[INF+10], pass[INF+10];
vector<int> ans;

void init(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		vis[a[i]]=true;
	}
}

void solve(){
	int j = 1;
	for(int i=1;i<=n;i++){
		int tmp = INF+1-a[i];
		if(pass[a[i]])
			continue;
		pass[a[i]]=true;
		pass[tmp]=true;
		if(!vis[tmp]){
			vis[tmp]=true;
			ans.push_back(tmp);
		}else{
			while(vis[j]||vis[INF+1-j])
				j++;
			ans.push_back(j);
			ans.push_back(INF+1-j);
			vis[j]=true;
			vis[INF+1-j]=true;
		}
	}
	printf("%d\n",ans.size());
	for(int i=0;i<ans.size();i++)
		printf("%d ",ans[i]);
}

int main(){
	init();
	solve();
}


#include<bits/stdc++.h>
using namespace std;
template<class T>inline void tense(T &a,const T &b){
	if(b<a)
		a=b;
}
const int MaxN = 100005;
const int MaxM = 100005;
const int ND = 10;
int n, m;
char prog[MaxN];
int pre[MaxN];
int nxt[MaxN];
int occur_l[MaxN][ND];
int occur_r[MaxN][ND];
int occur[ND];
int book[MaxN];

inline void init_l(){
	for(int i=0;i<=n+1;++i)
		pre[i]=i-1,nxt[i]=i+1;
}

inline void remove_l(const int &x){
	pre[nxt[x]]=pre[x];
	nxt[pre[x]]=nxt[x];
}

inline bool is_dir(const char &c){
	return c=='<'||c=='>';
}

inline void prog_run(int now){
	int last=0;
	char dir='>';
	while(now>0&&now<=n){
		if(!book[now]){
			for(int i=0;i<ND;++i)
				occur_l[now][i]=occur[i];
			book[now]=1;
		}
		if(is_dir(prog[now])){
			dir=prog[now];
			if(is_dir(prog[last])){
				if(book[last]==2)
					remove_l(last);
				else
					prog[last] = 'R';
			}
			last=now;
	}else
		if(prog[now]>='0'&&prog[now]<='9'){
				++occur[prog[last=now]-'0'];
			if(prog[now]>'0')
				--prog[now];
			else{
				if(book[now]==2)
					remove_l(now);
				else
					prog[now]='R';
			}
		}
		if(dir=='<'&&book[now]==1){
			book[now]=2;
			for(int i=0;i<ND;++i)
				occur_r[now][i]=occur[i];
			if(prog[now]=='R')
				remove_l(now);
		}
		if(dir=='<')
			now=pre[now];
		else
			now=nxt[now];
	}
}

inline void prog_run(){
	init_l();
	while (nxt[0] != n + 1){
		prog_run(nxt[0]);
		while(nxt[0]!=n+1&&book[nxt[0]])
			remove_l(nxt[0]);
	}
	for(int i=0;i<ND;++i)
		occur_l[n+1][i]=occur[i];
}

inline void query(int l,int r){
	for(int i=0;i<ND;++i)
		occur[i]=occur_l[r+1][i];
	if(book[l]==2)
		for(int i=0;i<ND;++i)
			tense(occur[i],occur_r[l][i]);
	for(int i=0;i<ND;++i)
		printf("%d ",occur[i]-occur_l[l][i]);
	printf("\n");
}

int main(){
	scanf("%d %d",&n,&m);
	scanf("%s",prog+1);
	prog_run();
	while(m--){
		int l,r;
		scanf("%d %d",&l,&r);
		query(l,r);
	}
	return 0;
}


#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>

const size_t maxN = 100005, maxR = maxN * 10 + 1;

int N, Q;
char S[maxN];
int Next[maxN], Pre[maxN];
int Left[maxN], Right[maxN], Ans[maxR][10];
bool Del[maxN];

inline void del(int i)
{
	//Del[i] = true;
	Next[Pre[i]] = Next[i];
	Pre[Next[i]] = Pre[i];
}

int main()
{
	scanf("%d%d%s", &N, &Q, S + 1);
	S[0] = '>';
	for (int i = 1; i <= N; ++i)
		Next[i] = i + 1, Pre[i] = i - 1;
	Next[0] = 1;

	memset(Left, 0x3F, sizeof(Left));
	memset(Right, 0x3F, sizeof(Right));

	int pos = 1, cur = 1, dir = 1, lastpos = 0;
	Left[1] = 1;

	while (pos != N + 1)
	{
		if (!Del[pos])
		{
			if (isdigit(S[pos]))
			{
				++Ans[cur][S[pos] ^ '0'], --S[pos];
				if (S[pos] == '0' - 1)
					Del[pos] = true;
			}
			else
				dir = S[pos] == '>' ? 1 : -1;
		}
		if (dir == -1)
		{
			if (!Right[pos])
				Right[pos] = cur;
			if (Del[pos])
				del(pos);
		}
		pos = dir == 1 ? Next[pos] : Pre[pos];
		if (Del[pos])
			continue;
		++cur;
		for (int j = 0; j != 10; ++j)
			Ans[cur][j] = Ans[cur - 1][j];
		if (dir == 1 && !Left[pos])
			Left[pos] = cur;
		if (lastpos && !isdigit(S[pos]) && !isdigit(S[lastpos]))
			Del[lastpos] = true;
		lastpos = pos;
	}

	for (int l, r; Q--;)
	{
		scanf("%d%d", &l, &r);
		for (int i = 0; i != 10; ++i)
			printf("%d%c", Ans[std::min(Right[l], Left[r + 1] - 1)][i] - Ans[Left[l] - 1][i], " \n"[i == 9]);
	}

	return 0;
}


#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>

const size_t maxN = 100005, maxR = maxN * 10 + 1;

int N, Q;
char S[maxN];
int Next[maxN], Pre[maxN];
int Left[maxN], Right[maxN], Ans[maxR][10];
bool Del[maxN];

inline void del(int i)
{
	//Del[i] = true;
	Next[Pre[i]] = Next[i];
	Pre[Next[i]] = Pre[i];
}

int main()
{
	scanf("%d%d%s", &N, &Q, S + 1);
	S[0] = '>';
	for (int i = 1; i <= N; ++i)
		Next[i] = i + 1, Pre[i] = i - 1;
	Next[0] = 1;

	memset(Left, 0x3F, sizeof(Left));
	memset(Right, 0x3F, sizeof(Right));

	int pos = 1, cur = 1, dir = 1, lastpos = 0;
	Left[1] = 1;

	while (pos != N + 1)
	{
		if (!Del[pos])
		{
			if (isdigit(S[pos]))
			{
				++Ans[cur][S[pos] ^ '0'], --S[pos];
				if (S[pos] == '0' - 1)
					Del[pos] = true;
			}
			else
				dir = S[pos] == '>' ? 1 : -1;
		}
		if (dir == -1)
		{
			if (Right[pos] == 0x3F3F3F3F)
				Right[pos] = cur;
			if (Del[pos])
				del(pos);
		}
		pos = dir == 1 ? Next[pos] : Pre[pos];
		if (Del[pos])
			continue;
		++cur;
		for (int j = 0; j != 10; ++j)
			Ans[cur][j] = Ans[cur - 1][j];
		if (dir == 1 && Left[pos] == 0x3F3F3F3F)
			Left[pos] = cur;
		if (lastpos && !isdigit(S[pos]) && !isdigit(S[lastpos]))
			Del[lastpos] = true;
		lastpos = pos;
	}

	for (int l, r; Q--;)
	{
		scanf("%d%d", &l, &r);
		for (int i = 0; i != 10; ++i)
			printf("%d%c", Ans[std::min(Right[l], Left[r + 1] - 1)][i] - Ans[Left[l] - 1][i], " \n"[i == 9]);
	}

	return 0;
}


#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>

const size_t ioSize = 1 << 21;
char oBuf[ioSize], *oS(oBuf), *oE(oBuf + ioSize);
inline void flush()
{
	fwrite(oBuf, 1, oS - oBuf, stdout);
	oS = oBuf;
}
inline void putc(char c)
{
	*oS++ = c;
	if (oS == oE)
		flush();
}
void puti(int x)
{
	static char qu[20];
	char *qr = qu;

	do
		*qr++ = x % 10 ^ '0';
	while (x /= 10);

	while (qr != qu)
		putc(*--qr);
}

const size_t maxN = 100005, maxR = maxN * 10 + 1;

int N, Q;
char S[maxN];
int Next[maxN], Pre[maxN];
int Left[maxN], Right[maxN], Ans[maxR][10];
bool Del[maxN];

inline void del(int i)
{
	//Del[i] = true;
	Next[Pre[i]] = Next[i];
	Pre[Next[i]] = Pre[i];
}

int main()
{
	scanf("%d%d%s", &N, &Q, S + 1);
	S[0] = '>';
	for (int i = 1; i <= N; ++i)
		Next[i] = i + 1, Pre[i] = i - 1;
	Next[0] = 1;

	memset(Left, 0x3F, sizeof(Left));
	memset(Right, 0x3F, sizeof(Right));

	int pos = 1, cur = 1, dir = 1, lastpos = 0;
	Left[1] = 1;

	while (pos != N + 1)
	{
		if (!Del[pos])
		{
			if (isdigit(S[pos]))
			{
				++Ans[cur][S[pos] ^ '0'], --S[pos];
				if (S[pos] == '0' - 1)
					Del[pos] = true;
			}
			else
				dir = S[pos] == '>' ? 1 : -1;
		}
		if (dir == -1)
		{
			if (Right[pos] == 0x3F3F3F3F)
				Right[pos] = cur;
			if (Del[pos])
				del(pos);
		}
		pos = dir == 1 ? Next[pos] : Pre[pos];
		if (Del[pos])
			continue;
		++cur;
		for (int j = 0; j != 10; ++j)
			Ans[cur][j] = Ans[cur - 1][j];
		if (dir == 1 && Left[pos] == 0x3F3F3F3F)
			Left[pos] = cur;
		if (lastpos && !isdigit(S[pos]) && !isdigit(S[lastpos]))
			Del[lastpos] = true;
		lastpos = pos;
	}

	for (int l, r; Q--;)
	{
		scanf("%d%d", &l, &r);
		for (int i = 0; i != 10; ++i)
			puti(Ans[std::min(Right[l], Left[r + 1] - 1)][i] - Ans[Left[l] - 1][i]), putc(" \n"[i == 9]);
			//printf("%d%c", Ans[std::min(Right[l], Left[r + 1] - 1)][i] - Ans[Left[l] - 1][i], " \n"[i == 9]);
	}

	flush();

	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)x.size())
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
typedef long long LL;
typedef pair<int,int> pa;
typedef vector<int> vec;
void getint(int &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
const int INF=1e9+10;
char s[500010],TMP[2100010];
vec v[2100000];
int n,q,ts,L[500010],tmp[5000010],R[500010],ans[100010][10],w[500010],bc[500010],l[500010],r[500010],f[2100010][10],fiap[500010],fil[500010],fir[500010];
int walk(int x,int d){
	if (d==1) return R[x];
	else return L[x];
}
void del(int x){
	L[R[x]]=L[x];
	R[L[x]]=R[x];
}
void mov(int S){
	int now=S;
	int d=1;
	tmp[++ts]=S;
	TMP[ts]=s[now];
	fiap[S]=ts;
	while (1) {
		int NOW;
		if (s[now]=='>' || s[now]=='<'){
			d=((s[now]=='>')?1:-1);
			NOW=walk(now,d);
			tmp[++ts]=NOW;
			TMP[ts]=s[NOW];
			if (!fiap[NOW]){
				fiap[NOW]=ts;
				bc[NOW]=L[NOW];
			}
			if (NOW>n) return;
			if (s[NOW]=='<' || s[NOW]=='>'){
				del(now);
			}
			now=NOW;
		}
		else{
			NOW=walk(now,d);
			tmp[++ts]=NOW;
			TMP[ts]=s[NOW];
			if (!fiap[NOW]){
				fiap[NOW]=ts;
				bc[NOW]=L[NOW];
			}
			if (NOW>n) return;
			--s[now];
			if (s[now]<'0') del(now);
			now=NOW;
		}
	}
}
int main(){
	cin>>n>>q;
	FOR(i,1,n) s[i]='>';
	scanf("%s",s+n+1);
	n<<=1;
	FOR(i,0,n) R[i]=i+1,L[i+1]=i;
	mov(n/2+1);
	tmp[0]=n/2;
	FOR(i,1,ts){
		FOR(j,0,9) f[i][j]=f[i-1][j]+(TMP[i]==j+'0');
	}

	FOR(i,1,q) getint(l[i]),getint(r[i]),l[i]+=n/2,r[i]+=n/2,v[fiap[l[i]]].pb(i);
	FOR(i,0,n+1) w[i]=INF;
	FOR(i,0,n+1) if (!fiap[i]) fiap[i]=INF;
	FORD(i,ts,1){
		if (i<ts){
			w[tmp[i+1]]=i;
		}
		FOR(j,0,SZ(v[i])-1){
			int id=v[i][j];
			int when=w[bc[l[id]]];
			int ll=fiap[l[id]];
			int rr=min(when,fiap[r[id]+1]-1);
			FOR(k,0,9) ans[id][k]=f[rr][k]-f[ll-1][k];
		}
	}
	FOR(i,1,q){
		FOR(j,0,9) printf("%d ",ans[i][j]);
		puts("");
	}
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)x.size())
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
typedef long long LL;
typedef pair<int,int> pa;
typedef vector<int> vec;
void getint(int &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
const int INF=1e9+10;
char s[500010],TMP[2100010];
vec v[2100000];
int n,q,ts,L[500010],tmp[5000010],R[500010],ans[100010][10],w[500010],bc[500010],l[500010],r[500010],f[2100010][10],fiap[500010],fil[500010],fir[500010];
int walk(int x,int d){
	if (d==1) return R[x];
	else return L[x];
}
void del(int x){
	L[R[x]]=L[x];
	R[L[x]]=R[x];
}
void mov(int S){
	int now=S;
	int d=1;
	tmp[++ts]=S;
	TMP[ts]=s[now];
	fiap[S]=ts;
	bc[now]=now-1;
	while (1) {
		int NOW;
		if (s[now]=='>' || s[now]=='<'){
			d=((s[now]=='>')?1:-1);
			NOW=walk(now,d);
			tmp[++ts]=NOW;
			TMP[ts]=s[NOW];
			if (s[NOW]=='<' || s[NOW]=='>'){
				del(now);
			}
			if (!fiap[NOW]){
				fiap[NOW]=ts;
				bc[NOW]=L[NOW];
			}
			if (NOW>n) return;
			now=NOW;
		}
		else{
			NOW=walk(now,d);
			tmp[++ts]=NOW;
			TMP[ts]=s[NOW];
			--s[now];
			if (s[now]<'0') del(now);
			if (!fiap[NOW]){
				fiap[NOW]=ts;
				bc[NOW]=L[NOW];
			}
			if (NOW>n) return;
			now=NOW;
		}
	}
}
int main(){
	cin>>n>>q;
	FOR(i,1,n) s[i]='>';
	scanf("%s",s+n+1);
	n<<=1;
	FOR(i,0,n) R[i]=i+1,L[i+1]=i;
	mov(n/2+1);
	tmp[0]=n/2;
	FOR(i,1,ts){
		FOR(j,0,9) f[i][j]=f[i-1][j]+(TMP[i]==j+'0');
	}

	FOR(i,1,q) getint(l[i]),getint(r[i]),l[i]+=n/2,r[i]+=n/2,v[fiap[l[i]]].pb(i);
	FOR(i,0,n+1) w[i]=INF;
	FOR(i,0,n+1) if (!fiap[i]) fiap[i]=INF;
	FORD(i,ts,1){
		if (i<ts){
			w[tmp[i+1]]=i;
		}
		FOR(j,0,SZ(v[i])-1){
			int id=v[i][j];
			int when=w[bc[l[id]]];
			int ll=fiap[l[id]];
			int rr=min(when,fiap[r[id]+1]-1);
			FOR(k,0,9) ans[id][k]=f[rr][k]-f[ll-1][k];
		}
	}
	FOR(i,1,q){
		FOR(j,0,9) printf("%d ",ans[i][j]);
		puts("");
	}
	return 0;
}


/*
Author: Dynamic JQ

Problem: Codefeorces 238D - Tape Programming

Time & Date(start): Apr/9/2018 21:53

Verdict: Coding

Tags: Offline + Segment Tree
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 1e9 + 7;

struct block
{
	int dat[10];
	void clear()
	{
		memset(dat, 0, sizeof(dat));
	}
	block()
	{
		clear();
	}
	block(int x)
	{
		clear();
		dat[x] ++;
	}
	block(const block& oth)
	{
		rep(i, 10) dat[i] = oth.dat[i];
	}
	block operator+(const block& oth) const
	{
		block ans;
		rep(i, 10) ans.dat[i] = dat[i] + oth.dat[i];
		return ans;
	}
	block operator-(const block& oth) const
	{
		block ans;
		rep(i, 10) ans.dat[i] = dat[i] - oth.dat[i];
		return ans;
	}
	block count(int l, int r) const
	{
		block ret;
		for(int i = 9 - l; i >= 0; i --) ret.dat[i] = dat[i + l];
		r -= l;
		for(int i = 8; i >= 0; i --) ret.dat[i] += ret.dat[i + 1];
		rep(i, 9 - r) ret.dat[i] -= ret.dat[i + r + 1];
		return ret;
	}
};

struct seg_tree
{
	block dat[262144];
	int bld[262144];
	void init()
	{
		memset(bld, -1, sizeof(bld));
	}
	void pushdown(int v)
	{
		if(bld[v << 1] == -1) {
			dat[v << 1] = dat[v << 1] + dat[v];
			bld[v << 1] = bld[v];
		}
		if(bld[v << 1 | 1] == -1) {
			dat[v << 1 | 1] = dat[v << 1 | 1] + dat[v];
			bld[v << 1 | 1] = bld[v];
		}
		dat[v] = block();
		bld[v] = -1;
	}
	void add(int l, int r, const block& val, int v = 1, int cl = 0, int cr = 131071)
	{
		if(bld[v] != -1) return;
		if(l == cl && r == cr) {
			dat[v] = dat[v] + val;
			return;
		}
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(l <= mid) add(l, min(r, mid), val, v << 1, cl, mid);
		if(r > mid) add(max(l, mid + 1), r, val, v << 1 | 1, mid + 1, cr);
	}
	void blockade(int l, int r, int bi, int v = 1, int cl = 0, int cr = 131071)
	{
		if(bld[v] != -1) return;
		if(l == cl && r == cr) {
			bld[v] = bi;
			return;
		}
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(l <= mid) blockade(l, min(r, mid), bi, v << 1, cl, mid);
		if(r > mid) blockade(max(l, mid + 1), r, bi, v << 1 | 1, mid + 1, cr);
	}
	int q_blockade(int id, int v = 1, int cl = 0, int cr = 131071)
	{
		if(cl == id && cr == id) return bld[v];
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(id <= mid) return q_blockade(id, v << 1, cl, mid);
		else return q_blockade(id, v << 1 | 1, mid + 1, cr);
	}
	block query(int id, int v = 1, int cl = 0, int cr = 131071)
	{
		if(cl == id && cr == id) return dat[v];
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(id <= mid) return query(id, v << 1, cl, mid);
		else return query(id, v << 1 | 1, mid + 1, cr);
	}
}tre;

char ch[100005];
vector<PII> qy[100005];
block ans[100005];
int n, q, sz;
int bid[100005];
bool tol[100005], isz[100005];
vector<int> ts;
int pre[100005], nxr[100005];
block pfx[100005];

void init_blo()
{
	ch[0] = '>';
	for(int i = 0; i <= n; i ++)
	if(ch[i] == '<' || ch[i] == '>') {
		tol[i] = ch[i] == '<';
		int cur = -1;
		for(int j = i + 1; j <= n && ch[j] != '<' && ch[j] != '>'; j ++) cur = max(cur, ch[j] - '0');
		isz[i] = !(cur & 1);
	}
	stack<int> st;
	for(int i = 0; i <= n; i ++) {
		if(tol[i]) {
			ts.push_back(i);
			if(st.empty()) pre[i] = -1;
			else {
				pre[i] = st.top();
				st.pop();
			}
		}
		if(isz[i]) st.push(i);
	}
	nxr[n] = n;
	for(int i = n - 1; i >= 0; i --) nxr[i] = ch[i] == '>' ? i : nxr[i + 1];
	pfx[0] = block();
	rep1(i, n) {
		pfx[i] = pfx[i - 1];
		if(ch[i] != '<' && ch[i] != '>') pfx[i] = pfx[i] + block(ch[i] - '0');
	}
	tre.init();
}

block get_block(int l, int r)
{
	if(l > r) return block();
	if(l == 0) return pfx[r];
	return pfx[r] - pfx[l - 1];
}

int prev_ts(int p)
{
	int pos = upper_bound(ts.begin(), ts.end(), p) - ts.begin();
	if(pos == 0) return -1;
	return ts[pos - 1];
}

void new_block(int i)
{
	tre.blockade(pre[i] + 1, i, i);
	int p = i - 1;
	block cur = get_block(pre[i] + 1, i);
	for(; ; ) {
		p = prev_ts(p);
		if(p <= pre[i]) break;
		cur = cur - get_block(pre[p] + 1, p);
		p = pre[p];
	}
	tre.add(0, i, cur);
}

block query(int l, int r)
{
	int b = tre.q_blockade(l);
	if(b == -1) return tre.query(l).count(1, 10) + get_block(l, r).count(0, 0);
	else return get_block(nxr[l] + 1, b).count(2, 10) + get_block(l, b).count(0, 1);
}

int main()
{
	scanf("%d%d", &n, &q);
	scanf("%s", ch + 1);
	init_blo();
	rep(i, q) {
		int l, r;
		scanf("%d%d", &l, &r);
		qy[r].push_back(MP(l, i));
	}
	for(int i = 0; i <= n; i ++) {
		if(ch[i] == '<') new_block(i);
		rep(j, qy[i].size()) ans[qy[i][j].second] = query(qy[i][j].first, i);
	}
	rep(i, q) {
		rep(j, 10) printf("%d ", ans[i].dat[j]);
		printf("\n");
	}
	return 0;
}


/*
Author: Dynamic JQ

Problem: Codefeorces 238D - Tape Programming

Time & Date(start): Apr/9/2018 21:53

Verdict: Coding

Tags: Offline + Segment Tree
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 1e9 + 7;

struct block
{
	int dat[10];
	void clear()
	{
		memset(dat, 0, sizeof(dat));
	}
	block()
	{
		clear();
	}
	block(int x)
	{
		clear();
		dat[x] ++;
	}
	block(const block& oth)
	{
		rep(i, 10) dat[i] = oth.dat[i];
	}
	block operator+(const block& oth) const
	{
		block ans;
		rep(i, 10) ans.dat[i] = dat[i] + oth.dat[i];
		return ans;
	}
	block operator-(const block& oth) const
	{
		block ans;
		rep(i, 10) ans.dat[i] = dat[i] - oth.dat[i];
		return ans;
	}
	block count(int l, int r) const
	{
		block ret;
		for(int i = 9 - l; i >= 0; i --) ret.dat[i] = dat[i + l];
		r -= l;
		for(int i = 8; i >= 0; i --) ret.dat[i] += ret.dat[i + 1];
		rep(i, 9 - r) ret.dat[i] -= ret.dat[i + r + 1];
		return ret;
	}
};

struct seg_tree
{
	block dat[262144];
	int bld[262144];
	void init()
	{
		memset(bld, -1, sizeof(bld));
	}
	void pushdown(int v)
	{
		if(bld[v << 1] == -1) {
			dat[v << 1] = dat[v << 1] + dat[v];
			bld[v << 1] = bld[v];
		}
		if(bld[v << 1 | 1] == -1) {
			dat[v << 1 | 1] = dat[v << 1 | 1] + dat[v];
			bld[v << 1 | 1] = bld[v];
		}
		dat[v] = block();
		bld[v] = -1;
	}
	void add(int l, int r, const block& val, int v = 1, int cl = 0, int cr = 131071)
	{
		if(bld[v] != -1) return;
		if(l == cl && r == cr) {
			dat[v] = dat[v] + val;
			return;
		}
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(l <= mid) add(l, min(r, mid), val, v << 1, cl, mid);
		if(r > mid) add(max(l, mid + 1), r, val, v << 1 | 1, mid + 1, cr);
	}
	void blockade(int l, int r, int bi, int v = 1, int cl = 0, int cr = 131071)
	{
		if(bld[v] != -1) return;
		if(l == cl && r == cr) {
			bld[v] = bi;
			return;
		}
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(l <= mid) blockade(l, min(r, mid), bi, v << 1, cl, mid);
		if(r > mid) blockade(max(l, mid + 1), r, bi, v << 1 | 1, mid + 1, cr);
	}
	int q_blockade(int id, int v = 1, int cl = 0, int cr = 131071)
	{
		if(cl == id && cr == id) return bld[v];
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(id <= mid) return q_blockade(id, v << 1, cl, mid);
		else return q_blockade(id, v << 1 | 1, mid + 1, cr);
	}
	block query(int id, int v = 1, int cl = 0, int cr = 131071)
	{
		if(cl == id && cr == id) return dat[v];
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(id <= mid) return query(id, v << 1, cl, mid);
		else return query(id, v << 1 | 1, mid + 1, cr);
	}
}tre;

char ch[100005];
vector<PII> qy[100005];
block ans[100005];
int n, q, sz;
int bid[100005];
bool tol[100005], isz[100005];
vector<int> ts;
int pre[100005], nxr[100005];
block pfx[100005];

void init_blo()
{
	ch[0] = '>';
	for(int i = 0; i <= n; i ++)
	if(ch[i] == '<' || ch[i] == '>') {
		tol[i] = ch[i] == '<';
		int cur = -1;
		for(int j = i + 1; j <= n && ch[j] != '<' && ch[j] != '>'; j ++) cur = max(cur, ch[j] - '0');
		isz[i] = !(cur & 1);
	}
	stack<int> st;
	for(int i = 0; i <= n; i ++) {
		if(tol[i]) {
			ts.push_back(i);
			if(st.empty()) pre[i] = -1;
			else {
				pre[i] = st.top();
				st.pop();
			}
		}
		if(isz[i]) st.push(i);
	}
	nxr[n] = n;
	for(int i = n - 1; i >= 0; i --) nxr[i] = ch[i] == '>' ? i : nxr[i + 1];
	pfx[0] = block();
	rep1(i, n) {
		pfx[i] = pfx[i - 1];
		if(ch[i] != '<' && ch[i] != '>') pfx[i] = pfx[i] + block(ch[i] - '0');
	}
	tre.init();
}

block get_block(int l, int r)
{
	if(l > r) return block();
	if(l == 0) return pfx[r];
	return pfx[r] - pfx[l - 1];
}

int prev_ts(int p)
{
	int pos = lower_bound(ts.begin(), ts.end(), p) - ts.begin();
	if(pos == 0) return -1;
	return ts[pos - 1];
}

void new_block(int i)
{
	tre.blockade(pre[i] + 1, i, i);
	int p = i;
	block cur = get_block(pre[i] + 1, i);
	for(; ; ) {
		p = prev_ts(p);
		if(p <= pre[i]) break;
		cur = cur - get_block(pre[p] + 1, p);
		p = pre[p];
	}
	tre.add(0, i, cur);
}

block query(int l, int r)
{
	int b = tre.q_blockade(l);
	if(b == -1) return tre.query(l).count(1, 10) + get_block(l, r).count(0, 0);
	else return get_block(nxr[l] + 1, b).count(2, 10) + get_block(l, b).count(0, 1);
}

int main()
{
	scanf("%d%d", &n, &q);
	scanf("%s", ch + 1);
	init_blo();
	rep(i, q) {
		int l, r;
		scanf("%d%d", &l, &r);
		qy[r].push_back(MP(l, i));
	}
	for(int i = 0; i <= n; i ++) {
		if(ch[i] == '<') new_block(i);
		rep(j, qy[i].size()) ans[qy[i][j].second] = query(qy[i][j].first, i);
	}
	rep(i, q) {
		rep(j, 10) printf("%d ", ans[i].dat[j]);
		printf("\n");
	}
	return 0;
}


/*
Author: Dynamic JQ

Problem: Codefeorces 238D - Tape Programming

Time & Date(start): Apr/9/2018 21:53

Verdict: Coding

Tags: Offline + Segment Tree
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 1e9 + 7;

struct block
{
	int dat[10];
	void clear()
	{
		memset(dat, 0, sizeof(dat));
	}
	block()
	{
		clear();
	}
	block(int x)
	{
		clear();
		dat[x] ++;
	}
	block(const block& oth)
	{
		rep(i, 10) dat[i] = oth.dat[i];
	}
	block operator+(const block& oth) const
	{
		block ans;
		rep(i, 10) ans.dat[i] = dat[i] + oth.dat[i];
		return ans;
	}
	block operator-(const block& oth) const
	{
		block ans;
		rep(i, 10) ans.dat[i] = dat[i] - oth.dat[i];
		return ans;
	}
	block count(int l, int r) const
	{
		block ret;
		for(int i = 9 - l; i >= 0; i --) ret.dat[i] = dat[i + l];
		r -= l;
		for(int i = 8; i >= 0; i --) ret.dat[i] += ret.dat[i + 1];
		rep(i, 9 - r) ret.dat[i] -= ret.dat[i + r + 1];
		return ret;
	}
};

struct seg_tree
{
	block dat[262144];
	int bld[262144];
	void init()
	{
		memset(bld, -1, sizeof(bld));
	}
	void pushdown(int v)
	{
		if(bld[v << 1] == -1) {
			dat[v << 1] = dat[v << 1] + dat[v];
			bld[v << 1] = bld[v];
		}
		if(bld[v << 1 | 1] == -1) {
			dat[v << 1 | 1] = dat[v << 1 | 1] + dat[v];
			bld[v << 1 | 1] = bld[v];
		}
		dat[v] = block();
		bld[v] = -1;
	}
	void add(int l, int r, const block& val, int v = 1, int cl = 0, int cr = 131071)
	{
		if(bld[v] != -1) return;
		if(l == cl && r == cr) {
			dat[v] = dat[v] + val;
			return;
		}
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(l <= mid) add(l, min(r, mid), val, v << 1, cl, mid);
		if(r > mid) add(max(l, mid + 1), r, val, v << 1 | 1, mid + 1, cr);
	}
	void blockade(int l, int r, int bi, int v = 1, int cl = 0, int cr = 131071)
	{
		if(bld[v] != -1) return;
		if(l == cl && r == cr) {
			bld[v] = bi;
			return;
		}
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(l <= mid) blockade(l, min(r, mid), bi, v << 1, cl, mid);
		if(r > mid) blockade(max(l, mid + 1), r, bi, v << 1 | 1, mid + 1, cr);
	}
	int q_blockade(int id, int v = 1, int cl = 0, int cr = 131071)
	{
		if(cl == id && cr == id) return bld[v];
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(id <= mid) return q_blockade(id, v << 1, cl, mid);
		else return q_blockade(id, v << 1 | 1, mid + 1, cr);
	}
	block query(int id, int v = 1, int cl = 0, int cr = 131071)
	{
		if(cl == id && cr == id) return dat[v];
		pushdown(v);
		int mid = (cl + cr) >> 1;
		if(id <= mid) return query(id, v << 1, cl, mid);
		else return query(id, v << 1 | 1, mid + 1, cr);
	}
}tre;

char ch[100005];
vector<PII> qy[100005];
block ans[100005];
int n, q, sz;
int bid[100005];
bool tol[100005], isz[100005];
vector<int> ts;
int pre[100005];
block pfx[100005];

void init_blo()
{
	ch[0] = '>';
	for(int i = 0; i <= n; i ++)
	if(ch[i] == '<' || ch[i] == '>') {
		tol[i] = ch[i] == '<';
		int cur = -1;
		for(int j = i + 1; j <= n && ch[j] != '<' && ch[j] != '>'; j ++) cur = max(cur, ch[j] - '0');
		isz[i] = !(cur & 1);
	}
	stack<int> st;
	for(int i = 0; i <= n; i ++) {
		if(tol[i]) {
			ts.push_back(i);
			if(st.empty()) pre[i] = -1;
			else {
				pre[i] = st.top();
				st.pop();
			}
		}
		if(isz[i]) st.push(i);
	}
	pfx[0] = block();
	rep1(i, n) {
		pfx[i] = pfx[i - 1];
		if(ch[i] != '<' && ch[i] != '>') pfx[i] = pfx[i] + block(ch[i] - '0');
	}
	tre.init();
}

block get_block(int l, int r)
{
	if(l == 0) return pfx[r];
	return pfx[r] - pfx[l - 1];
}

int prev_ts(int p)
{
	int pos = lower_bound(ts.begin(), ts.end(), p) - ts.begin();
	if(pos == 0) return -1;
	return ts[pos - 1];
}

void new_block(int i)
{
	tre.blockade(pre[i] + 1, i, i);
	int p = i;
	block cur = get_block(pre[i] + 1, i);
	for(; ; ) {
		p = prev_ts(p);
		if(p <= pre[i]) break;
		cur = cur - get_block(pre[p] + 1, p);
		p = pre[p];
	}
	tre.add(0, i, cur);
}

block query(int l, int r)
{
	int b = tre.q_blockade(l);
	block w = tre.query(l);
	if(b == -1) return w.count(1, 10) + get_block(l, r).count(0, 0);
	else return w.count(2, 10) + get_block(l, b).count(0, 1);
}

int main()
{
	scanf("%d%d", &n, &q);
	scanf("%s", ch + 1);
	init_blo();
	rep(i, q) {
		int l, r;
		scanf("%d%d", &l, &r);
		qy[r].push_back(MP(l, i));
	}
	for(int i = 0; i <= n; i ++) {
		if(ch[i] == '<') new_block(i);
		rep(j, qy[i].size()) ans[qy[i][j].second] = query(qy[i][j].first, i);
	}
	rep(i, q) {
		rep(j, 10) printf("%d ", ans[i].dat[j]);
		printf("\n");
	}
	return 0;
}


//lxrtxdy!
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

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

const int INF = 1e9;
const double EPS = 1e-9;
const double PI = acos(-1.);
const int MX = 2e6;
int cnt[10][MX];
int pos = 1;

char s[100500];
bool used[100500];
int fst[100500];
int lf[100500];
int rg[100500];

int ip;
int nxtr[100500], nxtl[100500];
void mrigh()
{
	rg[ip] = min(rg[ip], pos);
	while(s[nxtr[ip]] == ' ')
	{
		rg[nxtr[ip]] = min(rg[nxtr[ip]], pos);
		nxtr[ip] = nxtr[nxtr[ip]];
	}
	ip = nxtr[ip];
}
void mleft()
{
	lf[ip] = min(lf[ip], pos);
	while(s[nxtl[ip]] == ' ')
	{
		lf[nxtl[ip]] = min(lf[nxtl[ip]], pos);
		nxtl[ip] = nxtl[nxtl[ip]];
	}
	ip = nxtl[ip];
}

void build(int st)
{
	ip = st;
	int dir = 1;
	while (true)
	{
		if (ip < st || s[ip] == 0)
			return;
		used[ip] = true;
		fst[ip] = min(fst[ip], pos);
		int cur = ip;
		if (s[ip] == '>')
		{
			mrigh();
			if (s[ip] == '>' || s[ip] == '<')
				s[cur] = ' ';
			dir = 1;
			continue;
		}
		if (s[ip] == '<')
		{
			mleft();
			if (s[ip] == '>' || s[ip] == '<')
				s[cur] = ' ';
			dir = -1;
			continue;
		}
		cnt[s[ip] - '0'][pos] = 1;
		++pos;
		if (s[ip] == '0') s[ip] = ' ';
		else
			--s[ip];
		if (dir > 0)
			mrigh();
		else
			mleft();
	}
}

int main()
{
#ifdef _DEBUG
	freopen("Dtest.txt", "r", stdin);
#endif
	int n, q;
	scanf("%d%d%s", &n, &q, &s);
	int len = strlen(s);
	for (int i = 0; i <= len; ++i)
	{
		nxtl[i] = i - 1;
		nxtr[i] = i + 1;
		fst[i] = INF;
		lf[i] = INF;
		rg[i] = INF;
	}
	for (int i = 0; i < len; ++i)
	{
		if (!used[i])
			build(i);
	}
	for (int j = 0; j < 10; ++j)
	for (int i = 1; i < pos; ++i)
	{
		cnt[j][i] += cnt[j][i - 1];
	}
	for (int i = 0; i < q; ++i)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		--l;
		--r;
		int frm = fst[l] - 1;
		int to = min(lf[l], rg[r]) - 1;
		to = min(to, pos - 1);
		for (int j = 0; j < 10; ++j)
		{
			printf("%d ", cnt[j][to] - cnt[j][frm]);
		}
		puts("");
	}
	return 0;
}
//hellobig_tq
//orzlxr!


#include <cstdio>
#include <cctype>
#include <algorithm>

typedef long long int int64;

struct IO_Tp
{
	const static int _I_Buffer_Size = 2 << 20;
	char _I_Buffer[_I_Buffer_Size], *_I_pos = _I_Buffer;

	const static int _O_Buffer_Size = 5 << 20;
	char _O_Buffer[_O_Buffer_Size], *_O_pos = _O_Buffer;

	IO_Tp()
	{
		fread(_I_Buffer, 1, _I_Buffer_Size, stdin);
	}

	~IO_Tp()
	{
		fwrite(_O_Buffer, 1, _O_pos - _O_Buffer, stdout);
	}

	IO_Tp &operator>>(int &res)
	{
		while (!isdigit(*_I_pos))
			++_I_pos;
		res = *_I_pos++ & 15;
		while (isdigit(*_I_pos))
			(res *= 10) += *_I_pos++ & 15;
		return *this;
	}

	IO_Tp &operator>>(char *s)
	{
		while (isspace(*_I_pos))
			++_I_pos;
		do
			*s++ = *_I_pos++;
		while (!isspace(*_I_pos));
		*s = '\0';
		return *this;
	}

	IO_Tp &operator<<(int n)
	{
		static char _buf[10];
		char* _pos(_buf);
		do
			*_pos++ = '0' + n % 10;
		while (n /= 10);
		while (_pos != _buf)
			*_O_pos++ = *--_pos;
		return *this;
	}

	IO_Tp &operator<<(char ch)
	{
		*_O_pos++ = ch;
		return *this;
	}
} IO;

const int Max_N = 100005, Mod = 998244353;

int N, Q;
char s[Max_N];
int prev[Max_N], succ[Max_N];
int cnt[10];
bool del[Max_N], f;
int clock = 1, res[Max_N * 2][10], vis[Max_N], lea[Max_N];

void record()
{
	++clock;
	for (int c = 0; c != 10; ++c)
		res[clock][c] = cnt[c];
}

int main(int argc, char **argv)
{
	IO >> N >> Q;
	IO >> (s + 1);
	for (int i = 0; i <= N; ++i)
		succ[i] = i + 1, prev[i + 1] = i, lea[i] = Max_N * 2;

	for (int i = 1, last = 1, d = true, r = 0; i != N + 1; )
	{
		if (!vis[i])
		{
			if (f)
				record(), f = false;
			vis[i] = clock;
			r = i;
		}

		if (!del[i])
		{
			if (isdigit(s[i]))
			{
				if (s[i] == '0')
					del[i] = true;
				++cnt[s[i]-- & 15];
				f = true;
			}
			else
			{
				if (i != last && !isdigit(s[last]))
					del[last] = true;
				d = s[i] == '>';
			}
			last = i;
		}

		if (d)
			i = succ[i];
		else
		{
			if (lea[i] == Max_N * 2)
			{
				if (f)
					record(), f = false;
				lea[i] = clock;
			}
			if (del[i])
				succ[prev[i]] = succ[i], prev[succ[i]] = prev[i];
			i = prev[i];
		}
		if (i == 0)
			prev[r + 1] = 0, succ[0] = r + 1, i = r + 1, d = true;
	}
	if (f)
		record(), f = false;
	vis[N + 1] = clock;

	while (Q--)
	{
		int l, r;
		IO >> l >> r;
		int t = std::min(vis[r + 1], lea[l]);
		for (int c = 0; c != 10; ++c)
			IO << (res[t][c] - res[vis[l]][c]) <<  " \n"[c + 1 == 10];
	}

	return 0;
}


#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

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

const int INF = 1e9;
const double EPS = 1e-9;
const double PI = acos(-1.);
const int MX = 2e6;
int cnt[10][MX];
int pos = 1;

char s[100500];
bool used[100500];
int fst[100500];
int lf[100500];
int rg[100500];

int ip;
int nxtr[100500], nxtl[100500];
void mrigh()
{
	rg[ip] = min(rg[ip], pos);
	while(s[nxtr[ip]] == ' ')
	{
		rg[nxtr[ip]] = min(rg[nxtr[ip]], pos);
		nxtr[ip] = nxtr[nxtr[ip]];
	}
	ip = nxtr[ip];
}
void mleft()
{
	lf[ip] = min(lf[ip], pos);
	while(s[nxtl[ip]] == ' ')
	{
		lf[nxtl[ip]] = min(lf[nxtl[ip]], pos);
		nxtl[ip] = nxtl[nxtl[ip]];
	}
	ip = nxtl[ip];
}

void build(int st)
{
	ip = st;
	int dir = 1;
	while (true)
	{
		if (ip < st || s[ip] == 0)
			return;
		used[ip] = true;
		fst[ip] = min(fst[ip], pos);
		int cur = ip;
		if (s[ip] == '>')
		{
			mrigh();
			if (s[ip] == '>' || s[ip] == '<')
				s[cur] = ' ';
			dir = 1;
			continue;
		}
		if (s[ip] == '<')
		{
			mleft();
			if (s[ip] == '>' || s[ip] == '<')
				s[cur] = ' ';
			dir = -1;
			continue;
		}
		cnt[s[ip] - '0'][pos] = 1;
		++pos;
		if (s[ip] == '0') s[ip] = ' ';
		else
			--s[ip];
		if (dir > 0)
			mrigh();
		else
			mleft();
	}
}

int main()
{
#ifdef _DEBUG
	freopen("Dtest.txt", "r", stdin);
#endif
	int n, q;
	scanf("%d%d%s", &n, &q, &s);
	int len = strlen(s);
	for (int i = 0; i <= len; ++i)
	{
		nxtl[i] = i - 1;
		nxtr[i] = i + 1;
		fst[i] = INF;
		lf[i] = INF;
		rg[i] = INF;
	}
	for (int i = 0; i < len; ++i)
	{
		if (!used[i])
			build(i);
	}
	for (int j = 0; j < 10; ++j)
	for (int i = 1; i < pos; ++i)
	{
		cnt[j][i] += cnt[j][i - 1];
	}
	for (int i = 0; i < q; ++i)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		--l;
		--r;
		int frm = fst[l] - 1;
		int to = min(lf[l], rg[r]) - 1;
		to = min(to, pos - 1);
		for (int j = 0; j < 10; ++j)
		{
			printf("%d ", cnt[j][to] - cnt[j][frm]);
		}
		puts("");
	}
	return 0;
}
//hellobig_tq


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}T[maxn<<2],cnt;
int nx[maxn][2];
void erase(int x) {
	nx[nx[x][0]][1]=nx[x][1];
	nx[nx[x][1]][0]=nx[x][0];
}
vector<int> pass[maxn];
int t;
int fr[maxn];
bool solve() {
	for(int pos=nx[0][1],k=1; ;pos=nx[pos][k]) {
		T[++t]=cnt;
		if (pass[pos].empty()) fr[pos]=nx[pos][0];
		pass[pos].push_back(t);
		if (!pos) return 0;
		if (pos>n) return 1;
		if (s[pos]=='<'||s[pos]=='>') {
			k=s[pos]=='<'?0:1;
			if (!nx[pos][k]||s[nx[pos][k]]=='<'||s[nx[pos][k]]=='>')
				erase(pos);
		}
		else {
			cnt.v[s[pos]-'0']++,s[pos]--;
			if (s[pos]<'0') erase(pos);
		}
	}
}
int find(int x,int t) {
	vector<int>::iterator it=lower_bound(pass[x].begin(),pass[x].end(),t);
	if (it==pass[x].end()) return 1e9;
	else return *it;
}
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,0,n)
		nx[i][1]=i+1,nx[i+1][0]=i;
	int total=0;
	while(!solve()) {
		// for(int pos=nx[0][1];pos<n;pos=nx[pos][1])
		// 	putchar(s[pos]);
		// putchar('\n');
		// if (total>10) return 0;
		// total++;
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		int T1=pass[l][0];
		int T2=min(find(fr[l],T1),find(r+1,T1));
		node ans=T[T2]-T[T1];
		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int nxleft[maxn],nxright[maxn];
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (top&&s[i]=='<') solve(sta[top],i),top--;
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	nxleft[n+1]=nxright[n+1]=n+1;
	drp(i,n,1) {
		if (s[i]=='<') nxleft[i]=i;
		else nxleft[i]=nxleft[i+1];
		if (s[i]=='>') nxright[i]=i;
		else nxright[i]=nxright[i+1];
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		if (nxleft[l]<nxright[l]&&nxleft[l]<=r){
			r=nxleft[l];
			node x=sum[r]-sum[l-1],ans;
			rep(j,0,8) {
				ans.v[j]=x.v[j]+x.v[j+1];
			}
			ans.v[9]=x.v[9];
			rep(j,0,9) wrt(ans.v[j],' ');putchar('\n');
			continue;
		}
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		if (H[pos1].second>r) pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);

		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (s[i]=='<') solve(sta[top],i);
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);
		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int nxleft[maxn],nxright[maxn];
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (top&&s[i]=='<') solve(sta[top],i),top--;
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	nxleft[n+1]=nxright[n+1]=n+1;
	drp(i,n,1) {
		if (s[i]=='<') nxleft[i]=i;
		else nxleft[i]=nxleft[i+1];
		if (s[i]=='>') nxright[i]=i;
		else nxright[i]=nxright[i+1];
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		if (nxleft[l]<nxright[l]&&nxleft[l]<=r){
			r=nxleft[l];
			node x=sum[r]-sum[l-1],ans;
			rep(j,0,8) {
				ans.v[j]=x.v[j]+x.v[j+1];
			}
			ans.v[9]=x.v[9];
			rep(j,0,9) wrt(ans.v[j],' ');putchar('\n');
			continue;
		}
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans;
		if (H[pos2].second>r)
			ans=sum[r]-sum[l-1];
		else
			ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);

		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int nxleft[maxn],nxright[maxn];
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (s[i]=='<') solve(sta[top],i),top--;
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	nxleft[n+1]=nxright[n+1]=n+1;
	drp(i,n,1) {
		if (s[i]=='<') nxleft[i]=i;
		else nxleft[i]=nxleft[i+1];
		if (s[i]=='>') nxright[i]=i;
		else nxright[i]=nxright[i+1];
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		if (nxleft[l]<nxright[l]){
			r=nxleft[l];
			node x=sum[r]-sum[l-1],ans;
			rep(j,0,8) {
				ans.v[j]=x.v[j]+x.v[j+1];
			}
			ans.v[9]=x.v[9];
			rep(j,0,9) wrt(ans.v[j],' ');putchar('\n');
			continue;
		}
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);

		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int nxleft[maxn],nxright[maxn];
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (top&&s[i]=='<') solve(sta[top],i),top--;
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	nxleft[n+1]=nxright[n+1]=n+1;
	drp(i,n,1) {
		if (s[i]=='<') nxleft[i]=i;
		else nxleft[i]=nxleft[i+1];
		if (s[i]=='>') nxright[i]=i;
		else nxright[i]=nxright[i+1];
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		if (nxleft[l]<nxright[l]&&nxleft[l]<=r){
			r=nxleft[l];
			node x=sum[r]-sum[l-1],ans;
			rep(j,0,8) {
				ans.v[j]=x.v[j]+x.v[j+1];
			}
			ans.v[9]=x.v[9];
			rep(j,0,9) wrt(ans.v[j],' ');putchar('\n');
			continue;
		}
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);

		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int nxleft[maxn],nxright[maxn];
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (s[i]=='<') solve(sta[top],i),top--;
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	nxleft[n+1]=nxright[n+1]=n+1;
	drp(i,n,1) {
		if (s[i]=='<') nxleft[i]=i;
		else nxleft[i]=nxleft[i+1];
		if (s[i]=='>') nxright[i]=i;
		else nxright[i]=nxright[i+1];
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		if (nxleft[l]<nxright[l]&&nxleft[l]<r){
			r=nxleft[l];
			node x=sum[r]-sum[l-1],ans;
			rep(j,0,8) {
				ans.v[j]=x.v[j]+x.v[j+1];
			}
			ans.v[9]=x.v[9];
			rep(j,0,9) wrt(ans.v[j],' ');putchar('\n');
			continue;
		}
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);

		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 100005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}S[maxn],SS[maxn],sum[maxn];
void solve(int l,int r) {
	H[++tot]=make_pair(l,r);
	S[tot]=S[tot-1],SS[tot]=SS[tot-1];
	rep(i,l,r) if (s[i]>='0'&&s[i]<='9') {
		SS[tot].v[s[i]-'0']++;
		rep(j,0,s[i]-'0')
			S[tot].v[j]++;
	}
}
int nxleft[maxn],nxright[maxn];
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,1,n) {
		if (s[i]=='>') sta[++top]=i;
		if (s[i]=='<') solve(sta[top],i),top--;
		sum[i]=sum[i-1];
		if (s[i]>='0'&&s[i]<='9') sum[i].v[s[i]-'0']++;
	}
	nxleft[n+1]=nxright[n+1]=n+1;
	drp(i,n,1) {
		if (s[i]=='<') nxleft[i]=i;
		else nxleft[i]=nxleft[i+1];
		if (s[i]=='>') nxright[i]=i;
		else nxright[i]=nxright[i+1];
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		if (nxleft[l]<nxright[l]&&nxleft[l]<=r){
			r=nxleft[l];
			node x=sum[r]-sum[l-1],ans;
			rep(j,0,8) {
				ans.v[j]=x.v[j]+x.v[j+1];
			}
			ans.v[9]=x.v[9];
			rep(j,0,9) wrt(ans.v[j],' ');putchar('\n');
			continue;
		}
		int pos1=upper_bound(H+1,H+1+tot,make_pair(r,r))-H;
		pos1--;
		int pos2=lower_bound(H+1,H+1+tot,make_pair(l,l))-H;
		node ans=sum[r]-sum[l-1]+(S[pos1]-S[pos2-1])-(SS[pos1]-SS[pos2-1]);

		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


/*
	Author: zxy_hhhh
	date: 2019/09/03
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<iostream>
#define rep(x,a,b) for (int x=int(a);x<=(int)(b);x++)
#define drp(x,a,b) for (int x=int(a);x>=(int)(b);x--)
#define cross(x,a) for (int x=hd[a];x;x=nx[x])
#define ll long long
using namespace std;
inline ll rd()
{
	ll _x=0;int _ch=getchar(),_f=1;
	for(;!isdigit(_ch)&&(_ch!='-')&&(_ch!=EOF);_ch=getchar());
	if (_ch=='-'){_f=0;_ch=getchar();}
	for(;isdigit(_ch);_ch=getchar()) _x=_x*10+_ch-'0';
	return _f?_x:-_x;
}
void write(ll _x){if (_x>=10) write(_x/10),putchar(_x%10+'0'); else putchar(_x+'0'); }
inline void wrt(ll _x,char _p){if (_x<0) putchar('-'),_x=-_x; write(_x); if (_p) putchar(_p);}
#define maxn 1000005
char s[maxn];
int n,Q;
int sta[maxn],top,tot;
pair<int,int> H[maxn];
struct node {
	int v[10];
	node operator+ (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]+B.v[i];
		return ans;
	}
	node operator- (const node &B) const {
		node ans;
		rep(i,0,9) ans.v[i]=v[i]-B.v[i];
		return ans;
	}
}T[maxn],cnt;
int nx[maxn][2];
void erase(int x) {
	nx[nx[x][0]][1]=nx[x][1];
	nx[nx[x][1]][0]=nx[x][0];
}
vector<int> pass[maxn];
int t;
int fr[maxn];
bool solve() {
	for(int pos=nx[0][1],k=1; ;pos=nx[pos][k]) {
		T[++t]=cnt;
		if (pass[pos].empty()) fr[pos]=nx[pos][0];
		pass[pos].push_back(t);
		if (!pos) return 0;
		if (pos>n) return 1;
		if (s[pos]=='<'||s[pos]=='>') {
			k=s[pos]=='<'?0:1;
			if (!nx[pos][k]||s[nx[pos][k]]=='<'||s[nx[pos][k]]=='>')
				erase(pos);
		}
		else {
			cnt.v[s[pos]-'0']++,s[pos]--;
			if (s[pos]<'0') erase(pos);
		}
	}
}
int find(int x,int t) {
	vector<int>::iterator it=lower_bound(pass[x].begin(),pass[x].end(),t);
	if (it==pass[x].end()) return 1e9;
	else return *it;
}
int main() {
	n=rd();Q=rd();
	scanf("%s",s+1);
	rep(i,0,n)
		nx[i][1]=i+1,nx[i+1][0]=i;
	int total=0;
	while(!solve()) {
		// for(int pos=nx[0][1];pos<n;pos=nx[pos][1])
		// 	putchar(s[pos]);
		// putchar('\n');
		// if (total>10) return 0;
		// total++;
	}
	rep(i,1,Q) {
		int l=rd(),r=rd();
		int T1=pass[l][0];
		int T2=min(find(fr[l],T1),find(r+1,T1));
		node ans=T[T2]-T[T1];
		rep(j,0,9) wrt(ans.v[j],' ');
		putchar('\n');
	}
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 100005;
const int inf = 1<<30;

char str[maxn];
int s[10],f[maxn][10];
int n,q,idx,l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
struct st {
	int minw[maxn*4],val[maxn*4];
	void init() {
		for (int i=1;i<=4*(n+1);i++) minw[i]=inf;
	}
	void modify(int root,int L,int R,int l,int r,int w)
	{
		if (L>=l&&R<=r) {
			minw[root]=min(minw[root],w);return ;
		}
		int mid=L+R>>1;
		if (l<=mid) modify(root<<1,L,mid,l,r,w);
		if (r>mid) modify(root<<1|1,mid+1,R,l,r,w);
	}
	void dfs(int root,int L,int R,int w)
	{
		int mid=L+R>>1;w=min(w,minw[root]);
		if (L>=R) {
			val[L]=w;return ;
		}
		dfs(root<<1,L,mid,w);dfs(root<<1|1,mid+1,R,w);
	}
}ft,gt;
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	ft.init();gt.init();
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		memcpy(f[idx],s,sizeof s);
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0) gt.modify(1,0,n+1,cur+1,las,idx);
		if (dir==1) ft.modify(1,0,n+1,las+1,cur,idx);
	}

	ft.dfs(1,0,n+1,inf);gt.dfs(1,0,n+1,inf);
	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		int id=min(gt.val[_l],ft.val[_r+1]);
		for (int j=0;j<10;j++)
			printf("%d ",f[id][j]-f[ft.val[_l]][j]);
		puts("");
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 100005;
const int inf = 1<<30;

char str[maxn];
int s[10],f[maxn][10];
int n,q,idx,l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
struct st {
	int minw[maxn*4],val[maxn*4];
	void init() {
		for (int i=1;i<=4*(n+2);i++) minw[i]=inf;
	}
	void modify(int root,int L,int R,int l,int r,int w)
	{
		if (L>=l&&R<=r) {
			minw[root]=min(minw[root],w);return ;
		}
		int mid=L+R>>1;
		if (l<=mid) modify(root<<1,L,mid,l,r,w);
		if (r>mid) modify(root<<1|1,mid+1,R,l,r,w);
	}
	void dfs(int root,int L,int R,int w)
	{
		int mid=L+R>>1;w=min(w,minw[root]);
		if (L>=R) {
			val[L]=w;return ;
		}
		dfs(root<<1,L,mid,w);dfs(root<<1|1,mid+1,R,w);
	}
}ft,gt;
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	ft.init();gt.init();
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		memcpy(f[idx],s,sizeof s);
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0) gt.modify(1,0,n+1,cur+1,las,idx);
		if (dir==1) ft.modify(1,0,n+1,las+1,cur,idx);
	}

	ft.dfs(1,0,n+1,inf);gt.dfs(1,0,n+1,inf);
	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		int id=min(gt.val[_l],ft.val[_r+1]);
		for (int j=0;j<10;j++)
			printf("%d ",f[id][j]-f[ft.val[_l]][j]);
		puts("");
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 1000005;
const int inf = 1<<30;

char str[maxn];
int s[10],f[maxn][10];
int n,q,idx,l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
struct st {
	int minw[maxn*4],val[maxn*4];
	void init() {
		for (int i=1;i<=4*(n+2);i++) minw[i]=inf;
	}
	void modify(int root,int L,int R,int l,int r,int w)
	{
		if (L>=l&&R<=r) {
			minw[root]=min(minw[root],w);return ;
		}
		int mid=L+R>>1;
		if (l<=mid) modify(root<<1,L,mid,l,r,w);
		if (r>mid) modify(root<<1|1,mid+1,R,l,r,w);
	}
	void dfs(int root,int L,int R,int w)
	{
		int mid=L+R>>1;w=min(w,minw[root]);
		if (L>=R) {
			val[L]=w;return ;
		}
		dfs(root<<1,L,mid,w);dfs(root<<1|1,mid+1,R,w);
	}
}ft,gt;
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	ft.init();gt.init();
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		memcpy(f[idx],s,sizeof s);
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0) gt.modify(1,0,n+1,cur+1,las,idx);
		if (dir==1) ft.modify(1,0,n+1,las+1,cur,idx);
	}

	ft.dfs(1,0,n+1,inf);gt.dfs(1,0,n+1,inf);
	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		int id=min(gt.val[_l],ft.val[_r+1]);
		for (int j=0;j<10;j++)
			printf("%d ",f[id][j]-f[ft.val[_l]][j]);
		puts("");
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 100005;

int s[10];
int n,q,ft[maxn],gt[maxn],idx;
char str[maxn];
int f[maxn][10];
int g[maxn][10];
int l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0) {
			for (int t=cur+1;t<=las&&!gt[t];t++) {
				memcpy(g[t],s,sizeof s);gt[t]=idx;
			}
		}
		if (dir==1) {
			for (int t=cur;t>=las+1&&!ft[t];t--) {
				memcpy(f[t],s,sizeof s);ft[t]=idx;
			}
		}
	}

	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		if (gt[_l]<ft[_r+1]&&gt[_l]) {
			for (int j=0;j<10;j++)
				printf("%d ",g[_l][j]-f[_l][j]);
			puts("");
		}
		else {
			for (int j=0;j<10;j++)
				printf("%d ",f[_r+1][j]-f[_l][j]);
			puts("");
		}
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 100005;
const int inf = 1<<30;

char str[maxn];
int s[10],f[maxn][10];
int n,q,idx,l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
struct st {
	int minw[maxn*4],val[maxn];
	void init() {
		for (int i=1;i<=4*n;i++) minw[i]=inf;
	}
	void modify(int root,int L,int R,int l,int r,int w)
	{
		if (L>=l&&R<=r) {
			minw[root]=min(minw[root],w);return ;
		}
		int mid=L+R>>1;
		if (l<=mid) modify(root<<1,L,mid,l,r,w);
		if (r>mid) modify(root<<1|1,mid+1,R,l,r,w);
	}
	void dfs(int root,int L,int R)
	{
		if (L>=R) {
			val[L]=minw[root];return ;
		}
		int mid=L+R>>1;
		minw[root<<1]=min(minw[root<<1],minw[root]);
		minw[root<<1|1]=min(minw[root<<1|1],minw[root]);
		dfs(root<<1,L,mid);dfs(root<<1|1,mid+1,R);
	}
}ft,gt;
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	ft.init();gt.init();
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		memcpy(f[idx],s,sizeof s);
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0) gt.modify(1,0,n,cur+1,las,idx);
		if (dir==1) ft.modify(1,0,n,las+1,cur,idx);
	}

	ft.dfs(1,1,n);gt.dfs(1,1,n);
	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		int id=min(gt.val[_l],ft.val[_r+1]);
		for (int j=0;j<10;j++)
			printf("%d ",f[id][j]-f[ft.val[_l]][j]);
		puts("");
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 100005;

int s[10];
int n,q,ft[maxn],gt[maxn],idx;
char str[maxn];
int f[maxn][10];
int g[maxn][10];
int l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0) {
			for (int t=cur+1;t<=las;t++) if (!gt[t]){
				memcpy(g[t],s,sizeof s);gt[t]=idx;
			}
		}
		if (dir==1) {
			for (int t=cur;t>=las+1;t--) if (!ft[t]){
				memcpy(f[t],s,sizeof s);ft[t]=idx;
			}
		}
	}

	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		if (gt[_l]<ft[_r+1]&&gt[_l]) {
			for (int j=0;j<10;j++)
				printf("%d ",g[_l][j]-f[_l][j]);
			puts("");
		}
		else {
			for (int j=0;j<10;j++)
				printf("%d ",f[_r+1][j]-f[_l][j]);
			puts("");
		}
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <vector>

using namespace std;
typedef long long LL;
#define pb push_back
const int maxn = 100005;

int s[10];
int n,q,ft[maxn],gt[maxn],idx;
char str[maxn];
int f[maxn][10];
int g[maxn][10];
int l[maxn],r[maxn];
void remove(int x) {
	int _l=l[x],_r=r[x];
	l[_r]=_l;r[_l]=_r;
}
bool direct(int x) {
	return str[x]=='<'||str[x]=='>';
}
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("tape.in","r",stdin);
		freopen("tape.out","w",stdout);
	#endif
	scanf("%d %d %s",&n,&q,str+1);str[0]='>';
	for (int i=0;i<=n;i++) r[i]=i+1,l[i+1]=i;
	int cur=0,dir=1,las=n+1;
	while (cur<=n) {
		if (str[cur]=='<') dir=0;
		else if (str[cur]=='>') dir=1;
		else {
			s[str[cur]-'0']++;
			if (str[cur]>'0') str[cur]--;
			else remove(cur);
		}
		las=cur;cur=dir?r[cur]:l[cur];++idx;
		if (las&&direct(las)&&direct(cur)) remove(las);
		if (dir==0&&!gt[las]) memcpy(g[las],s,sizeof s),gt[las]=idx;
		if (dir==1&&!ft[cur]) memcpy(f[cur],s,sizeof s),ft[cur]=idx;
	}

	for (int _l,_r,i=1;i<=q;i++) {
		scanf("%d %d",&_l,&_r);
		if (gt[_l]<ft[_r+1]&&gt[_l]) {
			for (int j=0;j<10;j++)
				printf("%d ",g[_l][j]-f[_l][j]);
			puts("");
		}
		else {
			for (int j=0;j<10;j++)
				printf("%d ",f[_r+1][j]-f[_l][j]);
			puts("");
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define RI register int
const int N=100005,inf=0x3f3f3f3f;
int n,Q;char S[N];
int in[N][10],lout[N][10],rout[N][10],now[10],nxt[N],pre[N];
int arrive[N],l_leave[N],r_leave[N],a[N];

int move(int x,int direction) {
	if(direction==-1&&!l_leave[x]) {
		l_leave[x]=1;
		for(RI i=0;i<=9;++i) lout[x][i]=now[i];
	}
	if(direction==1&&!r_leave[x]) {
		r_leave[x]=1;
		for(RI i=0;i<=9;++i) rout[x][i]=now[i];
	}
	if(a[x]==-3&&l_leave[x]&&r_leave[x]) nxt[pre[x]]=nxt[x],pre[nxt[x]]=pre[x];
	if(direction==-1) return pre[x];
	else return nxt[x];
}
void walk(int x,int direction) {
	if(!arrive[x]) {
		arrive[x]=1;
		for(RI i=0;i<=9;++i) in[x][i]=now[i];
	}
	if(a[x]==-1) direction=-1;
	else if(a[x]==-2) direction=1;
	else {
		++now[a[x]],--a[x];
		if(a[x]==-1) a[x]=-3;
	}
	int y=move(x,direction);
	while(y>=1&&y<=n&&a[y]==-3) y=move(y,direction);
	if(y>=1&&y<=n) {
		if((a[y]==-1||a[y]==-2)&&(a[x]==-1||a[x]==-2)) a[x]=-3;
		walk(y,direction);
	}
}

int main()
{
	scanf("%d%d",&n,&Q);
	scanf("%s",S+1);
	for(RI i=1;i<=n;++i) {
		if(S[i]=='<') a[i]=-1;
		else if(S[i]=='>') a[i]=-2;
		else a[i]=S[i]-'0';
		nxt[i]=i+1,pre[i]=i-1;
	}
	for(RI i=1;i<=n;++i)
		for(RI j=0;j<=9;++j) lout[i][j]=rout[i][j]=inf;
	for(RI i=1;i<=n;++i) if(!arrive[i]) walk(i,1);
	while(Q--) {
		int l,r;scanf("%d%d",&l,&r);
		for(RI j=0;j<=9;++j) printf("%d ",min(lout[l][j],rout[r][j])-in[l][j]);
		puts("");
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define RI register int
const int N=100005;
int n,Q;char S[N];
int ans[N][10],vis[N],leave[N],now[10],a[N];
vector<int> st[N],ed[N];

void move(int x,int direction) {
	if(direction==1) {
		for(RI i=0;i<ed[x].size();++i)
			if(!leave[ed[x][i]]) {
				leave[ed[x][i]]=1;
				for(RI j=0;j<=9;++j) ans[ed[x][i]][j]+=now[j];
			}
	}
	else {
		for(RI i=0;i<st[x].size();++i)
			if(!leave[st[x][i]]) {
				leave[st[x][i]]=1;
				for(RI j=0;j<=9;++j) ans[st[x][i]][j]+=now[j];
			}
	}
}
void walk(int x,int direction) {
	if(!vis[x]) {
		vis[x]=1;
		for(RI i=0;i<st[x].size();++i)
			for(RI j=0;j<=9;++j) ans[st[x][i]][j]-=now[j];
	}
	if(a[x]==-1) direction=1;
	else if(a[x]==-2) direction=-1;
	else {
		++now[a[x]];
		if(a[x]==0) a[x]=-3;
		else --a[x];
	}
	move(x,direction);int y=x+direction;
	while(y>=1&&y<=n&&a[y]==-3) move(y,direction),y+=direction;
	if(y>=1&&y<=n) {
		if((a[y]==-1||a[y]==-2)&&(a[x]==-1||a[x]==-2)) a[x]=-3;
		walk(y,direction);
	}
}

int main()
{
	scanf("%d%d",&n,&Q);
	scanf("%s",S+1);
	for(RI i=1;i<=n;++i) {
		if(S[i]=='>') a[i]=-1;
		else if(S[i]=='<') a[i]=-2;
		else a[i]=S[i]-'0';
	}
	for(RI i=1;i<=Q;++i) {
		int l,r;scanf("%d%d",&l,&r);
		st[l].push_back(i),ed[r].push_back(i);
	}
	for(RI i=1;i<=n;++i) if(!vis[i]) walk(i,1);
	for(RI i=1;i<=Q;++i) {
		for(RI j=0;j<=9;++j) printf("%d ",ans[i][j]);
		puts("");
	}
	return 0;
}


/*
直接模拟原程序，当走出左边界时强制往右走继续模拟
那么显然，执行一个区间[l, r]得到的程序就是模拟原程序过程中的一个区间。找到第一次进入l和第一次走出l或r的位置，就能得到这个区间
*/

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int Max_N(100050);
const int Max_M(10 * 100050);

#define LEFT  (segt[cur].l)
#define RIGHT (segt[cur].r)
#define MID   (segt[cur].mid)
#define MIN   (segt[cur].Min)
#define LCH   (cur << 1)
#define RCH   ((cur << 1) | 1)

struct node
{
	int l, r, mid, Min;
};
node segt[Max_N << 2];

void build_tree(int cur, int l, int r)
{
	LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), MIN = 0X3F3F3F3F;
	if (l == r)
		return;
	build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r);
}

void cover(int cur, int l, int r, int v)
{
	if (LEFT == l && RIGHT == r)
	{
		MIN = min(MIN, v);
		return;
	}
	if (r <= MID)
		cover(LCH, l, r, v);
	else
		if (l > MID)
			cover(RCH, l, r, v);
		else
			cover(LCH, l, MID, v), cover(RCH, MID + 1, r, v);
}

int query(int cur, int p)
{
	if (LEFT == RIGHT)
		return MIN;
	return min(MIN, p <= MID ? query(LCH, p) : query(RCH, p));
}

int N, M, Q, L[Max_N], R[Max_N], Pre[Max_M][10], F[Max_N];
char S[Max_N];

int main()
{
	scanf("%d%d", &N, &Q);
	scanf("%s", S + 1);
	for (int i = 0;i <= N + 1;++i)
		L[i] = max(0, i - 1), R[i] = min(N + 1, i + 1);
	memset(F, 0X3F, sizeof(F)), build_tree(1, 1, N + 1);
	M = 1;
	for (int p = 0, dx;;)
	{
		if (p == 0)
			dx = +1;
		if ('0' <= S[p] && S[p] <= '9')
		{
			++M;
			for (int c = 0;c <= 9;++c)
				Pre[M][c] = Pre[M - 1][c];
			++Pre[M][S[p] - '0'];
			if (S[p] - '0')
				--S[p];
			else
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		if (S[p] == '<')
		{
			dx = -1;
			if (S[L[p]] == '<' || S[L[p]] == '>')
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		if (S[p] == '>')
		{
			dx = +1;
			if (S[R[p]] == '<' || S[R[p]] == '>')
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		F[p] = min(F[p], M);
		if (p == N + 1)
			break;
		if (dx == +1)
			p = R[p];
		else
			cover(1, L[p] + 1, p, M), p = L[p];
	}
	for (int l, r, a, b;Q--;)
	{
		scanf("%d%d", &l, &r);
		a = F[l] + 1 - ('0' <= S[l] && S[l] <= '9'), b = min(F[r + 1] - ('0' <= S[r + 1] && S[r + 1] <= '9'), query(1, l));
		for (int c = 0;c <= 9;++c)
			printf("%d ", a <= b ? Pre[b][c] - Pre[a - 1][c] : 0);
		printf("\n");
	}
	return 0;
}


/*
直接模拟原程序，当走出左边界时强制往右走继续模拟
那么显然，执行一个区间[l, r]得到的程序就是模拟原程序过程中的一个区间。找到第一次进入l和第一次走出l或r的位置，就能得到这个区间
*/

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int Max_N(100050);
const int Max_M(10 * 100050);

#define LEFT  (segt[cur].l)
#define RIGHT (segt[cur].r)
#define MID   (segt[cur].mid)
#define MIN   (segt[cur].Min)
#define LCH   (cur << 1)
#define RCH   ((cur << 1) | 1)

struct node
{
	int l, r, mid, Min;
};
node segt[Max_N << 2];

void build_tree(int cur, int l, int r)
{
	LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), MIN = 0X3F3F3F3F;
	if (l == r)
		return;
	build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r);
}

void cover(int cur, int l, int r, int v)
{
	if (LEFT == l && RIGHT == r)
	{
		MIN = min(MIN, v);
		return;
	}
	if (r <= MID)
		cover(LCH, l, r, v);
	else
		if (l > MID)
			cover(RCH, l, r, v);
		else
			cover(LCH, l, MID, v), cover(RCH, MID + 1, r, v);
}

int query(int cur, int p)
{
	if (LEFT == RIGHT)
		return MIN;
	return min(MIN, p <= MID ? query(LCH, p) : query(RCH, p));
}

int N, M, Q, L[Max_N], R[Max_N], Pre[Max_M][10], F[Max_N];
char S[Max_N];

int main()
{
	scanf("%d%d", &N, &Q);
	scanf("%s", S + 1);
	for (int i = 0;i <= N + 1;++i)
		L[i] = max(0, i - 1), R[i] = min(N + 1, i + 1);
	memset(F, 0X3F, sizeof(F)), build_tree(1, 1, N + 1);
	M = 1;
	for (int p = 0, dx;;)
	{
		if (p == 0)
			dx = +1;
		if ('0' <= S[p] && S[p] <= '9')
		{
			++M;
			for (int c = 0;c <= 9;++c)
				Pre[M][c] = Pre[M - 1][c];
			++Pre[M][S[p] - '0'];
			if (S[p] - '0')
				--S[p];
			else
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		if (S[p] == '<')
		{
			dx = -1;
			if (L[p] == 0 || S[L[p]] == '<' || S[L[p]] == '>')
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		if (S[p] == '>')
		{
			dx = +1;
			if (S[R[p]] == '<' || S[R[p]] == '>')
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		F[p] = min(F[p], M);
		if (p == N + 1)
			break;
		if (dx == +1)
			p = R[p];
		else
			cover(1, L[p] + 1, p, M), p = L[p];
	}
	for (int l, r, a, b;Q--;)
	{
		scanf("%d%d", &l, &r);
		a = F[l] + 1 - ('0' <= S[l] && S[l] <= '9'), b = min(F[r + 1] - ('0' <= S[r + 1] && S[r + 1] <= '9'), query(1, l));
		for (int c = 0;c <= 9;++c)
			printf("%d ", a <= b ? Pre[b][c] - Pre[a - 1][c] : 0);
		printf("\n");
	}
	return 0;
}


/*
直接模拟原程序，当走出左边界时强制往右走继续模拟
那么显然，执行一个区间[l, r]得到的程序就是模拟原程序过程中的一个区间。找到第一次进入l和第一次走出l或r的位置，就能得到这个区间
*/

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int Max_N(100050);
const int Max_M(10 * 100050);

#define LEFT  (segt[cur].l)
#define RIGHT (segt[cur].r)
#define MID   (segt[cur].mid)
#define MIN   (segt[cur].Min)
#define LCH   (cur << 1)
#define RCH   ((cur << 1) | 1)

struct node
{
	int l, r, mid, Min;
};
node segt[Max_N << 2];

void build_tree(int cur, int l, int r)
{
	LEFT = l, RIGHT = r, MID = l + ((r - l) >> 1), MIN = 0X3F3F3F3F;
	if (l == r)
		return;
	build_tree(LCH, l, MID), build_tree(RCH, MID + 1, r);
}

void cover(int cur, int l, int r, int v)
{
	if (LEFT == l && RIGHT == r)
	{
		MIN = min(MIN, v);
		return;
	}
	if (r <= MID)
		cover(LCH, l, r, v);
	else
		if (l > MID)
			cover(RCH, l, r, v);
		else
			cover(LCH, l, MID, v), cover(RCH, MID + 1, r, v);
}

int query(int cur, int p)
{
	if (LEFT == RIGHT)
		return MIN;
	return min(MIN, p <= MID ? query(LCH, p) : query(RCH, p));
}

int N, M, Q, L[Max_N], R[Max_N], Pre[Max_M][10], F[Max_N];
char S[Max_N];

int main()
{
	scanf("%d%d", &N, &Q);
	scanf("%s", S + 1);
	for (int i = 0;i <= N + 1;++i)
		L[i] = max(0, i - 1), R[i] = min(N + 1, i + 1);
	memset(F, 0X3F, sizeof(F)), build_tree(1, 1, N + 1);
	M = 1;
	for (int p = 0, dx;;)
	{
		if (p == 0)
			dx = +1;
		if ('0' <= S[p] && S[p] <= '9')
		{
			++M;
			for (int c = 0;c <= 9;++c)
				Pre[M][c] = Pre[M - 1][c];
			++Pre[M][S[p] - '0'];
			if (S[p] - '0')
				--S[p];
			else
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		if (S[p] == '<')
		{
			dx = -1;
			if (p == 0 || S[L[p]] == '<' || S[L[p]] == '>')
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		if (S[p] == '>')
		{
			dx = +1;
			if (S[R[p]] == '<' || S[R[p]] == '>')
				R[L[p]] = R[p], L[R[p]] = L[p];
		}
		F[p] = min(F[p], M);
		if (p == N + 1)
			break;
		if (dx == +1)
			p = R[p];
		else
			cover(1, L[p] + 1, p, M), p = L[p];
	}
	for (int l, r, a, b;Q--;)
	{
		scanf("%d%d", &l, &r);
		a = F[l] + 1 - ('0' <= S[l] && S[l] <= '9'), b = min(F[r + 1] - ('0' <= S[r + 1] && S[r + 1] <= '9'), query(1, l));
		for (int c = 0;c <= 9;++c)
			printf("%d ", a <= b ? Pre[b][c] - Pre[a - 1][c] : 0);
		printf("\n");
	}
	return 0;
}


/** I can do this all day **/

#pragma GCC optimize("O2")
#include <bits/stdc++.h>
using namespace std;

typedef long long                   ll;
typedef long double                 ld;
typedef pair<int,int>               pii;
typedef pair<ll,ll>                 pll;
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second
#define Mp                          make_pair
#define fast_io                     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define file_io                     freopen("in.txt" , "r+" , stdin) ; freopen("out.txt" , "w+" , stdout);
#define endl                        "\n"

const int N = 1e6 + 10;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const ll inf = 8e18;
const int LOG = 22;

ll pw(ll a , ll b, ll M)  { return (!b ? 1 : (b & 1 ? (a * pw(a * a % M, b / 2, M)) % M : pw(a * a % M, b / 2, M))); }

int v[N], ans[N], n, h;

int solve1()
{
        // hamash ye grouh
        vector < int > v2;
        for(int i = 1; i <= n; i++) { v2.push_back(v[i]); }
        sort(all(v2));
        return (v2[n - 1] + v2[n - 2]) - (v2[1] + v2[0]);
}

pii solve2()
{
        // min samte 1 baghie samte 2
        int Mn = 2e9, id = 1;
        for(int i = 1; i <= n; i++)
        {
                if(Mn > v[i])
                {
                        Mn = v[i];
                        id = i;
                }
        }
        vector < int > v2;
        for(int i = 1; i <= n; i++)
        {
                if(i == id) { continue; }
                v2.push_back(v[i]);
        }
        sort(all(v2));
        int M1 = 2e9, M2 = 0;
        M1 = min(M1, Mn + h + v2[0]);
        if(n > 2) { M1 = min(M1, v2[0] + v2[1]); }
        M2 = max(M2, Mn + h + v2[n - 2]);
        if(n > 2)
        {
                M2 = max(M2, v2[n - 2] + v2[n - 3]);
        }
        return Mp(M2 - M1, id);
}

int main(){
    fast_io;
    //cout << fixed << setprecision(15);
    //scanf("%d %d %f %lld %s %c", &x);
    //printf("%d %d %f %lld %s %c", x);
    cin >> n >> h;
    for(int i = 1; i <= n; i++) { cin >> v[i]; }
    int c1 = solve1();
    pii c2 = solve2();
    if(c1 <= c2.F)
    {
            cout << c1 << endl;
            for(int i = 1; i <= n; i++)
            {
                    cout << 2 << " ";
            }
    }
    else
    {
            cout << c2.F << endl;
            for(int i = 1; i <= n; i++)
            {
                    if(i == c2.S)
                    {
                            cout << 1 << " ";
                    }
                    else
                    {
                            cout << 2 << " ";
                    }
            }
    }
    return 0;
}
/*!
        stay away from negative people they have a problem for every solution !
*/


#pragma GCC optimize "03"
#include "bits/stdc++.h"
using namespace std;

#define int long long int
#define ld long double
#define pi pair<int, int>
#define pb push_back
#define fi first
#define se second
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#ifndef LOCAL
#define endl '\n'
#endif

const int N = 1e5 + 5;
const int mod = 1e9 + 7;
const int inf = 1e9 + 9;

pi a[N];
int p[N];

signed main() {
	IOS;
	#ifdef LOCAL
		freopen("input.txt","r", stdin);
		freopen("output.txt","w",stdout);
	#endif
	int n, h;
	cin >> n >> h;
	for(int i = 1; i <= n; i++){
		cin >> a[i].fi;
		a[i].se = i;
	}
	sort(a+1, a+n+1);
	int ans = (a[n].fi+a[n-1].fi) - (a[1].fi+a[2].fi);
	int mx = max({a[n].fi+a[n-1].fi, a[n].fi+a[1].fi+h});
	int mi = a[2].fi+a[1].fi+h;
	if(n >= 3)
		mi = min(mi, a[2].fi+a[3].fi);
	if(ans <= mx-mi){
		cout << ans << endl;
		for(int i = 1; i <= n; i++)
			cout << 1 << " ";
	}
	else{
		cout << mx-mi << endl;
		for(int i = 2; i <= n; i++)
			p[a[i].se] = 2;
		p[a[1].se] = 1;
		for(int i = 1; i <= n; i++)
			cout << p[i] << " ";
	}
	return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
//#include<unordered_map>
#include <set>
#include<string>
#include<string.h>
#include<fstream>
#include<stack>
#include<iomanip>
#include<bitset>
#include<cmath>
//#include<random>
using namespace std;
typedef long long LL;
typedef long long ll;
typedef pair<int, int> P;
//#define mp make_pair
#define lson rt<<1
#define rson rt<<1|1
#define mid (l+r)>>1
#define mes(a) memset(a,0,sizeof a)
#define NO "NO"
#define YES "YES"
#define pk push_back
#ifndef scanf
#define scanf scanf_s
#endif
//#define mp make_pair
//long double pi = acos(-1);
LL mod = 1e9 + 7;
LL QPow(LL a, LL b) { LL ans = 1; while (b > 0) { if (b & 1)ans = ans % mod * a%mod; a = a % mod * a%mod; b >>= 1; }return ans; }
/*LL inf = (LL)1 << 30;
double eps = 1e-8;
//LL mod = 1e9 + 7;
LL fac[5002];
LL fac_1[5002];
LL inv[5002];
void getInv()
{
	inv[1] = 1;
	for (int i = 2; i <= 5000; i++)
		inv[i] = (mod - mod / i)*inv[mod%i] % mod;
}
void init1()
{
	fac[0] = 1;
	fac_1[0] = 1;
	fac_1[1] = 1;
	for (int i = 1; i <= 5000; i++)
		fac[i] = fac[i - 1] * i%mod, fac_1[i] = inv[i] * fac_1[i - 1]%mod;
}
LL C(int n, int m)
{
	if (m<0 || m>n)return 0;
	return fac[n] * fac_1[n - m] % mod*fac_1[m] % mod;
}*/
LL gcd(LL x, LL y)
{
	if (x == 1 || y == 1)
		return 1;
	else
	{
		if (x == 0)return y;
		if (y == 0)return x;
		if (x%y == 0)return y;
		if (y%x == 0)return x;
		if (x > y)return gcd(x%y, y);
		else return gcd(x, y%x);
	}
}
/*
int sign(LL x)
{
	if (x == 0)return 0;
	if (x > 0)return 1;
	return -1;
}
LL toInt(string str)
{
	LL ans = 0;
	for (int i = (str[0] == '-'); i < str.size(); i++)
	{
		ans *= 10;
		ans += str[i] - '0';
	}
	if (str[0] == '-')
		ans = -ans;
	return ans;
}*/
//整数转字符串
string toString(LL a)
{
	if (a == 0)return "0";
	string temp = "";
	if (a < 0)
		temp.push_back('-');
	LL tp = a;
	while (tp)
	{
		temp.push_back('0' + tp % 10);
		tp /= 10;
	}
	string temp2 = temp;
	for (int ii = 0; ii < temp.size(); ii++)
	{
		temp[ii] = temp2[temp.size() - 1 - ii];
	}
	return temp;
}
/*ll fpow(ll a, ll b, ll c) { a %= c; ll ans = 1; while (b > 0) { if (b & 1)ans = ans * a%c; b >>= 1; a = a * a%c; }return ans; }
bool IsQuadraticResidue(ll a, ll p) {//判断a是否为p的二次剩余 p是素数
	return fpow(a, (p - 1) >> 1, p) == 1;
}
ll Shanks(ll a, ll p) {//求解二次同余方程x^2=a(mod p) p是素数
	if (a == 0)return 0;
	ll q = p - 1, e = 0;
	while (!(q & 1))q >>= 1, e++;
	static mt19937_64 rd(time(0));
	ll n = rd() % (p - 1) + 1;//随机选取p的一个非二次剩余，若p为定值，n也可为定值
	while (IsQuadraticResidue(n, p))n = rd() % (p - 1) + 1;
	ll z = fpow(n, q, p), y = z, r = e, x = fpow(a, (q - 1) >> 1, p), b = a * x%p*x%p;
	x = a * x%p;
	while (b != 1) {
		ll temp = b * b%p, m = 1;
		while (temp != 1)(temp *= temp) %= p, m++;
		if (m == r)return -1;
		ll t = y;
		//rep(i, 1, r - m - 1)
		for(int i=1;i<=r-m-1;i++)
			(t *= t) %= p;
		y = t * t%p, r = m % p, x = x * t%p, b = b * y%p;
	}
	return x;
}
const int mx = 1e3 + 5;
//int arr[mx][mx];
LL rd() {
	LL ans = 0; char last = ' ', ch = getchar();
	while (!(ch >= '0' && ch <= '9'))last = ch, ch = getchar();
	while (ch >= '0' && ch <= '9')ans = ans * 10 + ch - '0', ch = getchar();
	if (last == '-')ans = -ans; return ans;
}*/
LL inf = 1<<30;
const int maxn = 5e6+5 ;
const int maxm = 5e4 + 5;
int n, m, s, t, cnt = 0;
int head[maxn];
int cur[maxn];
int dis[maxn];
bool vis[maxn];
int minfee = 0;
struct edge
{
	int v, w, nx,f;//w=cost
}eds[maxm * 2];
inline void add(int u, int v, int flow,int w)
{
	eds[cnt].v = v;
	eds[cnt].w = flow;//cost
	eds[cnt].f = w;
	eds[cnt].nx = head[u];
	head[u] = cnt++;
}
/*bool spfa(int u, int v)
{
	for (int i = 0; i < maxn; i++)dis[i] = inf;
	mes(vis);
	dis[u] = 0;
	deque<int>d;
	d.push_back(u);
	vis[u] = 1;
	while (!d.empty())
	{
		int uu = d.front();
		d.pop_front();
		vis[uu] = 0;
		for (int i = head[uu]; i != -1; i = eds[i].nx)
		{
			int vv = eds[i].v;
			int w = eds[i].w;
			int f = eds[i].f;
			if (f&&dis[vv] > dis[uu] + w)
			{
				dis[vv] = dis[uu] + w;
				if (!vis[vv])
				{
					if (!d.empty() && dis[vv] < dis[d.front()])
						d.push_front(vv);
					else d.push_back(vv);
				}
			}
		}
	}
	return dis[t] != inf;
}*/
bool bfs()
{
	memset(dis, -1, sizeof dis);
	dis[1] = 0;
	queue<int>q;
	q.push(s);
	while (!q.empty())
	{
		int r = q.front();
		q.pop();
		for (int i = head[r]; i != -1; i = eds[i].nx)
		{
			int j = eds[i].v;
			if (dis[j] == -1 && eds[i].w)
			{
				dis[j] = dis[r] + 1;
				q.push(j);
			}
		}
	}
	return dis[t] != -1;
}
int dfs(int u, int flo)
{
	if (u == n)return flo;
	int detla = flo;
	for (int i = head[u]; i != -1; i = eds[i].nx)
	{
		int v = eds[i].v;
		if (dis[v] == (dis[u] + 1) && (eds[i].w > 0))
		{
			int d = dfs(v, min(detla, eds[i].w));
			eds[i].w -= d;
			eds[i ^ 1].v += d;
			detla -= d;
			if (detla == 0)break;
		}
	}
	return flo - detla;
}
int dini()
{
	int ans = 0;
	while (bfs())
	{
		//mes(vis);
		ans += dfs(s, inf);
	}
	return ans;
}
int arr[maxn];
int arr1[maxn];
int arr2[maxn];
vector<int>ch = { 0,1,2,3 };
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	ifstream in("Text.txt");
	LL h;
	cin >> n>>h;
	if (n == 2)
	{
		cout << 0 << endl;
		for (int i = 0; i < n; i++)
			cin >> h, cout << h << " ";
		return 0;
	}
	for (int i = 1; i <= n; i++)
		cin >> arr2[i],arr[i]=arr2[i];
	sort(arr+1, arr + n+1);
	arr[0] = -1;
	LL dif = inf;
	int c = 0;
	for (int i = 0; i < ch.size(); i++)
	{
		if (ch[i] == 0)
		{
			if (arr[n] + arr[n - 1] - arr[1] - arr[2]<dif)
			{
				c = i;
				dif = arr[n] + arr[n - 1] - arr[1] - arr[2];
			}
		}
		else
		{
			int cnt = 0;
			for (int j = 1; j <= n; j++)
				if (j != ch[i])
					arr1[cnt++] = arr[j];
			sort(arr1, arr1 + cnt);
			LL mx = arr[ch[i]]+arr1[cnt-1]+h;
			mx = max(mx, (LL)arr1[cnt-1]+arr1[cnt-2]);
			LL sum = 0;
			for (int j = 1; j <= 3; j++)
				if (j != i)
					sum += arr[j];
			sum = mx - min(sum, arr[ch[i]] + arr1[0] + h);
			//cout << i << " " << mx << " " << sum << endl;
			if (sum < dif)
				dif = sum, c = i;
		}
	}
	cout << dif << endl;
	int flag = 0;
	//cout << "c"<<c << endl;
	for(int i=1;i<=n;i++)
		if (arr2[i] == arr[c])
		{
			flag = i;
			break;
		}
	for (int i = 1; i <= n; i++)
	{
		if (i == flag)
			cout << 2 << " ";
		else cout << 1 << " ";
	}
//	system("pause");
	return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
//#include<unordered_map>
#include <set>
#include<string>
#include<string.h>
#include<fstream>
#include<stack>
#include<iomanip>
#include<bitset>
#include<cmath>
//#include<random>
using namespace std;
typedef long long LL;
typedef long long ll;
typedef pair<int, int> P;
//#define mp make_pair
#define lson rt<<1
#define rson rt<<1|1
#define mid (l+r)>>1
#define mes(a) memset(a,0,sizeof a)
#define NO "NO"
#define YES "YES"
#define pk push_back
#ifndef scanf
#define scanf scanf_s
#endif
//#define mp make_pair
//long double pi = acos(-1);
LL mod = 1e9 + 7;
LL QPow(LL a, LL b) { LL ans = 1; while (b > 0) { if (b & 1)ans = ans % mod * a%mod; a = a % mod * a%mod; b >>= 1; }return ans; }
/*LL inf = (LL)1 << 30;
double eps = 1e-8;
//LL mod = 1e9 + 7;
LL fac[5002];
LL fac_1[5002];
LL inv[5002];
void getInv()
{
	inv[1] = 1;
	for (int i = 2; i <= 5000; i++)
		inv[i] = (mod - mod / i)*inv[mod%i] % mod;
}
void init1()
{
	fac[0] = 1;
	fac_1[0] = 1;
	fac_1[1] = 1;
	for (int i = 1; i <= 5000; i++)
		fac[i] = fac[i - 1] * i%mod, fac_1[i] = inv[i] * fac_1[i - 1]%mod;
}
LL C(int n, int m)
{
	if (m<0 || m>n)return 0;
	return fac[n] * fac_1[n - m] % mod*fac_1[m] % mod;
}*/
LL gcd(LL x, LL y)
{
	if (x == 1 || y == 1)
		return 1;
	else
	{
		if (x == 0)return y;
		if (y == 0)return x;
		if (x%y == 0)return y;
		if (y%x == 0)return x;
		if (x > y)return gcd(x%y, y);
		else return gcd(x, y%x);
	}
}
/*
int sign(LL x)
{
	if (x == 0)return 0;
	if (x > 0)return 1;
	return -1;
}
LL toInt(string str)
{
	LL ans = 0;
	for (int i = (str[0] == '-'); i < str.size(); i++)
	{
		ans *= 10;
		ans += str[i] - '0';
	}
	if (str[0] == '-')
		ans = -ans;
	return ans;
}*/
//整数转字符串
string toString(LL a)
{
	if (a == 0)return "0";
	string temp = "";
	if (a < 0)
		temp.push_back('-');
	LL tp = a;
	while (tp)
	{
		temp.push_back('0' + tp % 10);
		tp /= 10;
	}
	string temp2 = temp;
	for (int ii = 0; ii < temp.size(); ii++)
	{
		temp[ii] = temp2[temp.size() - 1 - ii];
	}
	return temp;
}
/*ll fpow(ll a, ll b, ll c) { a %= c; ll ans = 1; while (b > 0) { if (b & 1)ans = ans * a%c; b >>= 1; a = a * a%c; }return ans; }
bool IsQuadraticResidue(ll a, ll p) {//判断a是否为p的二次剩余 p是素数
	return fpow(a, (p - 1) >> 1, p) == 1;
}
ll Shanks(ll a, ll p) {//求解二次同余方程x^2=a(mod p) p是素数
	if (a == 0)return 0;
	ll q = p - 1, e = 0;
	while (!(q & 1))q >>= 1, e++;
	static mt19937_64 rd(time(0));
	ll n = rd() % (p - 1) + 1;//随机选取p的一个非二次剩余，若p为定值，n也可为定值
	while (IsQuadraticResidue(n, p))n = rd() % (p - 1) + 1;
	ll z = fpow(n, q, p), y = z, r = e, x = fpow(a, (q - 1) >> 1, p), b = a * x%p*x%p;
	x = a * x%p;
	while (b != 1) {
		ll temp = b * b%p, m = 1;
		while (temp != 1)(temp *= temp) %= p, m++;
		if (m == r)return -1;
		ll t = y;
		//rep(i, 1, r - m - 1)
		for(int i=1;i<=r-m-1;i++)
			(t *= t) %= p;
		y = t * t%p, r = m % p, x = x * t%p, b = b * y%p;
	}
	return x;
}
const int mx = 1e3 + 5;
//int arr[mx][mx];
LL rd() {
	LL ans = 0; char last = ' ', ch = getchar();
	while (!(ch >= '0' && ch <= '9'))last = ch, ch = getchar();
	while (ch >= '0' && ch <= '9')ans = ans * 10 + ch - '0', ch = getchar();
	if (last == '-')ans = -ans; return ans;
}*/
LL inf = 1<<30;
const int maxn = 5e6+5 ;
const int maxm = 5e4 + 5;
int n, m, s, t, cnt = 0;
int head[maxn];
int cur[maxn];
int dis[maxn];
bool vis[maxn];
int minfee = 0;
struct edge
{
	int v, w, nx,f;//w=cost
}eds[maxm * 2];
inline void add(int u, int v, int flow,int w)
{
	eds[cnt].v = v;
	eds[cnt].w = flow;//cost
	eds[cnt].f = w;
	eds[cnt].nx = head[u];
	head[u] = cnt++;
}
/*bool spfa(int u, int v)
{
	for (int i = 0; i < maxn; i++)dis[i] = inf;
	mes(vis);
	dis[u] = 0;
	deque<int>d;
	d.push_back(u);
	vis[u] = 1;
	while (!d.empty())
	{
		int uu = d.front();
		d.pop_front();
		vis[uu] = 0;
		for (int i = head[uu]; i != -1; i = eds[i].nx)
		{
			int vv = eds[i].v;
			int w = eds[i].w;
			int f = eds[i].f;
			if (f&&dis[vv] > dis[uu] + w)
			{
				dis[vv] = dis[uu] + w;
				if (!vis[vv])
				{
					if (!d.empty() && dis[vv] < dis[d.front()])
						d.push_front(vv);
					else d.push_back(vv);
				}
			}
		}
	}
	return dis[t] != inf;
}*/
bool bfs()
{
	memset(dis, -1, sizeof dis);
	dis[1] = 0;
	queue<int>q;
	q.push(s);
	while (!q.empty())
	{
		int r = q.front();
		q.pop();
		for (int i = head[r]; i != -1; i = eds[i].nx)
		{
			int j = eds[i].v;
			if (dis[j] == -1 && eds[i].w)
			{
				dis[j] = dis[r] + 1;
				q.push(j);
			}
		}
	}
	return dis[t] != -1;
}
int dfs(int u, int flo)
{
	if (u == n)return flo;
	int detla = flo;
	for (int i = head[u]; i != -1; i = eds[i].nx)
	{
		int v = eds[i].v;
		if (dis[v] == (dis[u] + 1) && (eds[i].w > 0))
		{
			int d = dfs(v, min(detla, eds[i].w));
			eds[i].w -= d;
			eds[i ^ 1].v += d;
			detla -= d;
			if (detla == 0)break;
		}
	}
	return flo - detla;
}
int dini()
{
	int ans = 0;
	while (bfs())
	{
		//mes(vis);
		ans += dfs(s, inf);
	}
	return ans;
}
int arr[maxn];
int arr1[maxn];
int arr2[maxn];
vector<int>ch = { 0,1,2,3 };
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	ifstream in("Text.txt");
	LL h;
	cin >> n>>h;
	if (n == 2)
	{
		cout << 0 << endl;
		for (int i = 0; i < n; i++)
			cin >> h, cout << 1 << " ";
		return 0;
	}
	for (int i = 1; i <= n; i++)
		cin >> arr2[i],arr[i]=arr2[i];
	sort(arr+1, arr + n+1);
	arr[0] = -1;
	LL dif = inf;
	int c = 0;
	for (int i = 0; i < ch.size(); i++)
	{
		if (ch[i] == 0)
		{
			if (arr[n] + arr[n - 1] - arr[1] - arr[2]<dif)
			{
				c = i;
				dif = arr[n] + arr[n - 1] - arr[1] - arr[2];
			}
		}
		else
		{
			int cnt = 0;
			for (int j = 1; j <= n; j++)
				if (j != ch[i])
					arr1[cnt++] = arr[j];
			sort(arr1, arr1 + cnt);
			LL mx = arr[ch[i]]+arr1[cnt-1]+h;
			mx = max(mx, (LL)arr1[cnt-1]+arr1[cnt-2]);
			LL sum = 0;
			for (int j = 1; j <= 3; j++)
				if (j != i)
					sum += arr[j];
			sum = mx - min(sum, arr[ch[i]] + arr1[0] + h);
			//cout << i << " " << mx << " " << sum << endl;
			if (sum < dif)
				dif = sum, c = i;
		}
	}
	cout << dif << endl;
	int flag = 0;
	//cout << "c"<<c << endl;
	for(int i=1;i<=n;i++)
		if (arr2[i] == arr[c])
		{
			flag = i;
			break;
		}
	for (int i = 1; i <= n; i++)
	{
		if (i == flag)
			cout << 2 << " ";
		else cout << 1 << " ";
	}
//	system("pause");
	return 0;
}


//You are the SEMICOLON to My STATEMENTS;

#include<bits/stdc++.h>
#define ll          long long
#define pb          push_back
#define    endl        '\n'
#define mii         map<ll int,ll int>
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll int)x.size()
#define hell        1000000007
#define mp          make_pair
#define INF         (1ll<<60)
#define rep(i,a,b)  for(ll i=a;i<=b;i++)
#define rrep(i,a,b)  for(ll i=a;i>=b;i--)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define N 100005
using namespace std;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
ll lcm(ll a, ll b) { return a * (b / gcd(a, b)); }
void solve(){
    ll n,k;
    cin>>n>>k;
    vector<pii> v(n);
    rep(i,0,n-1) cin>>v[i].F,v[i].S=i;
    sort(all(v),greater<pii>());
    if(n==2){
        cout<<"0"<<endl<<"1 1";
    }
    else{
        ll min1=v[0].F+v[1].F-v[n-1].F-v[n-2].F;
        ll min2=max(v[0].F+v[1].F,v[0].F+v[n-1].F+k)-min(v[n-2].F+v[n-3].F,v[n-1].F+v[n-2].F+k);
        if(min1<=min2){
            cout<<min1<<endl;
            rep(i,0,n-1) cout<<"1 ";
        }
        else{
            cout<<min2<<endl;
            rep(i,0,n-1){
                if(v[n-1].S==i) cout<<"2 ";
                else cout<<"1 ";
            }
        }
    }
}
int main()
{
    ios
    int TESTS=1;
   // cin>>TESTS;
    while(TESTS--){
        solve();
    }
    return 0;
}