code: def _bio_tags_to_spans(
      self, tags: List[str]
  ) -> List[Tuple[int, int]]:
      spans = []
      span_start = 0
      span_end = 0
      active_conll_tag = None
      for index, tag in enumerate(tags):
          bio_tag = tag[0]
          conll_tag = tag[2:]
          if bio_tag == "O":
              # The span has ended.
              if active_conll_tag is not None:
                  spans.append((span_start, span_end))
              active_conll_tag = None
              continue
          elif bio_tag == "B" or (
              bio_tag == "I" and conll_tag != active_conll_tag
          ):
              # We are entering a new span; reset indices
              # and active tag to new span.
              if active_conll_tag is not None:
                  spans.append((span_start, span_end))
              active_conll_tag = conll_tag
              span_start = index
              span_end = index
          elif bio_tag == "I" and conll_tag == active_conll_tag:
              # We're inside a span.
              span_end += 1
          else:
              raise Exception("That should never happen.")
  
      # Last token might have been a part of a valid span.
      if active_conll_tag is not None:
          spans.append((span_start, span_end))
  
      return spans
  
imports: import bisect
  import io
  import json
  import logging
  import os
  import re
  from collections import defaultdict
  from pathlib import Path
  from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union
  import conllu
  import gdown
  from conllu.models import Metadata, Token
  import flair
  from flair.data import Sentence
  from flair.datasets.sequence_labeling import ColumnCorpus
  from flair.file_utils import cached_path
  from flair.splitter import SegtokSentenceSplitter, SentenceSplitter
label_desc: Use image node_id 4 for calling the RE_ENGLISH_CONLL04 obj's underlying member method code with example usage: obj._bio_tags_to_spans(tags) and returns: spans