const
  amount = 26;
type
  tmono = record
    letter: char;
    power: integer;
  end;

  tpoly = array[1 .. amount * amount] of record
    coeff: double;
    main, second: tmono;
  end;


procedure get_poly(var p: tpoly);
var
  found, quit: boolean;
  ch: char;
  i, curr: integer;
begin
  curr := 0;
  quit := false;
  repeat
    writeln('enter the element');
    write('letter: [A .. Z, <enter> to stop]: '); readln(ch);
    ch := upcase(ch);

    case ch of
      #13: quit := true;
      'A' .. 'Z':
        begin
          found := false;
          i := 1;
          while (i <= curr) and (not found) do
            if p[i].main.letter = ch then found := true
            else inc(i);

          if not found then begin
            inc(curr);
            p[curr].main.letter := ch;
            write('coeff = '); readln(p[curr].coeff);
            write('power = '); readln(p[curr].main.power);
          end
          else writeln('error: duplicate letter');
        end;
      else
        writeln('error in letter');
    end;

  until quit;
end;

procedure add(var p: tpoly; const p1, p2: tpoly);
var
  curr, i: integer;
begin
  curr := 0;
  for i := 1 to sqr(amount) do begin

    if p1[i].coeff <> 0 then begin
      inc(curr);
      p[curr] := p1[i];
    end;
    if p2[i].coeff <> 0 then begin
      inc(curr);
      p[curr] := p2[i];
    end;

  end;
end;

procedure mult(var p: tpoly; const p1, p2: tpoly);
var curr, i, j: integer;
begin
  curr := 0;
  for i := 1 to sqr(amount) do
    if p1[i].coeff <> 0 then
      for j := 1 to sqr(amount) do
        if p2[j].coeff <> 0then begin
          inc(curr);
          p[curr].coeff := p1[i].coeff * p2[j].coeff;
          p[curr].main.letter := p1[i].main.letter;
          p[curr].main.power := p1[i].main.power;
          p[curr].second.letter := p2[j].main.letter;
          p[curr].second.power := p2[j].main.power;
        end;
end;

procedure check_poly(var p: tpoly);

  function is_equal(a, b: tmono): boolean;
  begin
    is_equal := (a.letter = b.letter) and (a.power = b.power);
  end;

  function find_mono(start: integer;
           a, b: tmono; const pp: tpoly): integer;
  var i: integer;
  begin
    find_mono := -1;
    for i := start to sqr(amount) do
      if (pp[i].coeff <> 0) and
        (
          (is_equal(pp[i].main, a) and is_equal(pp[i].second, b))
          or
          (is_equal(pp[i].main, b) and is_equal(pp[i].second, a))
        )
      then begin
        find_mono := i; exit;
      end;
  end;

var
  i: integer;
  dup: integer;
begin
  for i := 1 to sqr(amount) do begin
    if p[i].coeff <> 0 then begin
      if (p[i].main.letter = p[i].second.letter) and
         (p[i].main.power = p[i].second.power) then begin
        inc(p[i].main.power, p[i].second.power);
        p[i].second.power := 0;
      end;
    end;
  end;

  for i := 1 to sqr(amount) do begin
    if p[i].coeff <> 0 then begin
      repeat
        dup := find_mono(i + 1, p[i].main, p[i].second, p);
        if dup <> -1 then begin
          p[i].coeff := p[i].coeff + p[dup].coeff;
          p[dup].coeff := 0;
        end;
      until dup = -1;
    end;
  end;

end;

procedure print_poly(const p: tpoly);
const
  sign: array[boolean] of char = ('+', '-');
var i: integer;
begin
  write('p = ');
  for i := 1 to sqr(amount) do
    if p[i].coeff <> 0 then begin
      write(sign[p[i].coeff < 0], abs(p[i].coeff):0:0, '*',
                                  p[i].main.letter, '^(', p[i].main.power, ')');
      if (p[i].second.letter in ['A' .. 'Z']) and (p[i].second.power <> 0) then
        write('*', p[i].second.letter, '^(', p[i].second.power, ')');
    end;
  writeln;
end;

var
  p1, p2, r1, r2: tpoly;

begin
  get_poly(p1); print_poly(p1);
  get_poly(p2); print_poly(p2);
  add(r1, p1, p2);
  mult(r2, p1, p2);

  writeln('adding:');
  check_poly(r1);
  print_poly(r1);
  writeln('multiply:');
  check_poly(r2);
  print_poly(r2);
end.