#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int maxn = 100100;
int n, q;
char s[maxn], S[maxn];
int pre[maxn], nxt[maxn], ans[maxn * 10][10], nowcnt[10], vis[maxn], tot,
    from[maxn];
inline void remove(int x) {
  nxt[pre[x]] = nxt[x];
  pre[nxt[x]] = pre[x];
}
vector<int> dfn[maxn];
inline bool Go() {
  if (nxt[0] > n) return 0;
  int now = nxt[0], flag = 0;
  for (;;) {
    memcpy(ans[++tot], nowcnt, sizeof(nowcnt));
    dfn[now].push_back(tot);
    if (now > n) return 0;
    if (now < 1) return 1;
    if (dfn[now].size() == 1) from[now] = pre[now];
    if (s[now] == '>') {
      flag = 0;
      int ttt = now;
      now = nxt[now];
      if (s[now] == '<' || s[now] == '>' || now == 0) remove(ttt);
    } else if (s[now] == '<') {
      flag = 1;
      int ttt = now;
      now = pre[now];
      if (s[now] == '<' || s[now] == '>' || now == 0) remove(ttt);
    } else {
      nowcnt[s[now] - '0']++;
      int ttt = now;
      if (flag)
        now = pre[now];
      else
        now = nxt[now];
      if (s[ttt] == '0')
        remove(ttt);
      else
        s[ttt]--;
    }
  }
}
inline int get(int x, int t) {
  vector<int>::iterator it = lower_bound(dfn[x].begin(), dfn[x].end(), t);
  if (it == dfn[x].end())
    return 1e8;
  else
    return *it;
}
int main() {
  scanf("%d%d%s", &n, &q, s + 1);
  for (int i = 1; i <= n; i++) nxt[i] = i + 1, pre[i] = i - 1;
  nxt[0] = 1;
  pre[n + 1] = n;
  for (; Go();)
    ;
  while (q--) {
    int l, r;
    scanf("%d%d", &l, &r);
    int posl = dfn[l][0], posr = min(get(from[l], posl), get(r + 1, posl));
    for (int i = 0; i <= 9; i++) printf("%d ", ans[posr][i] - ans[posl][i]);
    putchar('\n');
  }
  return 0;
}
