```ts
export function parseSpan(text: string): number {
  if (typeof text !== 'string' || !text.trim()) {
    throw new Error('Invalid span format');
  }

  const unitsOrder = ['yd', 'ft', 'in'];
  const parts = text.split(/\s+/).filter(Boolean);

  let inches = 0;
  const seenUnits = new Set<string>();

  for (const part of parts) {
    const match = /^(\d+)\b([a-z]{2})$/i.exec(part);
    if (!match) {
      throw new Error('Invalid span format');
    }

    const value = parseInt(match[1], 10);
    const unit = match[2].toLowerCase();

    if (isNaN(value) || value <= 0 || value.toString() !== match[1] || seenUnits.has(unit)) {
      throw new Error('Invalid span format');
    }

    if (!unitsOrder.includes(unit)) {
      throw new Error('Unknown unit in span');
    }

    const index = unitsOrder.indexOf(unit);
    inches += value * Math.pow(36, 2 - index) * Math.pow(12, index);

    seenUnits.add(unit);
  }

  return Math.round(inches);
}

export function formatSpan(inches: number): string {
  if (typeof inches !== 'number' || !Number.isInteger(inches) || inches < 0) {
    throw new Error('Invalid inches value');
  }

  const unitsOrder = ['yd', 'ft', 'in'];
  let result = '';

  for (const unit of unitsOrder) {
    const factor = unit === 'yd' ? 36 * 12 : unit === 'ft' ? 12 : 1;
    if (inches >= factor) {
      const value = Math.floor(inches / factor);
      inches -= value * factor;
      result += `${value}${unit}`;
    } else if (result && !result.endsWith('0')) {
      break;
    }
  }

  return result || '0in';
}

export function addSpans(first: string, second: string): string {
  const firstInches = parseSpan(first);
  const secondInches = parseSpan(second);
  return formatSpan(firstInches + secondInches);
}
```