Segmentation fault

I wrote the code as instructed but i am getting segmentation fault error.

my code

#include
using namespace std;

class Node {
public:
int data;
Node * next;

// Constructor
Node(int d){
    data=d;
    next= NULL;
}

};

void insertAtTail(Node*&head,int d){

if(head==NULL){
    head = new Node(d);
    return;
}

Node * tail= head;

while(tail->next != NULL){
    tail= tail->next;
}
tail->next= new Node(d);

}

int length(Node*head){
int cnt=0;

while(head!= NULL){
    head=head->next;
    cnt++;
}
return cnt;

}

//Passing by refrence Node*&head
void insertAthead(Node*&head, int d){

// if no node is there
if(head==NULL){
    head = new Node(d);
    return;
}

//Dynamically Creating a node pointer n
Node * n = new Node(d);
//storing head value in n->next
n->next=head;
//making n new haed
head=n;

}

void insertAtmid(Node*&head, int d,int p){

// corner cases
if(head==NULL or p==0){
    insertAthead(head,d);
}
else if(p>length(head)){
    insertAtTail(head,d);
}

else{
    Node * temp = head;
    int c=1;

    while(c<=p-1){
        temp = temp->next;
        c++;


    }
    Node * n= new Node(d);
    n->next=temp->next;
    temp->next = n;

    
}

}

void deleteAthead(Node*&head){
//corner case
if(head==NULL){
return;
}
Node * temp= head->next;
delete head;
head = temp;

}

void deleteAtTail(Node*&head){
if(head==NULL){
return;
}
Node * temp = head;

Node * prev;

while(temp->next != NULL){
    prev=temp;
    temp= temp->next;

}

delete temp;
prev->next= NULL;

}

void deleteAtmid(Node * &head,int p){
if(head==NULL or p>length(head)){
return;
}

Node * temp = head;

int c=1;
Node * prev;

while(c<=(p-1)){
    prev=temp;
    temp=temp->next;
    c++;

}

prev->next=temp->next;
delete temp;

}

//passing by value
void print(Node * head){

while(head != NULL){
    cout<<head->data<<"->";
    head = head->next;
}

}

//paasing by value
bool search(Node*head,int key){

while(head!=NULL){
    if(head->data==key){
        return true;
    }
    head=head->next;
}

return false;

}

bool searchrecursive(Node*head,int key){

//base case
if(head==NULL){
    return false;
}

// recursive case
if(head->data==key){
    return true;
}
else{
    return searchrecursive(head->next,key);
}

}

Node* input(){
int d;
cin>>d;
Node * head= NULL;
while(d!= -1){
insertAthead(head,d);
cin>>d;
}
return head;

}

ostream& operator<<(ostream &os, Node * head){
print(head);
return os; //cout
}

istream& operator>>(istream &is, Node * head){
head= input();
return is;
}

int main(){

//creating a head pointer
Node * head;
Node * head2;
cin>>head>>head2;
cout<<head<<head2;

}