#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
const int Maxn = 100005;
char s[Maxn];
int n, q;
int seq[Maxn * 15];
int pos[Maxn * 15];
int sum[Maxn * 15][10];
int Mx[Maxn * 15];
int fir[Maxn];
int prv[Maxn], nxt[Maxn];
void Del(int np) {
  prv[nxt[np]] = prv[np];
  nxt[prv[np]] = nxt[np];
}
int Move(int np, int d) { return (d == 1) ? nxt[np] : prv[np]; }
int f(char c) { return (c == '>') ? 1 : -1; }
int tmin[Maxn * 60], tmax[Maxn * 60];
void build(int push, int l, int r) {
  if (l == r) {
    tmin[push] = tmax[push] = pos[l];
    return;
  }
  int mid = l + r >> 1;
  build(push * 2, l, mid);
  build(push * 2 + 1, mid + 1, r);
  tmin[push] = min(tmin[push * 2], tmin[push * 2 + 1]);
  tmax[push] = max(tmax[push * 2], tmax[push * 2 + 1]);
}
int queryMin(int push, int l, int r, int lo, int lim) {
  if (tmin[push] >= lim) {
    return -1;
  }
  if (l == r) {
    return l;
  }
  int mid = l + r >> 1;
  if (lo <= mid) {
    int ans = queryMin(push * 2, l, mid, lo, lim);
    if (ans != -1) {
      return ans;
    }
  }
  return queryMin(push * 2 + 1, mid + 1, r, max(mid + 1, lo), lim);
}
int queryMax(int push, int l, int r, int lo, int lim) {
  if (tmax[push] <= lim) {
    return -1;
  }
  if (l == r) {
    return l;
  }
  int mid = l + r >> 1;
  if (lo <= mid) {
    int ans = queryMax(push * 2, l, mid, lo, lim);
    if (ans != -1) {
      return ans;
    }
  }
  return queryMax(push * 2 + 1, mid + 1, r, max(mid + 1, lo), lim);
}
int main() {
  scanf("%d %d", &n, &q);
  scanf("%s", s + 1);
  memset(seq, -1, sizeof(seq));
  for (int i = 1; i <= n; i++) {
    fir[i] = 1e9;
    prv[i] = i - 1;
    nxt[i] = i + 1;
  }
  int np = 1, Mxp = 1;
  int dir = 1;
  int nst = 1;
  while (1) {
    for (;;) {
      if (np == 0 || np == n + 1) {
        pos[nst] = np;
        Mxp = max(Mxp, np);
        fir[Mxp] = min(fir[Mxp], nst);
        Mx[nst++] = Mxp;
        break;
      }
      if (s[np] >= '0' && s[np] <= '9') {
        seq[nst] = s[np] - '0';
        pos[nst] = np;
        Mxp = max(Mxp, np);
        if (s[np] != '0') {
          s[np]--;
        } else {
          Del(np);
        }
        np = Move(np, dir);
        fir[Mxp] = min(fir[Mxp], nst);
        Mx[nst++] = Mxp;
      } else if (s[np] == '>' || s[np] == '<') {
        pos[nst] = np;
        Mxp = max(Mxp, np);
        fir[Mxp] = min(fir[Mxp], nst);
        Mx[nst++] = Mxp;
        dir = f(s[np]);
        int newpos = Move(np, dir);
        if (newpos >= 1 && newpos <= n &&
            (s[newpos] == '<' || s[newpos] == '>')) {
          Del(np);
        }
        np = newpos;
      }
    }
    if (Mxp >= n) break;
    np = Mxp + 1;
    dir = 1;
  }
  nst--;
  for (int i = 1; i <= nst; i++) {
    for (int j = 0; j < 10; j++) {
      sum[i][j] = sum[i - 1][j];
    }
    if (seq[i] >= 0 && seq[i] <= 9) {
      sum[i][seq[i]]++;
    }
  }
  build(1, 1, nst);
  for (int i = 1; i <= q; i++) {
    int l, r;
    scanf("%d %d", &l, &r);
    int st = fir[l];
    int ed1 = queryMin(1, 1, nst, st + 1, l),
        ed2 = queryMax(1, 1, nst, st + 1, r);
    if (ed1 == -1) ed1 = nst + 1;
    if (ed2 == -1) ed2 = nst + 1;
    int ed = min(ed1, ed2) - 1;
    for (int j = 0; j < 10; j++) {
      printf("%d ", sum[ed][j] - sum[st - 1][j]);
    }
    printf("\n");
  }
  return 0;
}
