// File: /workspace/github_cpp_makefile_star2_O2/manschga[P]M5GB/./poly.h
// Function: polynomial::operator+(polynomial const&) const
polynomial operator+(const polynomial& rhs) const
  {
    //polynomial test_1 = *this;
    //polynomial test_2 = rhs;
    //cout << "Add " << test_1 << "and" << test_2 << endl;

    //compute *this+rhs = f+g (sum of polynomials)
    vector<monomial> f_mon = this->_monomials;

    if (this->Get_LC() == 0)
      {
	return rhs;
      }
    if (rhs.Get_LC() == 0)
      {
	return *this;
      }
    
    vector<monomial> g_mon = rhs._monomials;
    reverse(f_mon.begin(),f_mon.end());
    reverse(g_mon.begin(),g_mon.end());
    vector<monomial> h_mon = {};

    int f_i = f_mon.size()-1;
    int g_i = g_mon.size()-1;
    h_mon.reserve(f_i+g_i+2);
    vector<monomial> merged(f_i+g_i+2);
    std::merge(f_mon.begin(),f_mon.end(),g_mon.begin(),g_mon.end(),merged.begin());

    if (merged.size() > 1)
      {
	for (int i = 0; i < merged.size()-1; ++i)
	  {
	    //if (count(merged[i], merged[i+1], merged[i+1].Get_term()) == 1) 
	    if (merged[i].Get_term() != merged[i+1].Get_term())
	      {
		h_mon.push_back(merged[i]);
	      }
	    else
	      {
		++i;// do sum of both in one step
		//push_back sum of coeffs, case p != 2
	      }
	  }
	{
	  if (merged[merged.size()-2].Get_term() < merged[merged.size()-1].Get_term())
	    {
	      h_mon.push_back(merged[merged.size()-1]);
	    }
	}
      }
    else
      {
	h_mon = merged;
      }
    reverse(h_mon.begin(),h_mon.end());
    /*
    
   
    while (f_i >= 0 || g_i >= 0)//go through all terms of f and g
      {
	if (f_i < 0) //all terms of f done, avoid index crash!
	{
	  h_mon.emplace_back(g_mon[g_i]);
	  g_i--;
	}
      else if (g_i < 0)
	{
	  h_mon.emplace_back(f_mon[f_i]);
	  f_i--;
	}
	else
	{
	  if (f_mon[f_i].Get_term() == g_mon[g_i].Get_term())
	    {//same term appears in both, add up coefficients
	      h_mon.emplace_back(monomial(f_mon[f_i].Get_term(), (f_mon[f_i].Get_coeff() + g_mon[g_i].Get_coeff())%rhs._p, f_mon[f_i].Get_p()));
	      f_i--;
	      g_i--;
	    }
	  else
	    {
	      if (f_mon[f_i].Get_term()< g_mon[g_i].Get_term())
		{
		  h_mon.emplace_back(f_mon[f_i]);
		  f_i--;
		}
	      else
		{
		  h_mon.emplace_back(g_mon[g_i]);
		  g_i--;
		}
	    }
      }
      }
    */
    if (h_mon.size() == 0)
      {
	int p = this->Get_p();
	polynomial h({monomial(0,0,p)});
	//cout << "equals" << h << endl;
	return h;
      }
    polynomial h(h_mon);
    //cout << "in addtion, p:" << h.Get_p() << endl;
    //h = h.update();
    //reorder, remove zeros, do a function!
    return h;
  }

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x58(%rsp), %rdi
callq 0x53f8
movq (%r14), %rax
cmpl $0x0, 0x8(%rax)
je 0x5940
movq (%r15), %rax
cmpl $0x0, 0x8(%rax)
je 0x593d
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x53f8
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x5ce1
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x5ce1
leaq 0x10(%rsp), %rdi
andq $0x0, 0x10(%rdi)
xorps %xmm0, %xmm0
movq 0x60(%rsp), %rax
subq 0x58(%rsp), %rax
movaps %xmm0, (%rdi)
movq 0x48(%rsp), %rcx
subq 0x40(%rsp), %rcx
shrq $0x4, %rax
shrq $0x4, %rcx
addl %eax, %ecx
movslq %ecx, %r15
movq %r15, %rsi
callq 0x5b90
leaq 0x28(%rsp), %rdi
leaq 0x70(%rsp), %rdx
movq %r15, %rsi
callq 0x5c38
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x40(%rsp), %rdx
movq 0x48(%rsp), %rcx
movq 0x28(%rsp), %r8
callq 0x5d86
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rcx
movq %rcx, %rax
subq %rsi, %rax
cmpq $0x11, %rax
jb 0x5950
xorl %r12d, %r12d
leaq 0x10(%rsp), %r15
subq %rsi, %rcx
movq %rcx, %rdx
sarq $0x4, %rdx
decq %rdx
movslq %r12d, %r12
movq %r12, %rax
shlq $0x4, %rax
addq %rsi, %rax
cmpq %r12, %rdx
jbe 0x5961
movq (%rax), %rdi
leal 0x1(%r12), %r8d
movslq %r8d, %r8
shlq $0x4, %r8
cmpq (%rsi,%r8), %rdi
jne 0x5923
addq $0x2, %r12
addq $0x20, %rax
jmp 0x58ff
movq %r15, %rdi
movq %rax, %rsi
callq 0x5c8a
incq %r12
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rcx
jmp 0x58e5
movq %r14, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x57a2
jmp 0x5a0d
leaq 0x10(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x51c4
jmp 0x597d
movq -0x20(%rsi,%rcx), %rax
shlq $0x4, %rdx
cmpq (%rsi,%rdx), %rax
jge 0x597d
addq %rdx, %rsi
leaq 0x10(%rsp), %rdi
callq 0x5c8a
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
callq 0x5ce1
movq 0x18(%rsp), %rax
cmpq 0x10(%rsp), %rax
je 0x59a7
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0xd5a4
jmp 0x59ef
movq (%r14), %rax
movl 0xc(%rax), %ecx
leaq 0x88(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xd4d0
leaq 0x70(%rsp), %rdi
leaq 0x88(%rsp), %rsi
pushq $0x1
popq %rdx
leaq 0xf(%rsp), %rcx
callq 0x5ca8
leaq 0x70(%rsp), %rsi
movq %rbx, %rdi
callq 0xd5a4
leaq 0x70(%rsp), %rdi
callq 0x2f74
leaq 0x28(%rsp), %rdi
callq 0x2f74
leaq 0x10(%rsp), %rdi
callq 0x2f74
leaq 0x40(%rsp), %rdi
callq 0x2f74
leaq 0x58(%rsp), %rdi
callq 0x2f74
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x2f74
jmp 0x5a54
jmp 0x5a51
jmp 0x5a51
jmp 0x5a51
jmp 0x5a40
movq %rax, %rbx
jmp 0x5a5e
jmp 0x5a47
movq %rax, %rbx
jmp 0x5a72
movq %rax, %rbx
jmp 0x5a68
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x2f74
leaq 0x10(%rsp), %rdi
callq 0x2f74
leaq 0x40(%rsp), %rdi
callq 0x2f74
leaq 0x58(%rsp), %rdi
callq 0x2f74
movq %rbx, %rdi
callq 0x2260