//#include "stdio.h"
//
//#define SIZE 10000
//typedef struct Node{
// int id;
// int filesize;
// int originsize;
// int isfolder;
// Node *child;
// Node *parent;
// Node *brother;
//}Node;
//
//Node file[SIZE+10];
//int realfile;
//
//Node* getNode(int id ,int index ,int isAdd){
// if(file[index].id == id || (isAdd && file[index].id == -1))
// return &file[index];
// else {
// index = (index + 1) % SIZE;
// return getNode(id, index ,isAdd);
// }
//}
//
//void updateParentSize(Node *par,int size){
// while(par){
// par->filesize += size;
// par = par->parent;
// }
//}
//
//void init(){
// realfile =0;
// file[0].id = 10000;
// file[0].filesize =0;
// file[0].originsize =0;
// file[0].isfolder =1;
// file[0].child = NULL;
// file[0].parent = NULL;
// file[0].brother = NULL;
//
// for(int i =1;i <SIZE+10;i++){
// file[i].id = -1;
// file[i].filesize =0;
// file[i].originsize =0;
// file[i].isfolder =1;
// file[i].child = NULL;
// file[i].parent = NULL;
// file[i].brother = NULL;
// }
//}
//
//int add(int id, int pid, int fileSize){
// Node *parent = getNode(pid ,pid % SIZE ,0);
// Node *cur = getNode(id ,id % SIZE ,1);
//
// cur->brother = parent->child;
// parent->child = cur;
// cur->parent = parent;
//
// cur->id = id;
// cur->filesize = fileSize;
// cur->originsize = fileSize;
// if(fileSize != 0){
// realfile++;
// cur->isfolder = 0;
// updateParentSize(parent,fileSize);
// }
//
// return parent->filesize;
//}
//
//int move(int id, int pid){
// Node *parent = getNode(pid ,pid % SIZE ,0);
// Node *cur = getNode(id ,id % SIZE ,0);
//
// if(cur->parent->child->id == cur->id){
// cur->parent->child = cur->brother;
// }else{
// Node *oldbro = cur->parent->child;
// while(oldbro){
// if(oldbro->brother->id == cur->id){
// break;
// }
// oldbro = oldbro->brother;
// }
// oldbro->brother = cur->brother;
// }
// updateParentSize(cur->parent, cur->filesize * (-1));
//
// cur->brother = parent->child;
// parent->child = cur;
// cur->parent = parent;
// updateParentSize(cur->parent, cur->filesize);
//
// return parent->filesize;
//}
//
//void infectFolder(Node *node ,int infectSize){
// while(node){
// if(node->isfolder){
// infectFolder(node->child,infectSize);
// }else{
// node->filesize += infectSize;
// updateParentSize(node->parent, infectSize);
// }
// node = node->brother;
// }
//}
//
//int infect(int id){
// if(realfile == 0)
// return 0;
//
// Node *cur = getNode(id ,id % SIZE ,0);
// int infectSize = file[0].filesize / realfile;
//
// if(cur->isfolder){
// infectFolder(cur->child,infectSize);
// }else{
// cur->filesize += infectSize;
// updateParentSize(cur->parent, infectSize);
// }
//
// return cur->filesize;
//}
//
//void recoverFolder(Node *node){
// while(node){
// if(node->isfolder){
// recoverFolder(node->child);
// }else{
// int value = node->originsize - node->filesize;
// node->filesize = node->originsize;
// updateParentSize(node->parent, value);
// }
// node = node->brother;
// }
//}
//
//int recover(int id){
// Node *cur = getNode(id ,id % SIZE ,0);
//
// if(cur->isfolder){
// recoverFolder(cur->child);
// }else{
// int value = cur->originsize - cur->filesize;
// cur->filesize = cur->originsize;
// updateParentSize(cur->parent, value);
// }
//
// return cur->filesize;
//}
//
//void deleteNode(Node *node){
// node->id = -1;
// node->filesize =0;
// node->originsize = 0;
// node->isfolder = 1;
// node->child = NULL;
// node->parent = NULL;
// node->brother = NULL;
//}
//
//void removeNode(Node *node){
//
// while(node){
// Node *tem = node->brother;
// if(node->isfolder){
// removeNode(node->child);
// }else{
// realfile--;
// }
// deleteNode(node);
// node = tem;
// }
//
//}
//
//int remove(int id){
// Node *cur = getNode(id ,id % SIZE ,0);
// int value = cur->filesize;
//
// if(id == 10000){
// init();
// }else{
// updateParentSize(cur->parent, value * -1);
//
// if(cur->parent->child->id == cur->id){
// cur->parent->child = cur->brother;
// }else{
// Node *oldbro = cur->parent->child;
// while(oldbro){
// if(oldbro->brother->id == cur->id){
// break;
// }
// oldbro = oldbro->brother;
// }
// oldbro->brother = cur->brother;
// }
// cur->brother = NULL;
// removeNode(cur);
// }
//
// return value;
//}

#include "stdio.h"

#define SIZE 10000
#define MOD 10003

typedef struct Node{
int id;
int filesize;
int originsize;
int isfolder;
Node *child;
Node *parent;
Node *brother;
Node *next;
}Node;

Node file[SIZE+10];
Node HashPool[SIZE+10];
int HashIndex =0;

int realfile;

Node *getNewNode(){
return &HashPool[HashIndex++];
}

void insertNode(int index, Node *newNode){
newNode->next = file[index].next;
file[index].next = newNode;
}

Node* getNode(int id ,int index){
Node *cur = &file[index];
while(cur != NULL){
if(cur->id == id )
return cur;

cur = cur->next;
}
}

void updateParentSize(Node *par,int size){
while(par){
par->filesize += size;
par = par->parent;
}
}

void init(){
realfile =0;
HashIndex =0;

for(int i =0;i <SIZE+10;i++){
file[i].id = HashPool[i].id = -1;
file[i].filesize = HashPool[i].filesize =0;
file[i].originsize = HashPool[i].originsize =0;
file[i].isfolder = HashPool[i].isfolder =1;
file[i].child = HashPool[i].child = NULL;
file[i].parent = HashPool[i].parent = NULL;
file[i].brother = HashPool[i].brother = NULL;
file[i].next = HashPool[i].next = NULL;
}

file[10000].id = 10000;
file[10000].filesize =0;
file[10000].originsize =0;
file[10000].isfolder =1;
file[10000].child = NULL;
file[10000].parent = NULL;
file[10000].brother = NULL;
file[10000].next = NULL;
}

int add(int id, int pid, int fileSize){
Node *parent = getNode(pid ,pid % MOD);
Node *cur = getNewNode();

insertNode(id % MOD ,cur);
cur->brother = parent->child;
parent->child = cur;
cur->parent = parent;

cur->id = id;
cur->filesize = fileSize;
cur->originsize = fileSize;
if(fileSize != 0){
realfile++;
cur->isfolder = 0;
updateParentSize(parent,fileSize);
}


return parent->filesize;
}

int move(int id, int pid){
Node *parent = getNode(pid ,pid % MOD);
Node *cur = getNode(id ,id % MOD);

if(cur->parent->child->id == cur->id){
cur->parent->child = cur->brother;
}else{
Node *oldbro = cur->parent->child;
while(oldbro){
if(oldbro->brother->id == cur->id){
break;
}
oldbro = oldbro->brother;
}
oldbro->brother = cur->brother;
}
updateParentSize(cur->parent, cur->filesize * (-1));

cur->brother = parent->child;
parent->child = cur;
cur->parent = parent;
updateParentSize(cur->parent, cur->filesize);

return parent->filesize;
}

void infectFolder(Node *node ,int infectSize){
while(node){
if(node->isfolder){
infectFolder(node->child,infectSize);
}else{
node->filesize += infectSize;
updateParentSize(node->parent, infectSize);
}
node = node->brother;
}
}

int infect(int id){
if(realfile == 0)
return 0;

Node *cur = getNode(id ,id % MOD);
int infectSize = file[10000].filesize / realfile;

if(cur->isfolder){
infectFolder(cur->child,infectSize);
}else{
cur->filesize += infectSize;
updateParentSize(cur->parent, infectSize);
}

return cur->filesize;
}

void recoverFolder(Node *node){
while(node){
if(node->isfolder){
recoverFolder(node->child);
}else{
int value = node->originsize - node->filesize;
node->filesize = node->originsize;
updateParentSize(node->parent, value);
}
node = node->brother;
}
}

int recover(int id){
Node *cur = getNode(id ,id % MOD);

if(cur->isfolder){
recoverFolder(cur->child);
}else{
int value = cur->originsize - cur->filesize;
cur->filesize = cur->originsize;
updateParentSize(cur->parent, value);
}

return cur->filesize;
}

void deleteNode(Node *node){

Node *cur = &file[node->id % MOD];

while(cur){
if(cur->next->id == node->id){
cur->next = cur->next->next;
break;
}

cur = cur->next;
}

node->id = -1;
node->filesize =0;
node->originsize = 0;
node->isfolder = 1;
node->child = NULL;
node->parent = NULL;
node->brother = NULL;
node->next = NULL;

}

void removeNode(Node *node){

while(node){
Node *tem = node->brother;
if(node->isfolder){
removeNode(node->child);
}else{
realfile--;
}
deleteNode(node);
node = tem;
}

}

int remove(int id){
Node *cur = getNode(id ,id % MOD);
int value = cur->filesize;

if(id == 10000){
init();
}else{
updateParentSize(cur->parent, value * -1);

if(cur->parent->child->id == cur->id){
cur->parent->child = cur->brother;
}else{
Node *oldbro = cur->parent->child;
while(oldbro){
if(oldbro->brother->id == cur->id){
break;
}
oldbro = oldbro->brother;
}
oldbro->brother = cur->brother;
}
cur->brother = NULL;
removeNode(cur);
}

return value;
}